Commit 77ceebd6c9ef227be3adda6f5ba2a1211e5c6140
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()) { | ... | ... |