diff --git a/src/util/json/parser.cpp b/src/util/json/parser.cpp index 0917149..b758109 100644 --- a/src/util/json/parser.cpp +++ b/src/util/json/parser.cpp @@ -72,7 +72,7 @@ Value Parser::parse() break; } - if (m_index < m_tokens->size()) { + if (!reachedEnd()) { m_job->printErrorLine(peek(), "multiple root elements"); } @@ -81,6 +81,11 @@ Value Parser::parse() // ----------------------------------------- +bool Parser::reachedEnd() +{ + return m_index >= m_tokens->size(); +} + Token Parser::peek() { return (*m_tokens)[m_index]; @@ -107,6 +112,10 @@ Token Parser::consume() bool Parser::consumeSpecific(Token::Type type) { + if (reachedEnd()) { + return false; + } + if (peek().type != type) { return false; } @@ -320,8 +329,13 @@ Value Parser::getArray() Value array = Value::Type::Array; Token token; for (;;) { - token = peek(); + // EOF + if (reachedEnd()) { + reportError(m_tokens->at(m_index - 1), "expecting closing ']' at end"); + break; + } + token = peek(); if (token.type == Token::Type::Literal) { array.emplace_back(getLiteral()); } @@ -349,6 +363,12 @@ Value Parser::getArray() break; } + // EOF + if (reachedEnd()) { + reportError(token, "expecting closing ']' at end"); + break; + } + // Find , or ] token = consume(); if (token.type == Token::Type::Comma) { @@ -383,6 +403,12 @@ Value Parser::getObject() std::string name; std::map unique; for (;;) { + // EOF + if (reachedEnd()) { + reportError(m_tokens->at(m_index - 1), "expecting closing '}' at end"); + break; + } + token = peek(); if (token.type == Token::Type::BraceClose) { // Trailing comma @@ -414,6 +440,13 @@ Value Parser::getObject() // Add name to hashmap unique.insert({ name, 0 }); + // EOF + if (reachedEnd()) { + reportError(token, "expecting colon, not 'EOF'"); + reportError(token, "expecting closing '}' at end"); + break; + } + // Find : token = consume(); if (token.type != Token::Type::Colon) { @@ -421,6 +454,13 @@ Value Parser::getObject() break; } + // EOF + if (reachedEnd()) { + reportError(token, "expecting value, not 'EOF'"); + reportError(token, "expecting closing '}' at end"); + break; + } + // Add member (name:value pair) to object token = peek(); if (token.type == Token::Type::Literal) { @@ -443,6 +483,12 @@ Value Parser::getObject() break; } + // EOF + if (reachedEnd()) { + reportError(token, "expecting closing '}' at end"); + break; + } + // Find , or } token = consume(); if (token.type == Token::Type::Comma) { diff --git a/src/util/json/parser.h b/src/util/json/parser.h index d2abcb0..f286ae4 100644 --- a/src/util/json/parser.h +++ b/src/util/json/parser.h @@ -25,6 +25,8 @@ public: Value parse(); private: + bool reachedEnd(); + Token peek(); bool seekForward(Token::Type type);