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,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()) { |