Skip to content

Commit 0ba1404

Browse files
committed
Fix handling of escape sequences in domain names
Fixes $140.
1 parent aeb5166 commit 0ba1404

File tree

2 files changed

+51
-20
lines changed

2 files changed

+51
-20
lines changed

src/generic/name.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ static really_inline int32_t scan_name(
110110
text += count + octet;
111111
wire += count + 1;
112112
length += count + 1;
113+
left -= count + octet;
113114
} else {
114115
block.dots &= mask;
115116
text += count;
116117
wire += count;
117118
length += count;
119+
left -= count;
118120
}
119121

120-
left -= count;
121-
122122
// check for null labels, i.e. ".."
123123
if (unlikely(block.dots & ((block.dots >> 1) | carry)))
124124
return -1;

tests/syntax.c

+49-18
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,16 @@ void strings(void **state)
257257
}
258258
}
259259

260-
static int32_t name_test_accept_rr(
260+
struct names_test {
261+
const char *input;
262+
int32_t code;
263+
struct {
264+
size_t length;
265+
const uint8_t *octets;
266+
} owner;
267+
};
268+
269+
static int32_t names_callback(
261270
zone_parser_t *parser,
262271
const zone_name_t *owner,
263272
uint16_t type,
@@ -267,14 +276,20 @@ static int32_t name_test_accept_rr(
267276
const uint8_t *rdata,
268277
void *user_data)
269278
{
279+
struct names_test *test = (struct names_test *)user_data;
280+
270281
(void)parser;
271282
(void)owner;
272283
(void)type;
273284
(void)class;
274285
(void)ttl;
275286
(void)rdlength;
276287
(void)rdata;
277-
(void)user_data;
288+
289+
if (owner->length != test->owner.length)
290+
return ZONE_SYNTAX_ERROR;
291+
if (memcmp(owner->octets, test->owner.octets, owner->length) != 0)
292+
return ZONE_SYNTAX_ERROR;
278293
return 0;
279294
}
280295

@@ -322,20 +337,36 @@ void names(void **state)
322337
static const char last_label_is_null[] = "foo..";
323338
static const char first_label_is_null[] = "..foo";
324339

325-
static const struct {
326-
const char *input;
327-
int32_t code;
328-
} tests[] = {
329-
{ only_rel_label_too_long, ZONE_SYNTAX_ERROR },
330-
{ only_abs_label_too_long, ZONE_SYNTAX_ERROR },
331-
{ first_label_too_long, ZONE_SYNTAX_ERROR },
332-
{ last_rel_label_too_long, ZONE_SYNTAX_ERROR },
333-
{ last_abs_label_too_long, ZONE_SYNTAX_ERROR },
334-
{ rel_name_too_long, ZONE_SYNTAX_ERROR },
335-
{ abs_name_too_long, ZONE_SYNTAX_ERROR },
336-
{ only_null_labels, ZONE_SYNTAX_ERROR },
337-
{ last_label_is_null, ZONE_SYNTAX_ERROR },
338-
{ first_label_is_null, ZONE_SYNTAX_ERROR }
340+
static const uint8_t owner_abs_0[] = { 1, 0, 0 };
341+
static const uint8_t owner_abs_spc[] = { 1, ' ', 0 };
342+
static const uint8_t owner_abs_0foo[] = { 4, 0, 'f', 'o', 'o', 0 };
343+
static const uint8_t owner_abs_00foo[] = { 5, 0, 0, 'f', 'o', 'o', 0 };
344+
static const uint8_t owner_abs_foo0[] = { 4, 'f', 'o', 'o', 0, 0 };
345+
static const uint8_t owner_abs_foo00[] = { 5, 'f', 'o', 'o', 0, 0, 0 };
346+
static const uint8_t owner_abs_foodot[] = { 4, 'f', 'o', 'o', '.', 0 };
347+
static const uint8_t owner_rel_foodot[] = { 4, 'f', 'o', 'o', '.', 3, 'f', 'o', 'o', 0 };
348+
349+
static struct names_test tests[] = {
350+
{ only_rel_label_too_long, ZONE_SYNTAX_ERROR, { 0, NULL } },
351+
{ only_abs_label_too_long, ZONE_SYNTAX_ERROR, { 0, NULL } },
352+
{ first_label_too_long, ZONE_SYNTAX_ERROR, { 0, NULL } },
353+
{ last_rel_label_too_long, ZONE_SYNTAX_ERROR, { 0, NULL } },
354+
{ last_abs_label_too_long, ZONE_SYNTAX_ERROR, { 0, NULL } },
355+
{ rel_name_too_long, ZONE_SYNTAX_ERROR, { 0, NULL } },
356+
{ abs_name_too_long, ZONE_SYNTAX_ERROR, { 0, NULL } },
357+
{ only_null_labels, ZONE_SYNTAX_ERROR, { 0, NULL } },
358+
{ last_label_is_null, ZONE_SYNTAX_ERROR, { 0, NULL } },
359+
{ first_label_is_null, ZONE_SYNTAX_ERROR, { 0, NULL } },
360+
{ "\\0.", ZONE_SYNTAX_ERROR, { 0, NULL } },
361+
{ "\\00.", ZONE_SYNTAX_ERROR, { 0, NULL } },
362+
{ "\\000.", 0, { 3, owner_abs_0 } },
363+
{ "\\ .", 0, { 3, owner_abs_spc } },
364+
{ "\\000foo. ", 0, { 6, owner_abs_0foo } },
365+
{ "\\000\\000foo.", 0, { 7, owner_abs_00foo } },
366+
{ "foo\\000.", 0, { 6, owner_abs_foo0 } },
367+
{ "foo\\000\\000.", 0, { 7, owner_abs_foo00 } },
368+
{ "foo\\..", 0, { 6, owner_abs_foodot } },
369+
{ "foo\\.", 0, { 10, owner_rel_foodot } }
339370
};
340371

341372
static const uint8_t origin[] = { 3, 'f', 'o', 'o', 0 };
@@ -353,14 +384,14 @@ void names(void **state)
353384
(void)snprintf(input, sizeof(input), "%s A 192.168.0.1", tests[i].input);
354385
length = strlen(input);
355386

356-
options.accept.callback = name_test_accept_rr;
387+
options.accept.callback = names_callback;
357388
options.origin.octets = origin;
358389
options.origin.length = sizeof(origin);
359390
options.default_ttl = 3600;
360391
options.default_class = ZONE_IN;
361392

362393
fprintf(stderr, "INPUT: '%s'\n", input);
363-
code = zone_parse_string(&parser, &options, &buffers, input, length, NULL);
394+
code = zone_parse_string(&parser, &options, &buffers, input, length, &tests[i]);
364395
assert_int_equal(code, tests[i].code);
365396
}
366397
}

0 commit comments

Comments
 (0)