From: Wouter Wijngaards Date: Mon, 3 Feb 2014 14:28:57 +0000 (+0000) Subject: - Fix parse in sldns of quoted parenthesized text strings. X-Git-Tag: release-1.4.22rc1~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2b03defcef34dcd97d3c8629c298a7e768b428f;p=thirdparty%2Funbound.git - Fix parse in sldns of quoted parenthesized text strings. git-svn-id: file:///svn/unbound/trunk@3066 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index e00c80623..1243ac049 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 3 February 2014: Wouter - Detect libevent2 install automatically by configure. - Fixup link with lib/event2 subdir. + - Fix parse in sldns of quoted parenthesized text strings. 31 January 2014: Wouter - unit test for ldns wire to str and back with zones, root, nlnetlabs diff --git a/ldns/str2wire.c b/ldns/str2wire.c index e88bbf7da..5a09a1326 100644 --- a/ldns/str2wire.c +++ b/ldns/str2wire.c @@ -534,7 +534,7 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len, const sldns_rr_descriptor *desc = sldns_rr_descript((uint16_t)rr_type); uint16_t r_cnt, r_min, r_max; size_t rr_cur_len = dname_len + 10, pre_data_pos, token_strlen; - int was_unknown_rr_format = 0, parens = 0, status, quoted; + int was_unknown_rr_format = 0, parens = 0, status, quoted, tokquote; const char* delimiters; sldns_rdf_type rdftype; /* a desc is always returned */ @@ -560,14 +560,49 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len, } pre_data_pos = sldns_buffer_position(strbuf); - if(sldns_bget_token_par(strbuf, token, delimiters, token_len, - &parens, quoted?NULL:" \t") == -1) { + if(sldns_bget_token_par(strbuf, token, quoted?"\"":delimiters, + token_len, &parens, quoted?NULL:" \t") == -1) { break; } - /* hmmz, rfc3597 specifies that any type can be represented + token_strlen = strlen(token); + /* check if not quoted yet, and we have encountered quotes */ + if(!quoted && sldns_rdf_type_maybe_quoted(rdftype) && + token_strlen >= 2 && + (token[0] == '"' || token[0] == '\'') && + (token[token_strlen-1] == '"' || token[token_strlen-1] == '\'')) { + /* move token two smaller (quotes) with endnull */ + memmove(token, token+1, token_strlen-2); + token[token_strlen-2] = 0; + token_strlen -= 2; + quoted = 1; + tokquote = 1; /* do not read endquotechar from buffer */ + } else if(!quoted && sldns_rdf_type_maybe_quoted(rdftype) && + token_strlen >= 2 && + (token[0] == '"' || token[0] == '\'')) { + /* got the start quote (remove it) but read remainder + * of quoted string as well into remainder of token */ + memmove(token, token+1, token_strlen-1); + token[token_strlen-1] = 0; + token_strlen -= 1; + quoted = 1; + tokquote = 0; + /* rewind buffer over skipped whitespace */ + while(sldns_buffer_position(strbuf) > 0 && + (sldns_buffer_current(strbuf)[-1] == ' ' || + sldns_buffer_current(strbuf)[-1] == '\t')) { + sldns_buffer_skip(strbuf, -1); + } + if(sldns_bget_token_par(strbuf, token+token_strlen, + "\"", token_len-token_strlen, + &parens, NULL) == -1) { + break; + } + token_strlen = strlen(token); + } else tokquote = 0; + + /* rfc3597 specifies that any type can be represented * with \# method, which can contain spaces... * it does specify size though... */ - token_strlen = strlen(token); /* unknown RR data */ if(token_strlen>=2 && strncmp(token, "\\#", 2) == 0 && @@ -577,7 +612,7 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len, token_len, rr, rr_len, &rr_cur_len, pre_data_pos)) != 0) return status; - } else { + } else if(token_strlen > 0 || quoted) { /* normal RR */ if((status=rrinternal_parse_rdf(strbuf, token, token_len, rr, *rr_len, &rr_cur_len, rdftype, @@ -586,7 +621,7 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len, return status; } } - if(quoted) { + if(quoted && !tokquote) { if(sldns_buffer_available(strbuf, 1)) sldns_buffer_skip(strbuf, 1); else break; diff --git a/testdata/test_ldnsrr.5 b/testdata/test_ldnsrr.5 index 862eee73e..c99d2a65f 100644 --- a/testdata/test_ldnsrr.5 +++ b/testdata/test_ldnsrr.5 @@ -113,3 +113,9 @@ eui64 IN EUI64 00-00-5e-ef-00-00-00-2a ;error.eui64 IN EUI64 00-00-5e-ef-00-00-00-2a-ef ; too long ;error.eui64 IN EUI64 00-00-5e-ef-r0-00-00-2a ; non-hex +; Tests for Unbound +; the text strings should be identical, with () and without (), parse test. +txt1 TXT "a" "bb" "ccc" +txt2 TXT ( "a" "bb" "ccc" ) +txt3 TXT "a b" "bb" " cc c " " " +txt4 TXT ( "a b" "bb" " cc c " " " ) diff --git a/testdata/test_ldnsrr.c5 b/testdata/test_ldnsrr.c5 index 3ca2e81c4..45414eaa3 100644 --- a/testdata/test_ldnsrr.c5 +++ b/testdata/test_ldnsrr.c5 @@ -128,3 +128,11 @@ caa. 3600 IN CAA \# 70 020461757468303E3039060A2B06010401D6790203010609608648016 eui48. 3600 IN EUI48 00-00-5e-90-01-2a 05657569363400006D000100000E10000800005EEF0000002A eui64. 3600 IN EUI64 00-00-5e-ef-00-00-00-2a +0474787431000010000100000E100009016102626203636363 +txt1. 3600 IN TXT "a" "bb" "ccc" +0474787432000010000100000E100009016102626203636363 +txt2. 3600 IN TXT "a" "bb" "ccc" +0474787433000010000100000E10001003612062026262062063632063200120 +txt3. 3600 IN TXT "a b" "bb" " cc c " " " +0474787434000010000100000E10001003612062026262062063632063200120 +txt4. 3600 IN TXT "a b" "bb" " cc c " " "