Skip to content

Commit

Permalink
Always log error if file cannot be opened
Browse files Browse the repository at this point in the history
Fixes comment by @wcawijngaards on NLnetLabs/nsd#278.
  • Loading branch information
k0ekk0ek committed Apr 11, 2024
1 parent e3c4c38 commit f1f61a6
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 21 deletions.
14 changes: 2 additions & 12 deletions src/generic/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,18 +251,8 @@ static really_inline int32_t parse_dollar_include(
file_t *file;
if ((code = take_quoted_or_contiguous(parser, &include, &fields[0], token)) < 0)
return code;

switch ((code = zone_open_file(parser, token->data, token->length, &file))) {
case ZONE_OUT_OF_MEMORY:
OUT_OF_MEMORY(parser, "Cannot open %s (%.*s), out of memory",
NAME(&include), (int)token->length, token->data);
case ZONE_NOT_PERMITTED:
NOT_PERMITTED(parser, "Cannot open %s (%.*s), access denied",
NAME(&include), (int)token->length, token->data);
case ZONE_NOT_A_FILE:
NOT_A_FILE(parser, "Cannot open %s (%.*s), no such file",
NAME(&include), (int)token->length, token->data);
}
if ((code = zone_open_file(parser, token->data, token->length, &file)) < 0)
return code;

name_buffer_t name;
const name_buffer_t *origin = &parser->file->origin;
Expand Down
45 changes: 36 additions & 9 deletions src/zone.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,21 @@ int32_t zone_open_file(

if (!(*file = malloc(sizeof(**file))))
return ZONE_OUT_OF_MEMORY;
if ((code = open_file(parser, *file, path, length)) < 0)
return (void)free(*file), code;
return 0;
if ((code = open_file(parser, *file, path, length)) == 0)
return 0;

free(*file);

const char *reason = NULL;
switch (code) {
case ZONE_OUT_OF_MEMORY: reason = "out of memory"; break;
case ZONE_NOT_PERMITTED: reason = "access denied"; break;
case ZONE_NOT_A_FILE: reason = "no such file"; break;
}

assert(reason);
zone_error(parser, "Cannot open %.*s, %s", (int)length, path, reason);
return code;
}

nonnull_all
Expand Down Expand Up @@ -411,9 +423,19 @@ int32_t zone_open(

if ((code = initialize_parser(parser, options, buffers, user_data)) < 0)
return code;
if ((code = open_file(parser, &parser->first, path, strlen(path))) < 0)
return code;
return 0;
if ((code = open_file(parser, &parser->first, path, strlen(path))) == 0)
return 0;

const char *reason = NULL;
switch (code) {
case ZONE_OUT_OF_MEMORY: reason = "out of memory"; break;
case ZONE_NOT_PERMITTED: reason = "access denied"; break;
case ZONE_NOT_A_FILE: reason = "no such file"; break;
}

assert(reason);
zone_error(parser, "Cannot open %s, %s", path, reason);
return code;
}

diagnostic_pop()
Expand Down Expand Up @@ -468,10 +490,15 @@ static void print_message(
const char *message,
void *user_data)
{
FILE *output = priority == ZONE_INFO ? stdout : stderr;
const char *format = "%s:%zu: %s\n";
(void)user_data;
fprintf(output, format, parser->file->name, parser->file->line, message);

assert(parser->file);
FILE *output = priority == ZONE_INFO ? stdout : stderr;

if (parser->file->name)
fprintf(output, "%s:%zu: %s\n", parser->file->name, parser->file->line, message);
else
fprintf(output, "%s\n", message);
}

void zone_vlog(
Expand Down
33 changes: 33 additions & 0 deletions tests/include.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,39 @@ static void no_such_file_log(
test->log_count++;
}

/*!cmocka */
void the_file_that_wasnt(void **state)
{
// test parsing of nonexistent file is handled gracefully
zone_parser_t parser;
zone_options_t options;
zone_name_buffer_t name;
zone_rdata_buffer_t rdata;
zone_buffers_t buffers = { 1, &name, &rdata };
no_file_test_t test;
int32_t code;

memset(&options, 0, sizeof(options));
options.accept.callback = &no_such_file_accept;
options.log.callback = &no_such_file_log;
options.origin.octets = origin;
options.origin.length = sizeof(origin);
options.default_ttl = 3600;
options.default_class = 1;

(void)state;

char *non_file = temporary_name();
assert_non_null(non_file);

memset(&test, 0, sizeof(test));
code = zone_parse(&parser, &options, &buffers, non_file, &test);
free(non_file);
assert_int_equal(code, ZONE_NOT_A_FILE);
assert_true(test.log_count == 1);
assert_true(test.accept_count == 0);
}

/*!cmocka */
void the_include_that_wasnt(void **state)
{
Expand Down

0 comments on commit f1f61a6

Please sign in to comment.