Commit 126dd31cad27991d40805df9582d5546464310c1

Authored by m-holger
1 parent 6748bd33

In JSONParser combine stacks

Showing 1 changed file with 20 additions and 12 deletions
libqpdf/JSON.cc
@@ -661,6 +661,18 @@ namespace @@ -661,6 +661,18 @@ namespace
661 ls_comma, 661 ls_comma,
662 }; 662 };
663 663
  664 + struct StackFrame
  665 + {
  666 + StackFrame(parser_state_e state, std::shared_ptr<JSON>& item) :
  667 + state(state),
  668 + item(item)
  669 + {
  670 + }
  671 +
  672 + parser_state_e state;
  673 + std::shared_ptr<JSON> item;
  674 + };
  675 +
664 InputSource& is; 676 InputSource& is;
665 JSON::Reactor* reactor; 677 JSON::Reactor* reactor;
666 lex_state_e lex_state; 678 lex_state_e lex_state;
@@ -673,8 +685,7 @@ namespace @@ -673,8 +685,7 @@ namespace
673 std::string token; 685 std::string token;
674 qpdf_offset_t token_start{0}; 686 qpdf_offset_t token_start{0};
675 parser_state_e parser_state; 687 parser_state_e parser_state;
676 - std::vector<std::shared_ptr<JSON>> stack;  
677 - std::vector<parser_state_e> ps_stack; 688 + std::vector<StackFrame> stack;
678 std::string dict_key; 689 std::string dict_key;
679 qpdf_offset_t dict_key_offset; 690 qpdf_offset_t dict_key_offset;
680 }; 691 };
@@ -1137,7 +1148,7 @@ JSONParser::handleToken() @@ -1137,7 +1148,7 @@ JSONParser::handleToken()
1137 1148
1138 std::string s_value; 1149 std::string s_value;
1139 std::shared_ptr<JSON> item; 1150 std::shared_ptr<JSON> item;
1140 - auto tos = stack.empty() ? nullptr : stack.back(); 1151 + auto tos = stack.empty() ? nullptr : stack.back().item;
1141 auto ls = lex_state; 1152 auto ls = lex_state;
1142 lex_state = ls_top; 1153 lex_state = ls_top;
1143 1154
@@ -1186,8 +1197,7 @@ JSONParser::handleToken() @@ -1186,8 +1197,7 @@ JSONParser::handleToken()
1186 "JSON: offset " + std::to_string(offset) + 1197 "JSON: offset " + std::to_string(offset) +
1187 ": unexpected array end delimiter"); 1198 ": unexpected array end delimiter");
1188 } 1199 }
1189 - parser_state = ps_stack.back();  
1190 - ps_stack.pop_back(); 1200 + parser_state = stack.back().state;
1191 tos->setEnd(offset); 1201 tos->setEnd(offset);
1192 if (reactor) { 1202 if (reactor) {
1193 reactor->containerEnd(*tos); 1203 reactor->containerEnd(*tos);
@@ -1205,8 +1215,7 @@ JSONParser::handleToken() @@ -1205,8 +1215,7 @@ JSONParser::handleToken()
1205 "JSON: offset " + std::to_string(offset) + 1215 "JSON: offset " + std::to_string(offset) +
1206 ": unexpected dictionary end delimiter"); 1216 ": unexpected dictionary end delimiter");
1207 } 1217 }
1208 - parser_state = ps_stack.back();  
1209 - ps_stack.pop_back(); 1218 + parser_state = stack.back().state;
1210 tos->setEnd(offset); 1219 tos->setEnd(offset);
1211 if (reactor) { 1220 if (reactor) {
1212 reactor->containerEnd(*tos); 1221 reactor->containerEnd(*tos);
@@ -1293,7 +1302,7 @@ JSONParser::handleToken() @@ -1293,7 +1302,7 @@ JSONParser::handleToken()
1293 1302
1294 case ps_top: 1303 case ps_top:
1295 if (!(item->isDictionary() || item->isArray())) { 1304 if (!(item->isDictionary() || item->isArray())) {
1296 - stack.push_back(item); 1305 + stack.push_back({ps_done, item});
1297 parser_state = ps_done; 1306 parser_state = ps_done;
1298 return; 1307 return;
1299 } 1308 }
@@ -1324,8 +1333,7 @@ JSONParser::handleToken() @@ -1324,8 +1333,7 @@ JSONParser::handleToken()
1324 } 1333 }
1325 1334
1326 if (item->isDictionary() || item->isArray()) { 1335 if (item->isDictionary() || item->isArray()) {
1327 - stack.push_back(item);  
1328 - ps_stack.push_back(parser_state); 1336 + stack.push_back({parser_state, item});
1329 // Calling container start method is postponed until after 1337 // Calling container start method is postponed until after
1330 // adding the containers to their parent containers, if any. 1338 // adding the containers to their parent containers, if any.
1331 // This makes it much easier to keep track of the current 1339 // This makes it much easier to keep track of the current
@@ -1342,7 +1350,7 @@ JSONParser::handleToken() @@ -1342,7 +1350,7 @@ JSONParser::handleToken()
1342 parser_state = ps_array_begin; 1350 parser_state = ps_array_begin;
1343 } 1351 }
1344 1352
1345 - if (ps_stack.size() > 500) { 1353 + if (stack.size() > 500) {
1346 throw std::runtime_error( 1354 throw std::runtime_error(
1347 "JSON: offset " + std::to_string(offset) + 1355 "JSON: offset " + std::to_string(offset) +
1348 ": maximum object depth exceeded"); 1356 ": maximum object depth exceeded");
@@ -1361,7 +1369,7 @@ JSONParser::parse() @@ -1361,7 +1369,7 @@ JSONParser::parse()
1361 QTC::TC("libtests", "JSON parse premature EOF"); 1369 QTC::TC("libtests", "JSON parse premature EOF");
1362 throw std::runtime_error("JSON: premature end of input"); 1370 throw std::runtime_error("JSON: premature end of input");
1363 } 1371 }
1364 - auto const& tos = stack.back(); 1372 + auto const& tos = stack.back().item;
1365 if (reactor && tos.get() && !(tos->isArray() || tos->isDictionary())) { 1373 if (reactor && tos.get() && !(tos->isArray() || tos->isDictionary())) {
1366 reactor->topLevelScalar(); 1374 reactor->topLevelScalar();
1367 } 1375 }