@@ -115,89 +115,28 @@ diagnostic_push()
115115msvc_diagnostic_ignored (4996 )
116116
117117#if _WIN32
118- nonnull_all
119- static bool is_separator (int c )
120- {
121- return c == '\\' || c == '/' ;
122- }
123-
124- nonnull_all
125- static bool is_rooted (const char * s )
126- {
127- if ((s [0 ] >= 'A' && s [0 ] <= 'Z' ) || (s [0 ] >= 'a' && s [0 ] <= 'z' ))
128- return s [1 ] == ':' ;
129- return false;
130- }
131-
132- nonnull_all
133- static bool is_relative (const char * s )
134- {
135- // rooted paths can be relative, e.g. C:foo
136- if (is_rooted (s ))
137- return !is_separator ((unsigned char )s [2 ]);
138- if (is_separator ((unsigned char )s [0 ]))
139- return !(s [1 ] == '?' || is_separator ((unsigned char )s [1 ]));
140- return false;
141- }
142-
143118// The Win32 API offers PathIsRelative, but it requires linking with shlwapi.
144119// Rewriting a relative path is not too complex, unlike correct conversion of
145120// Windows paths in general (https://googleprojectzero.blogspot.com/2016/02/).
146121// Rooted paths, relative or not, unc and extended paths are never resolved
147122// relative to the includer.
148- nonnull ((2 ,3 ))
149- static int32_t resolve_path (
150- const char * includer , const char * include , char * * path )
123+ nonnull_all
124+ static int32_t resolve_path (const char * include , char * * path )
151125{
152- // support relative non-rooted paths only
153- if (* includer && is_relative (include ) && !is_rooted (include )) {
154- assert (!is_relative (includer ));
155- char buffer [16 ];
156- int length = snprintf (
157- buffer , sizeof (buffer ), "%s/%s" , includer , include );
158- if (length < 0 )
159- return ZONE_OUT_OF_MEMORY ;
160- char * absolute ;
161- if (!(absolute = malloc (length + 1 )))
162- return ZONE_OUT_OF_MEMORY ;
163- (void )snprintf (
164- absolute , (size_t )length + 1 , "%s/%s" , includer , include );
165- * path = _fullpath (NULL , absolute , 0 );
166- free (absolute );
167- } else {
168- * path = _fullpath (NULL , include , 0 );
169- }
170-
171- if (* path )
126+ if ((* path = _fullpath (NULL , include , 0 )))
172127 return 0 ;
173128 return (errno == ENOMEM ) ? ZONE_OUT_OF_MEMORY : ZONE_NOT_A_FILE ;
174129}
175130#else
176131nonnull_all
177- static int32_t resolve_path (
178- const char * includer , const char * include , char * * path )
132+ static int32_t resolve_path (const char * include , char * * path )
179133{
180134 char * resolved ;
181135 char buffer [PATH_MAX + 1 ];
182136
183- if (* includer && * include != '/' ) {
184- assert (* includer == '/' );
185- int length = snprintf (
186- buffer , sizeof (buffer ), "%s/%s" , includer , include );
187- if (length < 0 )
188- return ZONE_OUT_OF_MEMORY ;
189- char * absolute ;
190- if (!(absolute = malloc ((size_t )length + 1 )))
191- return ZONE_OUT_OF_MEMORY ;
192- (void )snprintf (
193- absolute , (size_t )length + 1 , "%s/%s" , includer , include );
194- resolved = realpath (absolute , buffer );
195- free (absolute );
196- } else {
197- resolved = realpath (include , buffer );
198- }
137+ resolved = realpath (include , buffer );
199138
200- if (!resolved )
139+ if (!( resolved = realpath ( include , buffer )) )
201140 return (errno == ENOMEM ) ? ZONE_OUT_OF_MEMORY : ZONE_NOT_A_FILE ;
202141 assert (resolved == buffer );
203142 size_t length = strlen (buffer );
@@ -318,24 +257,20 @@ static int32_t open_file(
318257 file -> path [0 ] = '-' ;
319258 file -> path [1 ] = '\0' ;
320259 } else {
321- /* The file is resolved relative to the working directory. */
322- char workdir [PATH_MAX ];
323- #if _WIN32
324- if (!_getcwd (workdir , sizeof (workdir )))
325- return (void )close_file (parser , file ), ZONE_NOT_A_FILE ;
326- #else
327- if (!getcwd (workdir , sizeof (workdir )))
328- return (void )close_file (parser , file ), ZONE_NOT_A_FILE ;
329- #endif
330- if ((code = resolve_path (workdir , file -> name , & file -> path )))
260+ // The file is resolved relative to the working directory. The absolute
261+ // path is used to protect against recusive includes. Not for opening the
262+ // file as file descriptors for pipes and sockets the entries will be
263+ // symoblic links whose content is the file type with the inode.
264+ // See NLnetLabs/nsd#380.
265+ if ((code = resolve_path (file -> name , & file -> path )))
331266 return (void )close_file (parser , file ), code ;
332267 }
333268
334269 if (strcmp (file -> path , "-" ) == 0 ) {
335270 file -> handle = stdin ;
336271 return 0 ;
337272 } else {
338- if ((file -> handle = fopen (file -> path , "rb" )))
273+ if ((file -> handle = fopen (file -> name , "rb" )))
339274 return 0 ;
340275 }
341276
0 commit comments