Skip to content

Commit 47445d3

Browse files
committed
Ensure unterminated strings are caught
1 parent ecfb3a1 commit 47445d3

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

tests/syntax.c

+88
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
*
88
*/
99
#include <assert.h>
10+
#include <limits.h>
1011
#include <stdarg.h>
1112
#include <setjmp.h>
1213
#include <string.h>
1314
#include <cmocka.h>
15+
#if !_WIN32
16+
#include <unistd.h>
17+
#endif
1418

1519
#include "zone.h"
1620

@@ -471,3 +475,87 @@ void ttls(void **state)
471475
assert_int_equal(code, tests[i].code);
472476
}
473477
}
478+
479+
static int32_t dummy_callback(
480+
zone_parser_t *parser,
481+
const zone_name_t *owner,
482+
uint16_t type,
483+
uint16_t class,
484+
uint32_t ttl,
485+
uint16_t rdlength,
486+
const uint8_t *rdata,
487+
void *user_data)
488+
{
489+
(void)parser;
490+
(void)owner;
491+
(void)type;
492+
(void)class;
493+
(void)ttl;
494+
(void)rdlength;
495+
(void)rdata;
496+
(void)user_data;
497+
return 0;
498+
}
499+
500+
static int32_t parse_text(const char *text)
501+
{
502+
zone_parser_t parser;
503+
zone_name_buffer_t name;
504+
zone_rdata_buffer_t rdata;
505+
zone_buffers_t buffers = { 1, &name, &rdata };
506+
zone_options_t options = { 0 };
507+
const uint8_t origin[] = { 0 };
508+
509+
options.accept.callback = &dummy_callback;
510+
options.origin.octets = origin;
511+
options.origin.length = sizeof(origin);
512+
options.default_ttl = 3600;
513+
options.default_class = 1;
514+
515+
fprintf(stderr, "INPUT: '%s'\n", text);
516+
return zone_parse_string(&parser, &options, &buffers, text, strlen(text), NULL);
517+
}
518+
519+
static char *generate_include(const char *text)
520+
{
521+
char *path = tempnam(NULL, "zone");
522+
if (path) {
523+
FILE *handle = fopen(path, "wbx");
524+
if (handle) {
525+
int result = fputs(text, handle);
526+
(void)fclose(handle);
527+
if (result != EOF)
528+
return path;
529+
}
530+
free(path);
531+
}
532+
return NULL;
533+
}
534+
535+
/*!cmocka */
536+
void quote_no_unquote(void **state)
537+
{
538+
(void)state;
539+
540+
int32_t code;
541+
static const char *no_unquote = PAD("foo. TXT \"unterminated string");
542+
543+
// verify unterminated strings are caught
544+
code = parse_text(no_unquote);
545+
assert_int_equal(code, ZONE_SYNTAX_ERROR);
546+
547+
// verify unterminated strings are caught in included file
548+
char *path = generate_include(no_unquote);
549+
assert_non_null(path);
550+
char dummy[16];
551+
int length = snprintf(dummy, sizeof(dummy), "$INCLUDE \"%s\"\n", path);
552+
assert_true(length > 0 && length < INT_MAX - ZONE_PADDING_SIZE);
553+
char *include = malloc(length + 1 + ZONE_PADDING_SIZE);
554+
assert_non_null(include);
555+
(void)snprintf(include, (size_t)length + 1, "$INCLUDE \"%s\"\n", path);
556+
code = parse_text(include);
557+
assert_int_equal(code, ZONE_SYNTAX_ERROR);
558+
free(include);
559+
unlink(path);
560+
free(path);
561+
}

0 commit comments

Comments
 (0)