Commit 83f972ceda20e244f52bde7ac052e6931a6d33d3

Authored by m-holger
1 parent 8fd6e1c5

Refactor end of input handling in JSONParser

libqpdf/JSON.cc
@@ -1012,7 +1012,7 @@ JSONParser::getToken() @@ -1012,7 +1012,7 @@ JSONParser::getToken()
1012 case ls_number: 1012 case ls_number:
1013 // We only get here after we have seen an exponent. 1013 // We only get here after we have seen an exponent.
1014 if ((*p >= '0') && (*p <= '9')) { 1014 if ((*p >= '0') && (*p <= '9')) {
1015 - ++number_after_e; 1015 + ++number_after_e;
1016 } else if (QUtil::is_space(*p)) { 1016 } else if (QUtil::is_space(*p)) {
1017 action = ignore; 1017 action = ignore;
1018 ready = true; 1018 ready = true;
@@ -1093,38 +1093,27 @@ JSONParser::getToken() @@ -1093,38 +1093,27 @@ JSONParser::getToken()
1093 } 1093 }
1094 } 1094 }
1095 if (done) { 1095 if (done) {
1096 - if ((!token.empty()) && (!ready)) { 1096 + if (!token.empty() && !ready) {
1097 switch (lex_state) { 1097 switch (lex_state) {
1098 case ls_top: 1098 case ls_top:
1099 // Can't happen 1099 // Can't happen
1100 throw std::logic_error("tok_start set in ls_top while parsing"); 1100 throw std::logic_error("tok_start set in ls_top while parsing");
1101 break; 1101 break;
1102 1102
1103 - case ls_number:  
1104 - case ls_number_minus:  
1105 case ls_number_leading_zero: 1103 case ls_number_leading_zero:
1106 case ls_number_before_point: 1104 case ls_number_before_point:
1107 - case ls_number_point:  
1108 case ls_number_after_point: 1105 case ls_number_after_point:
1109 - case ls_number_e:  
1110 - case ls_number_e_sign:  
1111 - case ls_alpha:  
1112 - // okay 1106 + lex_state = ls_number;
1113 break; 1107 break;
1114 1108
1115 - case ls_u4:  
1116 - QTC::TC("libtests", "JSON parse premature end of u");  
1117 - throw std::runtime_error(  
1118 - "JSON: offset " + std::to_string(offset - u_count - 1) +  
1119 - ": \\u must be followed by four characters");  
1120 -  
1121 - case ls_string:  
1122 - case ls_backslash:  
1123 - QTC::TC("libtests", "JSON parse unterminated string");  
1124 - throw std::runtime_error(  
1125 - "JSON: offset " + std::to_string(offset) +  
1126 - ": unterminated string"); 1109 + case ls_number:
  1110 + case ls_alpha:
  1111 + // terminal state
1127 break; 1112 break;
  1113 +
  1114 + default:
  1115 + QTC::TC("libtests", "JSON parse ls premature end of input");
  1116 + throw std::runtime_error("JSON: premature end of input");
1128 } 1117 }
1129 } 1118 }
1130 } 1119 }
@@ -1181,32 +1170,6 @@ JSONParser::handleToken() @@ -1181,32 +1170,6 @@ JSONParser::handleToken()
1181 break; 1170 break;
1182 1171
1183 case ls_number: 1172 case ls_number:
1184 - case ls_number_minus:  
1185 - case ls_number_leading_zero:  
1186 - case ls_number_before_point:  
1187 - case ls_number_point:  
1188 - case ls_number_after_point:  
1189 - case ls_number_e:  
1190 - case ls_number_e_sign:  
1191 - if (number_saw_point && (number_after_point == 0)) {  
1192 - // QTC::TC("libtests", "JSON parse decimal with no digits");  
1193 - throw std::runtime_error(  
1194 - "JSON: offset " + std::to_string(offset) +  
1195 - ": decimal point with no digits");  
1196 - }  
1197 - if ((number_before_point > 1) &&  
1198 - ((first_char == '0') ||  
1199 - ((first_char == '-') && (token.at(1) == '0')))) {  
1200 - throw std::runtime_error(  
1201 - "JSON: offset " + std::to_string(offset) +  
1202 - ": number with leading zero");  
1203 - }  
1204 - if ((number_before_point == 0) && (number_after_point == 0)) {  
1205 - // QTC::TC("libtests", "JSON parse number no digits");  
1206 - throw std::runtime_error(  
1207 - "JSON: offset " + std::to_string(offset) +  
1208 - ": number with no digits");  
1209 - }  
1210 item = std::make_shared<JSON>(JSON::makeNumber(token)); 1173 item = std::make_shared<JSON>(JSON::makeNumber(token));
1211 break; 1174 break;
1212 1175
@@ -1229,10 +1192,9 @@ JSONParser::handleToken() @@ -1229,10 +1192,9 @@ JSONParser::handleToken()
1229 item = std::make_shared<JSON>(JSON::makeString(s_value)); 1192 item = std::make_shared<JSON>(JSON::makeString(s_value));
1230 break; 1193 break;
1231 1194
1232 - case ls_backslash:  
1233 - case ls_u4: 1195 + default:
1234 throw std::logic_error( 1196 throw std::logic_error(
1235 - "tok_end is set while state = ls_backslash or ls_u4"); 1197 + "JSONParser::handleToken : non-terminal lexer state encountered");
1236 break; 1198 break;
1237 } 1199 }
1238 1200
libtests/libtests.testcov
@@ -79,9 +79,8 @@ JSON parse number minus no digits 0 @@ -79,9 +79,8 @@ JSON parse number minus no digits 0
79 JSON parse incomplete number 0 79 JSON parse incomplete number 0
80 JSON parse keyword bad character 0 80 JSON parse keyword bad character 0
81 JSON parse backslash bad character 0 81 JSON parse backslash bad character 0
82 -JSON parse unterminated string 0  
83 JSON parse leading zero 0 82 JSON parse leading zero 0
84 -JSON parse premature end of u 0 83 +JSON parse ls premature end of input 0
85 JSON parse bad hex after u 0 84 JSON parse bad hex after u 0
86 JSONHandler unhandled value 0 85 JSONHandler unhandled value 0
87 JSONHandler unexpected key 0 86 JSONHandler unexpected key 0
libtests/qtest/json_parse/bad-27.out
1 -exception: bad-27.json: JSON: offset 6: unterminated string 1 +exception: bad-27.json: JSON: premature end of input
libtests/qtest/json_parse/bad-28.out
1 -exception: bad-28.json: JSON: offset 16: unterminated string 1 +exception: bad-28.json: JSON: premature end of input
libtests/qtest/json_parse/bad-34.out
1 -exception: bad-34.json: JSON: offset 3: \u must be followed by four characters 1 +exception: bad-34.json: JSON: premature end of input