Skip to content

Commit ddd2b54

Browse files
committed
Drop support for quoted labels in domain names
RFC 1035 section 5.1 states domain names can contain arbitrary characters if quoted and that labels are expressed as character strings and separated by dots. Using quoted labels to express domain names is uncommon and implementations handle quoted domain names very inconsistently.
1 parent cd96fd9 commit ddd2b54

File tree

3 files changed

+73
-92
lines changed

3 files changed

+73
-92
lines changed

src/generic/format.h

+47-69
Original file line numberDiff line numberDiff line change
@@ -47,30 +47,19 @@ static really_inline int32_t parse_name(
4747
{
4848
size_t length = 0;
4949

50-
if (likely(is_contiguous(token))) {
51-
// a freestanding "@" denotes the current origin
52-
if (token->length == 1 && token->data[0] == '@')
50+
assert(is_contiguous(token));
51+
52+
// a freestanding "@" denotes the current origin
53+
if (unlikely(token->length == 1 && token->data[0] == '@'))
54+
goto relative;
55+
switch (scan_name(token->data, token->length, rdata->octets, &length)) {
56+
case 0:
57+
rdata->octets += length;
58+
return 0;
59+
case 1:
5360
goto relative;
54-
switch (scan_name(token->data, token->length, rdata->octets, &length)) {
55-
case 0:
56-
rdata->octets += length;
57-
return 0;
58-
case 1:
59-
goto relative;
60-
}
61-
} else if (is_quoted(token)) {
62-
if (token->length == 0)
63-
goto invalid;
64-
switch (scan_name(token->data, token->length, rdata->octets, &length)) {
65-
case 0:
66-
rdata->octets += length;
67-
return 0;
68-
case 1:
69-
goto relative;
70-
}
7161
}
7262

73-
invalid:
7463
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type));
7564

7665
relative:
@@ -91,33 +80,20 @@ static really_inline int32_t parse_owner(
9180
size_t length = 0;
9281
uint8_t *octets = parser->file->owner.octets;
9382

94-
if (likely(is_contiguous(token))) {
95-
// a freestanding "@" denotes the origin
96-
if (token->length == 1 && token->data[0] == '@')
83+
assert(is_contiguous(token));
84+
85+
// a freestanding "@" denotes the origin
86+
if (unlikely(token->length == 1 && token->data[0] == '@'))
87+
goto relative;
88+
switch (scan_name(token->data, token->length, octets, &length)) {
89+
case 0:
90+
parser->file->owner.length = length;
91+
parser->owner = &parser->file->owner;
92+
return 0;
93+
case 1:
9794
goto relative;
98-
switch (scan_name(token->data, token->length, octets, &length)) {
99-
case 0:
100-
parser->file->owner.length = length;
101-
parser->owner = &parser->file->owner;
102-
return 0;
103-
case 1:
104-
goto relative;
105-
}
106-
} else {
107-
assert(is_quoted(token));
108-
if (token->length == 0)
109-
goto invalid;
110-
switch (scan_name(token->data, token->length, octets, &length)) {
111-
case 0:
112-
parser->file->owner.length = length;
113-
parser->owner = &parser->file->owner;
114-
return 0;
115-
case 1:
116-
goto relative;
117-
}
11895
}
11996

120-
invalid:
12197
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type));
12298

12399
relative:
@@ -146,18 +122,6 @@ static really_inline int32_t parse_rr(
146122
const type_info_t *descriptor;
147123
rdata_t rdata = { parser->rdata->octets, parser->rdata->octets + 65535 };
148124

149-
if (parser->file->start_of_line) {
150-
if ((code = have_contiguous_or_quoted(parser, &rr, &fields[0], token)) < 0)
151-
return code;
152-
if ((code = parse_owner(parser, &rr, &fields[0], token)) < 0)
153-
return code;
154-
if ((code = take_contiguous(parser, &rr, &fields[1], token)) < 0)
155-
return code;
156-
} else {
157-
if ((code = have_contiguous(parser, &rr, &fields[1], token)) < 0)
158-
return code;
159-
}
160-
161125
const mnemonic_t *mnemonic;
162126

163127
if ((uint8_t)token->data[0] - '0' < 10) {
@@ -340,30 +304,44 @@ static really_inline int32_t parse_dollar_ttl(
340304

341305
static inline int32_t parse(parser_t *parser)
342306
{
307+
static const rdata_info_t fields[] = { FIELD("OWNER") };
308+
static const type_info_t rr = ENTRY("RR", FIELDS(fields));
309+
343310
int32_t code = 0;
344311
token_t token;
345312

346313
while (code >= 0) {
347314
take(parser, &token);
348315
if (likely(is_contiguous(&token))) {
349-
if (!parser->file->start_of_line || token.data[0] != '$')
350-
code = parse_rr(parser, &token);
351-
else if (token.length == 4 && memcmp(token.data, "$TTL", 4) == 0)
352-
code = parse_dollar_ttl(parser, &token);
353-
else if (token.length == 7 && memcmp(token.data, "$ORIGIN", 7) == 0)
354-
code = parse_dollar_origin(parser, &token);
355-
else if (token.length == 8 && memcmp(token.data, "$INCLUDE", 8) == 0)
356-
code = parse_dollar_include(parser, &token);
357-
else
358-
code = parse_rr(parser, &token);
359-
} else if (is_quoted(&token)) {
316+
if (likely(parser->file->start_of_line)) {
317+
// control entry
318+
if (unlikely(token.data[0] == '$')) {
319+
if (token.length == 4 && memcmp(token.data, "$TTL", 4) == 0)
320+
code = parse_dollar_ttl(parser, &token);
321+
else if (token.length == 7 && memcmp(token.data, "$ORIGIN", 7) == 0)
322+
code = parse_dollar_origin(parser, &token);
323+
else if (token.length == 8 && memcmp(token.data, "$INCLUDE", 8) == 0)
324+
code = parse_dollar_include(parser, &token);
325+
else
326+
SYNTAX_ERROR(parser, "Invalid control entry");
327+
continue;
328+
}
329+
330+
if ((code = parse_owner(parser, &rr, &fields[0], &token)) < 0)
331+
return code;
332+
if ((code = take_contiguous(parser, &rr, &fields[0], &token)) < 0)
333+
return code;
334+
}
335+
360336
code = parse_rr(parser, &token);
361337
} else if (is_end_of_file(&token)) {
362338
if (parser->file->end_of_file == ZONE_NO_MORE_DATA)
363339
break;
364-
} else {
340+
} else if (is_line_feed(&token)) {
365341
assert(token.code == LINE_FEED);
366342
adjust_line_count(parser->file);
343+
} else {
344+
code = have_contiguous(parser, &rr, &fields[0], &token);
367345
}
368346
}
369347

src/generic/parser.h

+7
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,13 @@ static really_inline bool is_delimiter(const token_t *token)
363363
return (token->code == LINE_FEED || token->code == END_OF_FILE);
364364
}
365365

366+
nonnull_all
367+
warn_unused_result
368+
static really_inline bool is_line_feed(const token_t *token)
369+
{
370+
return token->code == LINE_FEED;
371+
}
372+
366373
nonnull_all
367374
warn_unused_result
368375
static really_inline bool is_end_of_file(const token_t *token)

src/generic/types.h

+19-23
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ static int32_t parse_ns_rdata(
292292
int32_t code;
293293
const rdata_info_t *fields = type->rdata.fields;
294294

295-
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
295+
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
296296
return code;
297297
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
298298
return code;
@@ -332,11 +332,11 @@ static int32_t parse_soa_rdata(
332332
int32_t code;
333333
const rdata_info_t *fields = type->rdata.fields;
334334

335-
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
335+
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
336336
return code;
337337
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
338338
return code;
339-
if ((code = take_contiguous_or_quoted(parser, type, &fields[1], token)) < 0)
339+
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
340340
return code;
341341
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
342342
return code;
@@ -501,11 +501,11 @@ static int32_t parse_minfo_rdata(
501501
int32_t code;
502502
const rdata_info_t *fields = type->rdata.fields;
503503

504-
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
504+
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
505505
return code;
506506
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
507507
return code;
508-
if ((code = take_contiguous_or_quoted(parser, type, &fields[1], token)) < 0)
508+
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
509509
return code;
510510
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
511511
return code;
@@ -703,7 +703,7 @@ static int32_t parse_rt_rdata(
703703
return code;
704704
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
705705
return code;
706-
if ((code = take_contiguous_or_quoted(parser, type, &fields[1], token)) < 0)
706+
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
707707
return code;
708708
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
709709
return code;
@@ -790,7 +790,7 @@ static int32_t parse_nsap_ptr_rdata(
790790
int32_t code;
791791
const rdata_info_t *fields = type->rdata.fields;
792792

793-
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
793+
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
794794
return code;
795795
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
796796
return code;
@@ -882,11 +882,11 @@ static int32_t parse_px_rdata(
882882
return code;
883883
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
884884
return code;
885-
if ((code = take_contiguous_or_quoted(parser, type, &fields[1], token)) < 0)
885+
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
886886
return code;
887887
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
888888
return code;
889-
if ((code = take_contiguous_or_quoted(parser, type, &fields[2], token)) < 0)
889+
if ((code = take_contiguous(parser, type, &fields[2], token)) < 0)
890890
return code;
891891
if ((code = parse_name(parser, type, &fields[2], rdata, token)) < 0)
892892
return code;
@@ -1117,7 +1117,7 @@ static int32_t parse_nxt_rdata(
11171117
int32_t code;
11181118
const rdata_info_t *fields = type->rdata.fields;
11191119

1120-
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
1120+
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
11211121
return code;
11221122
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
11231123
return code;
@@ -1168,7 +1168,7 @@ static int32_t parse_srv_rdata(
11681168
return code;
11691169
if ((code = parse_int16(parser, type, &fields[2], rdata, token)) < 0)
11701170
return code;
1171-
if ((code = take_contiguous_or_quoted(parser, type, &fields[3], token)) < 0)
1171+
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
11721172
return code;
11731173
if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
11741174
return code;
@@ -1213,7 +1213,7 @@ static int32_t parse_naptr_rdata(
12131213
return code;
12141214
if ((code = parse_string(parser, type, &fields[4], rdata, token)) < 0)
12151215
return code;
1216-
if ((code = take_contiguous_or_quoted(parser, type, &fields[5], token)) < 0)
1216+
if ((code = take_contiguous(parser, type, &fields[5], token)) < 0)
12171217
return code;
12181218
if ((code = parse_name(parser, type, &fields[5], rdata, token)) < 0)
12191219
return code;
@@ -1504,28 +1504,24 @@ static int32_t parse_ipseckey_rdata(
15041504
return code;
15051505
if ((code = parse_int8(parser, type, &fields[2], rdata, token)) < 0)
15061506
return code;
1507+
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
1508+
return code;
15071509

15081510
switch (octets[1]) {
15091511
case 1: /* IPv4 address */
15101512
type = (const type_info_t *)ipseckey_ipv4;
15111513
fields = type->rdata.fields;
1512-
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
1513-
return code;
15141514
if ((code = parse_ip4(parser, type, &fields[3], rdata, token)) < 0)
15151515
return code;
15161516
break;
15171517
case 2: /* IPv6 address */
15181518
type = (const type_info_t *)ipseckey_ipv6;
15191519
fields = type->rdata.fields;
1520-
if ((code = take_contiguous(parser, type, &fields[3], token)) < 0)
1521-
return code;
15221520
if ((code = parse_ip6(parser, type, &fields[3], rdata, token)) < 0)
15231521
return code;
15241522
break;
15251523
case 0: /* no gateway */
15261524
case 3: /* domain name */
1527-
if ((code = take_contiguous_or_quoted(parser, type, &fields[3], token)) < 0)
1528-
return code;
15291525
if ((code = parse_name(parser, type, &fields[3], rdata, token)) < 0)
15301526
return code;
15311527
break;
@@ -1608,7 +1604,7 @@ static int32_t parse_rrsig_rdata(
16081604
return code;
16091605
if ((code = parse_int16(parser, type, &fields[6], rdata, token)) < 0)
16101606
return code;
1611-
if ((code = take_contiguous_or_quoted(parser, type, &fields[7], token)) < 0)
1607+
if ((code = take_contiguous(parser, type, &fields[7], token)) < 0)
16121608
return code;
16131609
if ((code = parse_name(parser, type, &fields[7], rdata, token)) < 0)
16141610
return code;
@@ -1645,7 +1641,7 @@ static int32_t parse_nsec_rdata(
16451641
int32_t code;
16461642
const rdata_info_t *fields = type->rdata.fields;
16471643

1648-
if ((code = have_contiguous_or_quoted(parser, type, &fields[0], token)) < 0)
1644+
if ((code = have_contiguous(parser, type, &fields[0], token)) < 0)
16491645
return code;
16501646
if ((code = parse_name(parser, type, &fields[0], rdata, token)) < 0)
16511647
return code;
@@ -1928,7 +1924,7 @@ static int32_t parse_hip_rdata(
19281924
memcpy(&octets[2], &pk_length, sizeof(pk_length));
19291925

19301926
take(parser, token);
1931-
while (is_contiguous_or_quoted(token)) {
1927+
while (is_contiguous(token)) {
19321928
if ((code = parse_name(parser, type, &fields[5], rdata, token)) < 0)
19331929
return code;
19341930
take(parser, token);
@@ -2061,7 +2057,7 @@ static int32_t parse_svcb_rdata(
20612057
return code;
20622058
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
20632059
return code;
2064-
if ((code = take_contiguous_or_quoted(parser, type, &fields[1], token)) < 0)
2060+
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
20652061
return code;
20662062
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
20672063
return code;
@@ -2090,7 +2086,7 @@ static int32_t parse_https_rdata(
20902086
return code;
20912087
if ((code = parse_int16(parser, type, &fields[0], rdata, token)) < 0)
20922088
return code;
2093-
if ((code = take_contiguous_or_quoted(parser, type, &fields[1], token)) < 0)
2089+
if ((code = take_contiguous(parser, type, &fields[1], token)) < 0)
20942090
return code;
20952091
if ((code = parse_name(parser, type, &fields[1], rdata, token)) < 0)
20962092
return code;

0 commit comments

Comments
 (0)