diff --git a/src/libknot/util/error.h b/src/libknot/util/error.h index 46c19d40210f6d7b5c6420986bc93318731d4a8f..db726f04145f22d78fe53f4b32c25781dadf8ecb 100644 --- a/src/libknot/util/error.h +++ b/src/libknot/util/error.h @@ -94,6 +94,7 @@ enum knot_error { ZSCANNER_EBAD_GATEWAY, ZSCANNER_EBAD_APL, ZSCANNER_EBAD_RDATA, + ZSCANNER_EBAD_HEX_RDATA, ZSCANNER_EBAD_HEX_CHAR, ZSCANNER_EBAD_BASE64_CHAR, ZSCANNER_EBAD_BASE32HEX_CHAR, @@ -105,6 +106,7 @@ enum knot_error { ZSCANNER_EBAD_TIME, ZSCANNER_EBAD_BITMAP, ZSCANNER_ETEXT_OVERFLOW, + ZSCANNER_EBAD_TEXT, ZSCANNER_EBAD_DIRECTIVE, ZSCANNER_EBAD_TTL, ZSCANNER_EBAD_ORIGIN, diff --git a/src/libknot/util/libknot_error.c b/src/libknot/util/libknot_error.c index 8acecb77b859bd04e41ef61ce96831542242c47f..874e49f7fa3d7ef63a5c55db8a1f86c4a6d08027 100644 --- a/src/libknot/util/libknot_error.c +++ b/src/libknot/util/libknot_error.c @@ -76,6 +76,7 @@ const error_table_t knot_error_msgs[] = { {ZSCANNER_EBAD_GATEWAY, "Bad gateway!"}, {ZSCANNER_EBAD_APL, "Bad adress prefix list!"}, {ZSCANNER_EBAD_RDATA, "Bad record data!"}, + {ZSCANNER_EBAD_HEX_RDATA, "Bad record data in hex format!"}, {ZSCANNER_EBAD_HEX_CHAR, "Bad hexadecimal character!"}, {ZSCANNER_EBAD_BASE64_CHAR, "Bad Base64 character!"}, {ZSCANNER_EBAD_BASE32HEX_CHAR, "Bad Base32hex character!"}, @@ -87,6 +88,7 @@ const error_table_t knot_error_msgs[] = { {ZSCANNER_EBAD_TIME, "Bad time!"}, {ZSCANNER_EBAD_BITMAP, "Bad bitmap!"}, {ZSCANNER_ETEXT_OVERFLOW, "Text is too long!"}, + {ZSCANNER_EBAD_TEXT, "Bad text string!"}, {ZSCANNER_EBAD_DIRECTIVE, "Bad directive!"}, {ZSCANNER_EBAD_TTL, "Bad zone TTL!"}, {ZSCANNER_EBAD_ORIGIN, "Bad zone origin!"}, diff --git a/src/zscanner/scanner.h b/src/zscanner/scanner.h index 312591ad5a23e4603b462d5dbbb5f3403757d9ad..62feed394718df91e28fb9cf2472548e53812012 100644 --- a/src/zscanner/scanner.h +++ b/src/zscanner/scanner.h @@ -42,7 +42,7 @@ #define INET4_ADDR_LENGTH 4 #define INET6_ADDR_LENGTH 16 -#define RAGEL_STACK_SIZE 8 // But 2 should suffices (2 nested fcalls). +#define RAGEL_STACK_SIZE 16 // Each nested call needs one. #define ASCII_0 48 diff --git a/src/zscanner/scanner_body.rl b/src/zscanner/scanner_body.rl index 33dbf683169501d1e76c4b7ee0788da2374ceae3..543e79b1b1e79447705a440c38ca35b4595ff889 100644 --- a/src/zscanner/scanner_body.rl +++ b/src/zscanner/scanner_body.rl @@ -476,6 +476,10 @@ fhold; fgoto err_line; } } + action _text_error { + SCANNER_ERROR(ZSCANNER_EBAD_TEXT); + fhold; fgoto err_line; + } action _text_dec_init { if (rdata_tail <= rdata_stop) { @@ -502,11 +506,14 @@ . digit {3} $_text_dec %_text_dec_exit # "DDD" rest. ) ); - quoted_text_char = text_char | ([ \t;] $_text_char); + quoted_text_char = + ( text_char + | ([ \t;] | [\n] when { s->multiline }) $_text_char + ); # Text string machine instantiation (for smaller code). text_ := (('\"' . quoted_text_char* . '\"') | text_char+) - %_ret . all_wchar; + $!_text_error %_ret . all_wchar; text = ^all_wchar ${ fhold; fcall text_; }; # Text string with forward 1-byte length. @@ -1382,10 +1389,23 @@ # END # BEGIN - Hexadecimal rdata processing + action _hex_r_data_error { + SCANNER_WARNING(ZSCANNER_EBAD_HEX_RDATA); + fhold; fgoto err_line; + } - zero_hex_r_data = "\\#" . sep . '0'; - hex_r_data = "\\#" . sep . length_number . sep . type_data; + hex_r_data_ := + (sep . length_number . sep . type_data) + $!_hex_r_data_error %_ret . end_wchar; + hex_r_data = "\\#" @{ fcall hex_r_data_; }; + unknown_hex_r_data_ := + (sep . + ( ('0' %_ret . all_wchar) + | (length_number . sep . type_data %_ret . end_wchar) + ) + ) $!_hex_r_data_error; + unknown_hex_r_data = "\\#" @{ fcall unknown_hex_r_data_; }; # END # BEGIN - Rdata processing @@ -1536,137 +1556,180 @@ } r_data_a := - ( sep . ipv4_addr_write ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | ipv4_addr_write + ) + ) $!_r_data_error %_ret . all_wchar; r_data_ns := - ( sep . r_dname ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | r_dname + ) + ) $!_r_data_error %_ret . all_wchar; r_data_soa := - ( sep . r_dname . sep . r_dname . sep . num32 . sep . time32 . - sep . time32 . sep . time32 . sep . time32 ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | r_dname . sep . r_dname . sep . num32 . sep . time32 . sep . + time32 . sep . time32 . sep . time32 + ) + ) $!_r_data_error %_ret . all_wchar; r_data_hinfo := - ( sep . text_item . sep . text_item ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | text_item . sep . text_item + ) + ) $!_r_data_error %_ret . all_wchar; r_data_minfo := - ( sep . r_dname . sep . r_dname ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | r_dname . sep . r_dname + ) + ) $!_r_data_error %_ret . all_wchar; r_data_mx := - ( sep . num16 . sep . r_dname ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | num16 . sep . r_dname + ) + ) $!_r_data_error %_ret . all_wchar; r_data_txt := - ( sep . text_array ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | text_array + ) + ) $!_r_data_error %_ret . end_wchar; r_data_rp := - ( sep . r_dname . sep . r_dname ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | r_dname . sep . r_dname + ) + ) $!_r_data_error %_ret . all_wchar; r_data_aaaa := - ( sep . ipv6_addr_write ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | ipv6_addr_write + ) + ) $!_r_data_error %_ret . all_wchar; r_data_loc := - ( sep . loc ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | loc + ) + ) $!_r_data_error %_ret . end_wchar; r_data_srv := - ( sep . num16 . sep . num16 . sep . num16 . sep . r_dname ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | num16 . sep . num16 . sep . num16 . sep . r_dname + ) + ) $!_r_data_error %_ret . all_wchar; r_data_naptr := - ( sep . num16 . sep . num16 . sep . text_item . sep . - text_item . sep . text_item . sep . r_dname ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | num16 . sep . num16 . sep . text_item . sep . text_item . sep . + text_item . sep . r_dname + ) + ) $!_r_data_error %_ret . all_wchar; r_data_cert := - ( sep . num16 . sep . num16 . sep . num8 . sep . base64 ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | num16 . sep . num16 . sep . num8 . sep . base64 + ) + ) $!_r_data_error %_ret . end_wchar; r_data_apl := - ( sep . apl_array ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | apl_array + ) + ) $!_r_data_error %_ret . end_wchar; r_data_ds := - ( sep . num16 . sep . num8 . sep . num8 . sep . hex_array ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | num16 . sep . num8 . sep . num8 . sep . hex_array + ) + ) $!_r_data_error %_ret . end_wchar; r_data_sshfp := - ( sep . num8 . sep . num8 . sep . hex_array ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | num8 . sep . num8 . sep . hex_array + ) + ) $!_r_data_error %_ret . end_wchar; r_data_ipseckey := - ( sep . num8 . sep . gateway . sep . base64 ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | num8 . sep . gateway . sep . base64 + ) + ) $!_r_data_error %_ret . end_wchar; r_data_rrsig := - ( sep . type_num . sep . num8 . sep . num8 . sep . num32 . - sep . timestamp . sep . timestamp . sep . num16 . sep . r_dname . - sep . base64 ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | type_num . sep . num8 . sep . num8 . sep . num32 . sep . + timestamp . sep . timestamp . sep . num16 . sep . r_dname . + sep . base64 + ) + ) $!_r_data_error %_ret . end_wchar; r_data_nsec := - ( sep . r_dname . bitmap ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | r_dname . bitmap + ) + ) $!_r_data_error %_ret . all_wchar; r_data_dnskey := - ( sep . num16 . sep . num8 . sep . num8 . sep . base64 ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | num16 . sep . num8 . sep . num8 . sep . base64 + ) + ) $!_r_data_error %_ret . end_wchar; r_data_dhcid := - ( sep . base64 ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | base64 + ) + ) $!_r_data_error %_ret . end_wchar; r_data_nsec3 := - ( sep . num8 . sep . num8 . sep . num16 . sep . salt . sep . - hash . bitmap ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | num8 . sep . num8 . sep . num16 . sep . salt . sep . hash . bitmap + ) + ) $!_r_data_error %_ret . all_wchar; r_data_nsec3param := - ( sep . num8 . sep . num8 . sep . num16 . sep . salt ) - $!_r_data_error - %_ret . all_wchar; + (sep . + ( hex_r_data + | num8 . sep . num8 . sep . num16 . sep . salt + ) + ) $!_r_data_error %_ret . all_wchar; r_data_tlsa := - ( sep . num8 . sep . num8 . sep . num8 . sep . hex_array ) - $!_r_data_error - %_ret . end_wchar; + (sep . + ( hex_r_data + | num8 . sep . num8 . sep . num8 . sep . hex_array + ) + ) $!_r_data_error %_ret . end_wchar; r_data_type := - ( sep . - ( zero_hex_r_data %_ret . all_wchar - | hex_r_data %_ret . end_wchar - ) - ) - $!_r_data_error; + (sep . unknown_hex_r_data) + $!_r_data_error %_ret . all_wchar; r_type_r_data = ( "A"i %_r_data_a diff --git a/src/zscanner/test/data/test1 b/src/zscanner/test/data/test1 index 3e75e2b8e555d0692c985395fddc9c7eccde4c72..9c4e29679c583cdfef5a8a6fbae6282577c9e12c 100644 --- a/src/zscanner/test/data/test1 +++ b/src/zscanner/test/data/test1 @@ -67,3 +67,4 @@ c TYPE6231 \# 1 05 d TYPE0 \# 0 e TYPE65535 \# 0 e TYPE65536 \# 0 + A \# 2 03040201 \ No newline at end of file diff --git a/src/zscanner/test/data/test3 b/src/zscanner/test/data/test3 index 59ac4fa0343c243057cd8a0361fc8b61794122fc..f6da6f380ac5402e586b3b4a1b1a9a2143c1d85b 100644 --- a/src/zscanner/test/data/test3 +++ b/src/zscanner/test/data/test3 @@ -50,3 +50,8 @@ www.zdrojak.root.cz. 600 IN NSEC root.cz. A TXT "a ; b" TXT \043\ - + TXT ( +"one +two +three") + TXT next \ No newline at end of file