diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc index c881811b..1c3378a7 100644 --- a/libqpdf/JSON.cc +++ b/libqpdf/JSON.cc @@ -648,6 +648,7 @@ namespace ls_top, ls_number, ls_number_minus, + ls_number_leading_zero, ls_alpha, ls_string, ls_backslash, @@ -868,13 +869,20 @@ JSONParser::getToken() number_after_e = 0; number_saw_point = false; number_saw_e = false; - } else if ((*p >= '0') && (*p <= '9')) { + } else if ((*p >= '1') && (*p <= '9')) { lex_state = ls_number; number_before_point = 1; number_after_point = 0; number_after_e = 0; number_saw_point = false; number_saw_e = false; + } else if (*p == '0') { + lex_state = ls_number_leading_zero; + number_before_point = 1; + number_after_point = 0; + number_after_e = 0; + number_saw_point = false; + number_saw_e = false; } else if (*p == '.') { lex_state = ls_number; number_before_point = 0; @@ -898,7 +906,7 @@ JSONParser::getToken() lex_state = ls_number; } else if (*p == '0') { ++number_before_point; - lex_state = ls_number; + lex_state = ls_number_leading_zero; } else { QTC::TC("libtests", "JSON parse number minus no digits"); throw std::runtime_error( @@ -907,6 +915,25 @@ JSONParser::getToken() } break; + case ls_number_leading_zero: + if (*p == '.') { + lex_state = ls_number; + } else if (*p == 'e') { + lex_state = ls_number; + } else if (QUtil::is_space(*p)) { + action = ignore; + ready = true; + } else if (strchr("{}[]:,", *p)) { + action = reread; + ready = true; + } else { + QTC::TC("libtests", "JSON parse leading zero"); + throw std::runtime_error( + "JSON: offset " + std::to_string(offset) + + ": number with leading zero"); + } + break; + case ls_number: if ((*p >= '0') && (*p <= '9')) { if (number_saw_e) { @@ -1037,6 +1064,7 @@ JSONParser::getToken() case ls_number: case ls_number_minus: + case ls_number_leading_zero: case ls_alpha: // okay break; @@ -1111,6 +1139,7 @@ JSONParser::handleToken() case ls_number: case ls_number_minus: + case ls_number_leading_zero: if (number_saw_point && (number_after_point == 0)) { // QTC::TC("libtests", "JSON parse decimal with no digits"); throw std::runtime_error( @@ -1120,7 +1149,6 @@ JSONParser::handleToken() if ((number_before_point > 1) && ((first_char == '0') || ((first_char == '-') && (token.at(1) == '0')))) { - QTC::TC("libtests", "JSON parse leading zero"); throw std::runtime_error( "JSON: offset " + std::to_string(offset) + ": number with leading zero"); diff --git a/libtests/qtest/json_parse/bad-32.out b/libtests/qtest/json_parse/bad-32.out index 4372e0cf..41a681c0 100644 --- a/libtests/qtest/json_parse/bad-32.out +++ b/libtests/qtest/json_parse/bad-32.out @@ -1 +1 @@ -exception: bad-32.json: JSON: offset 5: number with leading zero +exception: bad-32.json: JSON: offset 1: number with leading zero diff --git a/libtests/qtest/json_parse/bad-33.out b/libtests/qtest/json_parse/bad-33.out index ae41e48b..98a72942 100644 --- a/libtests/qtest/json_parse/bad-33.out +++ b/libtests/qtest/json_parse/bad-33.out @@ -1 +1 @@ -exception: bad-33.json: JSON: offset 6: number with leading zero +exception: bad-33.json: JSON: offset 2: number with leading zero