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 1137  
1138 1138 std::string s_value;
1139 1139 std::shared_ptr<JSON> item;
  1140 + auto tos = stack.empty() ? nullptr : stack.back();
1140 1141  
1141 1142 switch (lex_state) {
1142 1143 case ls_begin_dict:
... ... @@ -1180,16 +1181,24 @@ JSONParser::handleToken()
1180 1181 return;
1181 1182  
1182 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 1186 QTC::TC("libtests", "JSON parse unexpected ]");
1188 1187 throw std::runtime_error(
1189 1188 "JSON: offset " + std::to_string(offset) +
1190 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 1203 case ls_end_dict:
1195 1204 if (!((parser_state == ps_dict_begin) ||
... ... @@ -1199,7 +1208,17 @@ JSONParser::handleToken()
1199 1208 "JSON: offset " + std::to_string(offset) +
1200 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 1223 case ls_number:
1205 1224 item = std::make_shared<JSON>(JSON::makeNumber(token));
... ... @@ -1286,68 +1305,52 @@ JSONParser::handleToken()
1286 1305 // whatever we need to do with it.
1287 1306  
1288 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 1356 if (reactor && item.get()) {
... ...