|
7 | 7 | *
|
8 | 8 | */
|
9 | 9 | #include <assert.h>
|
| 10 | +#include <limits.h> |
10 | 11 | #include <stdarg.h>
|
11 | 12 | #include <setjmp.h>
|
12 | 13 | #include <string.h>
|
13 | 14 | #include <cmocka.h>
|
| 15 | +#if !_WIN32 |
| 16 | +#include <unistd.h> |
| 17 | +#endif |
14 | 18 |
|
15 | 19 | #include "zone.h"
|
16 | 20 |
|
@@ -471,3 +475,87 @@ void ttls(void **state)
|
471 | 475 | assert_int_equal(code, tests[i].code);
|
472 | 476 | }
|
473 | 477 | }
|
| 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