mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-05 16:12:13 +00:00
In JSONParser combine stacks
This commit is contained in:
parent
6748bd33f7
commit
126dd31cad
@ -661,6 +661,18 @@ namespace
|
|||||||
ls_comma,
|
ls_comma,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct StackFrame
|
||||||
|
{
|
||||||
|
StackFrame(parser_state_e state, std::shared_ptr<JSON>& item) :
|
||||||
|
state(state),
|
||||||
|
item(item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
parser_state_e state;
|
||||||
|
std::shared_ptr<JSON> item;
|
||||||
|
};
|
||||||
|
|
||||||
InputSource& is;
|
InputSource& is;
|
||||||
JSON::Reactor* reactor;
|
JSON::Reactor* reactor;
|
||||||
lex_state_e lex_state;
|
lex_state_e lex_state;
|
||||||
@ -673,8 +685,7 @@ namespace
|
|||||||
std::string token;
|
std::string token;
|
||||||
qpdf_offset_t token_start{0};
|
qpdf_offset_t token_start{0};
|
||||||
parser_state_e parser_state;
|
parser_state_e parser_state;
|
||||||
std::vector<std::shared_ptr<JSON>> stack;
|
std::vector<StackFrame> stack;
|
||||||
std::vector<parser_state_e> ps_stack;
|
|
||||||
std::string dict_key;
|
std::string dict_key;
|
||||||
qpdf_offset_t dict_key_offset;
|
qpdf_offset_t dict_key_offset;
|
||||||
};
|
};
|
||||||
@ -1137,7 +1148,7 @@ JSONParser::handleToken()
|
|||||||
|
|
||||||
std::string s_value;
|
std::string s_value;
|
||||||
std::shared_ptr<JSON> item;
|
std::shared_ptr<JSON> item;
|
||||||
auto tos = stack.empty() ? nullptr : stack.back();
|
auto tos = stack.empty() ? nullptr : stack.back().item;
|
||||||
auto ls = lex_state;
|
auto ls = lex_state;
|
||||||
lex_state = ls_top;
|
lex_state = ls_top;
|
||||||
|
|
||||||
@ -1186,8 +1197,7 @@ JSONParser::handleToken()
|
|||||||
"JSON: offset " + std::to_string(offset) +
|
"JSON: offset " + std::to_string(offset) +
|
||||||
": unexpected array end delimiter");
|
": unexpected array end delimiter");
|
||||||
}
|
}
|
||||||
parser_state = ps_stack.back();
|
parser_state = stack.back().state;
|
||||||
ps_stack.pop_back();
|
|
||||||
tos->setEnd(offset);
|
tos->setEnd(offset);
|
||||||
if (reactor) {
|
if (reactor) {
|
||||||
reactor->containerEnd(*tos);
|
reactor->containerEnd(*tos);
|
||||||
@ -1205,8 +1215,7 @@ JSONParser::handleToken()
|
|||||||
"JSON: offset " + std::to_string(offset) +
|
"JSON: offset " + std::to_string(offset) +
|
||||||
": unexpected dictionary end delimiter");
|
": unexpected dictionary end delimiter");
|
||||||
}
|
}
|
||||||
parser_state = ps_stack.back();
|
parser_state = stack.back().state;
|
||||||
ps_stack.pop_back();
|
|
||||||
tos->setEnd(offset);
|
tos->setEnd(offset);
|
||||||
if (reactor) {
|
if (reactor) {
|
||||||
reactor->containerEnd(*tos);
|
reactor->containerEnd(*tos);
|
||||||
@ -1293,7 +1302,7 @@ JSONParser::handleToken()
|
|||||||
|
|
||||||
case ps_top:
|
case ps_top:
|
||||||
if (!(item->isDictionary() || item->isArray())) {
|
if (!(item->isDictionary() || item->isArray())) {
|
||||||
stack.push_back(item);
|
stack.push_back({ps_done, item});
|
||||||
parser_state = ps_done;
|
parser_state = ps_done;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1324,8 +1333,7 @@ JSONParser::handleToken()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (item->isDictionary() || item->isArray()) {
|
if (item->isDictionary() || item->isArray()) {
|
||||||
stack.push_back(item);
|
stack.push_back({parser_state, item});
|
||||||
ps_stack.push_back(parser_state);
|
|
||||||
// Calling container start method is postponed until after
|
// Calling container start method is postponed until after
|
||||||
// adding the containers to their parent containers, if any.
|
// adding the containers to their parent containers, if any.
|
||||||
// This makes it much easier to keep track of the current
|
// This makes it much easier to keep track of the current
|
||||||
@ -1342,7 +1350,7 @@ JSONParser::handleToken()
|
|||||||
parser_state = ps_array_begin;
|
parser_state = ps_array_begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps_stack.size() > 500) {
|
if (stack.size() > 500) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"JSON: offset " + std::to_string(offset) +
|
"JSON: offset " + std::to_string(offset) +
|
||||||
": maximum object depth exceeded");
|
": maximum object depth exceeded");
|
||||||
@ -1361,7 +1369,7 @@ JSONParser::parse()
|
|||||||
QTC::TC("libtests", "JSON parse premature EOF");
|
QTC::TC("libtests", "JSON parse premature EOF");
|
||||||
throw std::runtime_error("JSON: premature end of input");
|
throw std::runtime_error("JSON: premature end of input");
|
||||||
}
|
}
|
||||||
auto const& tos = stack.back();
|
auto const& tos = stack.back().item;
|
||||||
if (reactor && tos.get() && !(tos->isArray() || tos->isDictionary())) {
|
if (reactor && tos.get() && !(tos->isArray() || tos->isDictionary())) {
|
||||||
reactor->topLevelScalar();
|
reactor->topLevelScalar();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user