Skip to content

Commit f1f61a6

Browse files
committed
Always log error if file cannot be opened
Fixes comment by @wcawijngaards on NLnetLabs/nsd#278.
1 parent e3c4c38 commit f1f61a6

File tree

3 files changed

+71
-21
lines changed

3 files changed

+71
-21
lines changed

src/generic/format.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -251,18 +251,8 @@ static really_inline int32_t parse_dollar_include(
251251
file_t *file;
252252
if ((code = take_quoted_or_contiguous(parser, &include, &fields[0], token)) < 0)
253253
return code;
254-
255-
switch ((code = zone_open_file(parser, token->data, token->length, &file))) {
256-
case ZONE_OUT_OF_MEMORY:
257-
OUT_OF_MEMORY(parser, "Cannot open %s (%.*s), out of memory",
258-
NAME(&include), (int)token->length, token->data);
259-
case ZONE_NOT_PERMITTED:
260-
NOT_PERMITTED(parser, "Cannot open %s (%.*s), access denied",
261-
NAME(&include), (int)token->length, token->data);
262-
case ZONE_NOT_A_FILE:
263-
NOT_A_FILE(parser, "Cannot open %s (%.*s), no such file",
264-
NAME(&include), (int)token->length, token->data);
265-
}
254+
if ((code = zone_open_file(parser, token->data, token->length, &file)) < 0)
255+
return code;
266256

267257
name_buffer_t name;
268258
const name_buffer_t *origin = &parser->file->origin;

src/zone.c

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,21 @@ int32_t zone_open_file(
334334

335335
if (!(*file = malloc(sizeof(**file))))
336336
return ZONE_OUT_OF_MEMORY;
337-
if ((code = open_file(parser, *file, path, length)) < 0)
338-
return (void)free(*file), code;
339-
return 0;
337+
if ((code = open_file(parser, *file, path, length)) == 0)
338+
return 0;
339+
340+
free(*file);
341+
342+
const char *reason = NULL;
343+
switch (code) {
344+
case ZONE_OUT_OF_MEMORY: reason = "out of memory"; break;
345+
case ZONE_NOT_PERMITTED: reason = "access denied"; break;
346+
case ZONE_NOT_A_FILE: reason = "no such file"; break;
347+
}
348+
349+
assert(reason);
350+
zone_error(parser, "Cannot open %.*s, %s", (int)length, path, reason);
351+
return code;
340352
}
341353

342354
nonnull_all
@@ -411,9 +423,19 @@ int32_t zone_open(
411423

412424
if ((code = initialize_parser(parser, options, buffers, user_data)) < 0)
413425
return code;
414-
if ((code = open_file(parser, &parser->first, path, strlen(path))) < 0)
415-
return code;
416-
return 0;
426+
if ((code = open_file(parser, &parser->first, path, strlen(path))) == 0)
427+
return 0;
428+
429+
const char *reason = NULL;
430+
switch (code) {
431+
case ZONE_OUT_OF_MEMORY: reason = "out of memory"; break;
432+
case ZONE_NOT_PERMITTED: reason = "access denied"; break;
433+
case ZONE_NOT_A_FILE: reason = "no such file"; break;
434+
}
435+
436+
assert(reason);
437+
zone_error(parser, "Cannot open %s, %s", path, reason);
438+
return code;
417439
}
418440

419441
diagnostic_pop()
@@ -468,10 +490,15 @@ static void print_message(
468490
const char *message,
469491
void *user_data)
470492
{
471-
FILE *output = priority == ZONE_INFO ? stdout : stderr;
472-
const char *format = "%s:%zu: %s\n";
473493
(void)user_data;
474-
fprintf(output, format, parser->file->name, parser->file->line, message);
494+
495+
assert(parser->file);
496+
FILE *output = priority == ZONE_INFO ? stdout : stderr;
497+
498+
if (parser->file->name)
499+
fprintf(output, "%s:%zu: %s\n", parser->file->name, parser->file->line, message);
500+
else
501+
fprintf(output, "%s\n", message);
475502
}
476503

477504
void zone_vlog(

tests/include.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,39 @@ static void no_such_file_log(
284284
test->log_count++;
285285
}
286286

287+
/*!cmocka */
288+
void the_file_that_wasnt(void **state)
289+
{
290+
// test parsing of nonexistent file is handled gracefully
291+
zone_parser_t parser;
292+
zone_options_t options;
293+
zone_name_buffer_t name;
294+
zone_rdata_buffer_t rdata;
295+
zone_buffers_t buffers = { 1, &name, &rdata };
296+
no_file_test_t test;
297+
int32_t code;
298+
299+
memset(&options, 0, sizeof(options));
300+
options.accept.callback = &no_such_file_accept;
301+
options.log.callback = &no_such_file_log;
302+
options.origin.octets = origin;
303+
options.origin.length = sizeof(origin);
304+
options.default_ttl = 3600;
305+
options.default_class = 1;
306+
307+
(void)state;
308+
309+
char *non_file = temporary_name();
310+
assert_non_null(non_file);
311+
312+
memset(&test, 0, sizeof(test));
313+
code = zone_parse(&parser, &options, &buffers, non_file, &test);
314+
free(non_file);
315+
assert_int_equal(code, ZONE_NOT_A_FILE);
316+
assert_true(test.log_count == 1);
317+
assert_true(test.accept_count == 0);
318+
}
319+
287320
/*!cmocka */
288321
void the_include_that_wasnt(void **state)
289322
{

0 commit comments

Comments
 (0)