Commit 77ceebd6c9ef227be3adda6f5ba2a1211e5c6140

Authored by m-holger
1 parent a7338ab1

In JSONParser::handleToken move processing for ls_end_array and ls_end_dict into switch statement

Showing 1 changed file with 65 additions and 62 deletions
libqpdf/JSON.cc
@@ -1137,6 +1137,7 @@ JSONParser::handleToken() @@ -1137,6 +1137,7 @@ JSONParser::handleToken()
1137 1137
1138 std::string s_value; 1138 std::string s_value;
1139 std::shared_ptr<JSON> item; 1139 std::shared_ptr<JSON> item;
  1140 + auto tos = stack.empty() ? nullptr : stack.back();
1140 1141
1141 switch (lex_state) { 1142 switch (lex_state) {
1142 case ls_begin_dict: 1143 case ls_begin_dict:
@@ -1180,16 +1181,24 @@ JSONParser::handleToken() @@ -1180,16 +1181,24 @@ JSONParser::handleToken()
1180 return; 1181 return;
1181 1182
1182 case ls_end_array: 1183 case ls_end_array:
1183 - if (!((parser_state == ps_array_begin) ||  
1184 - (parser_state == ps_array_after_item)))  
1185 -  
1186 - { 1184 + if (!(parser_state == ps_array_begin ||
  1185 + parser_state == ps_array_after_item)) {
1187 QTC::TC("libtests", "JSON parse unexpected ]"); 1186 QTC::TC("libtests", "JSON parse unexpected ]");
1188 throw std::runtime_error( 1187 throw std::runtime_error(
1189 "JSON: offset " + std::to_string(offset) + 1188 "JSON: offset " + std::to_string(offset) +
1190 ": unexpected array end delimiter"); 1189 ": unexpected array end delimiter");
1191 } 1190 }
1192 - break; 1191 + parser_state = ps_stack.back();
  1192 + ps_stack.pop_back();
  1193 + tos->setEnd(offset);
  1194 + if (reactor) {
  1195 + reactor->containerEnd(*tos);
  1196 + }
  1197 + if (parser_state != ps_done) {
  1198 + stack.pop_back();
  1199 + }
  1200 + lex_state = ls_top;
  1201 + return;
1193 1202
1194 case ls_end_dict: 1203 case ls_end_dict:
1195 if (!((parser_state == ps_dict_begin) || 1204 if (!((parser_state == ps_dict_begin) ||
@@ -1199,7 +1208,17 @@ JSONParser::handleToken() @@ -1199,7 +1208,17 @@ JSONParser::handleToken()
1199 "JSON: offset " + std::to_string(offset) + 1208 "JSON: offset " + std::to_string(offset) +
1200 ": unexpected dictionary end delimiter"); 1209 ": unexpected dictionary end delimiter");
1201 } 1210 }
1202 - break; 1211 + parser_state = ps_stack.back();
  1212 + ps_stack.pop_back();
  1213 + tos->setEnd(offset);
  1214 + if (reactor) {
  1215 + reactor->containerEnd(*tos);
  1216 + }
  1217 + if (parser_state != ps_done) {
  1218 + stack.pop_back();
  1219 + }
  1220 + lex_state = ls_top;
  1221 + return;
1203 1222
1204 case ls_number: 1223 case ls_number:
1205 item = std::make_shared<JSON>(JSON::makeNumber(token)); 1224 item = std::make_shared<JSON>(JSON::makeNumber(token));
@@ -1286,68 +1305,52 @@ JSONParser::handleToken() @@ -1286,68 +1305,52 @@ JSONParser::handleToken()
1286 // whatever we need to do with it. 1305 // whatever we need to do with it.
1287 1306
1288 parser_state_e next_state = ps_top; 1307 parser_state_e next_state = ps_top;
1289 - if ((lex_state == ls_end_array) || (lex_state == ls_end_dict)) {  
1290 - next_state = ps_stack.back();  
1291 - ps_stack.pop_back();  
1292 - auto tos = stack.back();  
1293 - tos->setEnd(offset);  
1294 - if (reactor) {  
1295 - reactor->containerEnd(*tos);  
1296 - }  
1297 - if (next_state != ps_done) {  
1298 - stack.pop_back(); 1308 +
  1309 + if (!(item->isArray() || item->isDictionary())) {
  1310 + item->setStart(token_start);
  1311 + item->setEnd(offset);
  1312 + }
  1313 +
  1314 + switch (parser_state) {
  1315 + case ps_dict_begin:
  1316 + case ps_dict_after_comma:
  1317 + this->dict_key = s_value;
  1318 + this->dict_key_offset = item->getStart();
  1319 + item = nullptr;
  1320 + next_state = ps_dict_after_key;
  1321 + break;
  1322 +
  1323 + case ps_dict_after_colon:
  1324 + if (tos->checkDictionaryKeySeen(dict_key)) {
  1325 + QTC::TC("libtests", "JSON parse duplicate key");
  1326 + throw std::runtime_error(
  1327 + "JSON: offset " + std::to_string(dict_key_offset) +
  1328 + ": duplicated dictionary key");
1299 } 1329 }
1300 - } else if (item.get()) {  
1301 - if (!(item->isArray() || item->isDictionary())) {  
1302 - item->setStart(token_start);  
1303 - item->setEnd(offset); 1330 + if (!reactor || !reactor->dictionaryItem(dict_key, *item)) {
  1331 + tos->addDictionaryMember(dict_key, *item);
1304 } 1332 }
  1333 + next_state = ps_dict_after_item;
  1334 + break;
1305 1335
1306 - std::shared_ptr<JSON> tos;  
1307 - if (!stack.empty()) {  
1308 - tos = stack.back(); 1336 + case ps_array_begin:
  1337 + case ps_array_after_comma:
  1338 + if (!reactor || !reactor->arrayItem(*item)) {
  1339 + tos->addArrayElement(*item);
1309 } 1340 }
1310 - switch (parser_state) {  
1311 - case ps_dict_begin:  
1312 - case ps_dict_after_comma:  
1313 - this->dict_key = s_value;  
1314 - this->dict_key_offset = item->getStart();  
1315 - item = nullptr;  
1316 - next_state = ps_dict_after_key;  
1317 - break;  
1318 -  
1319 - case ps_dict_after_colon:  
1320 - if (tos->checkDictionaryKeySeen(dict_key)) {  
1321 - QTC::TC("libtests", "JSON parse duplicate key");  
1322 - throw std::runtime_error(  
1323 - "JSON: offset " + std::to_string(dict_key_offset) +  
1324 - ": duplicated dictionary key");  
1325 - }  
1326 - if (!reactor || !reactor->dictionaryItem(dict_key, *item)) {  
1327 - tos->addDictionaryMember(dict_key, *item);  
1328 - }  
1329 - next_state = ps_dict_after_item;  
1330 - break;  
1331 -  
1332 - case ps_array_begin:  
1333 - case ps_array_after_comma:  
1334 - if (!reactor || !reactor->arrayItem(*item)) {  
1335 - tos->addArrayElement(*item);  
1336 - }  
1337 - next_state = ps_array_after_item;  
1338 - break; 1341 + next_state = ps_array_after_item;
  1342 + break;
1339 1343
1340 - case ps_top:  
1341 - next_state = ps_done;  
1342 - break; 1344 + case ps_top:
  1345 + next_state = ps_done;
  1346 + break;
1343 1347
1344 - case ps_dict_after_key:  
1345 - case ps_dict_after_item:  
1346 - case ps_array_after_item:  
1347 - case ps_done:  
1348 - throw std::logic_error(  
1349 - "JSONParser::handleToken: unexpected parser state");  
1350 - } 1348 + case ps_dict_after_key:
  1349 + case ps_dict_after_item:
  1350 + case ps_array_after_item:
  1351 + case ps_done:
  1352 + throw std::logic_error(
  1353 + "JSONParser::handleToken: unexpected parser state");
1351 } 1354 }
1352 1355
1353 if (reactor && item.get()) { 1356 if (reactor && item.get()) {