From 98e63d18fe85b29517ae8fb21ca94f37c7972652 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 10:04:57 +0200 Subject: Merging upstream version 3.3.5. Signed-off-by: Daniel Baumann --- src/libzscanner/error.c | 4 +- src/libzscanner/error.h | 3 +- src/libzscanner/scanner.c.g2 | 313 ++++++++++++++++++++++++++++++---------- src/libzscanner/scanner.c.t0 | 23 ++- src/libzscanner/scanner.h | 4 +- src/libzscanner/scanner_body.rl | 25 +++- src/libzscanner/version.h | 2 +- 7 files changed, 279 insertions(+), 95 deletions(-) (limited to 'src/libzscanner') diff --git a/src/libzscanner/error.c b/src/libzscanner/error.c index 8e571f9..a43db0e 100644 --- a/src/libzscanner/error.c +++ b/src/libzscanner/error.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 CZ.NIC, z.s.p.o. +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -167,6 +167,8 @@ static const err_table_t err_msgs[] = { "empty comma-separated list item" ), ERR_ITEM( ZS_FILE_ACCESS, "permission denied" ), + ERR_ITEM( ZS_BAD_ALPN_BACKSLASH, + "unscaped backslash character" ), ERR_ITEM( 0, NULL ) // Terminator }; diff --git a/src/libzscanner/error.h b/src/libzscanner/error.h index f54a750..87b73a9 100644 --- a/src/libzscanner/error.h +++ b/src/libzscanner/error.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 CZ.NIC, z.s.p.o. +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -96,6 +96,7 @@ enum err_codes { ZS_MISSING_SVCB_MANDATORY, ZS_EMPTY_LIST_ITEM, ZS_FILE_ACCESS, + ZS_BAD_ALPN_BACKSLASH, }; /*! diff --git a/src/libzscanner/scanner.c.g2 b/src/libzscanner/scanner.c.g2 index 66f6b1a..f97c3ae 100644 --- a/src/libzscanner/scanner.c.g2 +++ b/src/libzscanner/scanner.c.g2 @@ -40865,6 +40865,7 @@ tr1008: // Reset per-record contexts. s->long_string = false; s->comma_list = false; + s->pending_backslash = false; s->state = ZS_STATE_ERROR; @@ -40909,6 +40910,7 @@ tr1010: // Reset per-record contexts. s->long_string = false; s->comma_list = false; + s->pending_backslash = false; s->state = ZS_STATE_ERROR; @@ -41367,24 +41369,31 @@ tr1033: goto st319; tr1037: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41416,24 +41425,31 @@ tr1045: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41484,24 +41500,31 @@ case 319: goto tr1032; tr1036: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41514,24 +41537,31 @@ tr1044: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41551,24 +41581,31 @@ case 1409: goto st0; tr1038: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41603,24 +41640,31 @@ tr1046: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41674,24 +41718,31 @@ case 1410: goto tr1032; tr1039: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41701,24 +41752,31 @@ tr1047: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41866,24 +41924,31 @@ tr1048: goto st324; tr1052: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -41915,24 +41980,31 @@ tr1061: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -42006,24 +42078,31 @@ tr1049: goto st325; tr1053: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -42055,24 +42134,31 @@ tr1062: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -42122,24 +42208,31 @@ case 325: goto tr1032; tr1054: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -42149,24 +42242,31 @@ tr1063: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -42187,24 +42287,31 @@ case 326: goto tr1056; tr1055: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -42214,24 +42321,31 @@ tr1064: rdata_tail++; } { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {goto st307;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} } } } @@ -57047,6 +57161,10 @@ tr1951: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -57083,6 +57201,10 @@ tr1952: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -57126,6 +57248,10 @@ tr1953: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -57169,6 +57295,10 @@ tr1954: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -58174,6 +58304,7 @@ case 609: tr1949: { s->comma_list = true; + s->pending_backslash = false; } { if (rdata_tail < rdata_stop) { @@ -58264,6 +58395,10 @@ tr1955: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -58568,6 +58703,10 @@ tr1956: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -58919,6 +59058,10 @@ tr1957: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -59590,6 +59733,10 @@ tr2128: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -59686,6 +59833,10 @@ tr1958: } { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {goto st307;} + } } { s->item_length = rdata_tail - s->item_length2_location - 2; @@ -61488,6 +61639,7 @@ case 696: tr1950: { s->comma_list = true; + s->pending_backslash = false; } { if (rdata_tail < rdata_stop) { @@ -61552,6 +61704,7 @@ case 697: tr2127: { s->comma_list = true; + s->pending_backslash = false; } { if (rdata_tail < rdata_stop) { diff --git a/src/libzscanner/scanner.c.t0 b/src/libzscanner/scanner.c.t0 index 0909496..b1b2616 100644 --- a/src/libzscanner/scanner.c.t0 +++ b/src/libzscanner/scanner.c.t0 @@ -6983,6 +6983,7 @@ _match: // Reset per-record contexts. s->long_string = false; s->comma_list = false; + s->pending_backslash = false; s->state = ZS_STATE_ERROR; @@ -7528,24 +7529,31 @@ _match: break; case 68: { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); p--; {cs = 307;goto _again;} - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {cs = 307;goto _again;} } } } @@ -8844,11 +8852,16 @@ _match: case 292: { s->comma_list = true; + s->pending_backslash = false; } break; case 293: { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + p--; {cs = 307;goto _again;} + } } break; case 294: diff --git a/src/libzscanner/scanner.h b/src/libzscanner/scanner.h index b45ca48..140b4f1 100644 --- a/src/libzscanner/scanner.h +++ b/src/libzscanner/scanner.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 CZ.NIC, z.s.p.o. +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -157,6 +157,8 @@ struct zs_scanner { bool long_string; /*! Comma separated string list indication (svcb parsing). */ bool comma_list; + /*! Indication of a non-applied backslash. */ + bool pending_backslash; /*! Pointer to the actual dname storage (origin/owner/rdata). */ uint8_t *dname; diff --git a/src/libzscanner/scanner_body.rl b/src/libzscanner/scanner_body.rl index 34d51cd..a1ff46c 100644 --- a/src/libzscanner/scanner_body.rl +++ b/src/libzscanner/scanner_body.rl @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 CZ.NIC, z.s.p.o. +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -116,6 +116,7 @@ // Reset per-record contexts. s->long_string = false; s->comma_list = false; + s->pending_backslash = false; s->state = ZS_STATE_ERROR; @@ -656,24 +657,31 @@ } action _comma_list { - uint8_t *last_two = rdata_tail - 2; - uint16_t current_len = rdata_tail - s->item_length_location - 2; if (s->comma_list) { + uint8_t *last_two = rdata_tail - 2; + uint16_t current_len = rdata_tail - s->item_length_location - 2; if (last_two[1] == ',') { if (current_len <= 1) { WARN(ZS_EMPTY_LIST_ITEM); fhold; fgoto err_line; - } else if (last_two[0] != '\\') { // Start a new item. + } else if (last_two[0] != '\\' || !s->pending_backslash) { // Start a new item. *(s->item_length_location) = current_len; s->item_length_location = rdata_tail - 1; } else { // Remove backslash. last_two[0] = ','; rdata_tail--; + s->pending_backslash = false; } - } else if (current_len > 1 && last_two[1] == '\\') { - if (last_two[0] == '\\') { // Remove backslash. + } else if (last_two[1] == '\\') { + if (s->pending_backslash) { // Remove backslash. rdata_tail--; + s->pending_backslash = false; + } else { + s->pending_backslash = true; } + } else if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + fhold; fgoto err_line; } } } @@ -1800,9 +1808,14 @@ action _alpnl_init { s->comma_list = true; + s->pending_backslash = false; } action _alpnl_exit { s->comma_list = false; + if (s->pending_backslash) { + WARN(ZS_BAD_ALPN_BACKSLASH); + fhold; fgoto err_line; + } } action _mandatory_init { diff --git a/src/libzscanner/version.h b/src/libzscanner/version.h index 653d9bf..25520c7 100644 --- a/src/libzscanner/version.h +++ b/src/libzscanner/version.h @@ -18,7 +18,7 @@ #define ZSCANNER_VERSION_MAJOR 3 #define ZSCANNER_VERSION_MINOR 3 -#define ZSCANNER_VERSION_PATCH 0x04 +#define ZSCANNER_VERSION_PATCH 0x05 #define ZSCANNER_VERSION_HEX ((ZSCANNER_VERSION_MAJOR << 16) | \ (ZSCANNER_VERSION_MINOR << 8) | \ -- cgit v1.2.3