Skip to content

Commit 8800033

Browse files
author
Blake Gross
committed
Changed json parse behavior
1 parent 96ee9e1 commit 8800033

File tree

1 file changed

+79
-51
lines changed

1 file changed

+79
-51
lines changed

Release/src/json/json_parsing.cpp

Lines changed: 79 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,14 @@ class JSON_Parser
140140

141141
JsonParseStatus GetNextToken(Token &);
142142

143-
web::json::value ParseValue(typename JSON_Parser<CharType>::Token &first)
143+
web::json::value ParseValue(typename JSON_Parser<CharType>::Token &first, JsonParseStatus& parseStatus)
144144
{
145145
#ifndef _MS_WINDOWS
146146
utility::details::scoped_c_thread_locale locale;
147147
#endif
148148

149-
auto _value = _ParseValue(first);
149+
auto _value = _ParseValue(first, parseStatus);
150+
if (!parseStatus.didSucceed) return web::json::value();
150151
#ifdef ENABLE_JSON_VALUE_VISUALIZER
151152
auto type = _value->type();
152153
#endif
@@ -172,9 +173,9 @@ class JSON_Parser
172173
bool CompleteKeywordTrue(Token &token);
173174
bool CompleteKeywordFalse(Token &token);
174175
bool CompleteKeywordNull(Token &token);
175-
std::unique_ptr<web::json::details::_Value> _ParseValue(typename JSON_Parser<CharType>::Token &first);
176-
std::unique_ptr<web::json::details::_Object> _ParseObject(typename JSON_Parser<CharType>::Token &tkn);
177-
std::unique_ptr<web::json::details::_Array> _ParseArray(typename JSON_Parser<CharType>::Token &tkn);
176+
std::unique_ptr<web::json::details::_Value> _ParseValue(typename JSON_Parser<CharType>::Token &first, JsonParseStatus& parseStatus);
177+
std::unique_ptr<web::json::details::_Object> _ParseObject(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus);
178+
std::unique_ptr<web::json::details::_Array> _ParseArray(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus);
178179

179180
JSON_Parser& operator=(const JSON_Parser&);
180181

@@ -1014,12 +1015,12 @@ JsonParseStatus JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharTyp
10141015
}
10151016

10161017
template <typename CharType>
1017-
std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject(typename JSON_Parser<CharType>::Token &tkn)
1018+
std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus)
10181019
{
1019-
JsonParseStatus parseAttempt = GetNextToken(tkn);
1020-
if (!parseAttempt.didSucceed)
1020+
parseStatus = GetNextToken(tkn);
1021+
if (!parseStatus.didSucceed)
10211022
{
1022-
CreateError(tkn, parseAttempt.errorMsg);
1023+
return nullptr;
10231024
}
10241025

10251026
auto obj = utility::details::make_unique<web::json::details::_Object>(g_keep_json_object_unsorted);
@@ -1042,18 +1043,20 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
10421043
goto error;
10431044
}
10441045

1045-
parseAttempt = GetNextToken(tkn);
1046-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1046+
parseStatus = GetNextToken(tkn);
1047+
if (!parseStatus.didSucceed) goto getNextTokenError;
10471048

10481049
// State 2: Looking for a colon.
10491050

10501051
if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_Colon ) goto done;
10511052

1052-
parseAttempt = GetNextToken(tkn);
1053-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1053+
parseStatus = GetNextToken(tkn);
1054+
if (!parseStatus.didSucceed) goto getNextTokenError;
10541055
// State 3: Looking for an expression.
10551056
#ifdef ENABLE_JSON_VALUE_VISUALIZER
1056-
auto fieldValue = _ParseValue(tkn);
1057+
auto fieldValue = _ParseValue(tkn, parseStatus);
1058+
1059+
if (!parseStatus.didSucceed) goto getNextTokenError;
10571060
auto type = fieldValue->type();
10581061

10591062
elems.emplace_back(utility::conversions::to_string_t(std::move(fieldName)), json::value(std::move(fieldValue), type));
@@ -1066,8 +1069,8 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
10661069
switch (tkn.kind)
10671070
{
10681071
case JSON_Parser<CharType>::Token::TKN_Comma:
1069-
parseAttempt = GetNextToken(tkn);
1070-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1072+
parseStatus = GetNextToken(tkn);
1073+
if (!parseStatus.didSucceed) goto getNextTokenError;
10711074
break;
10721075
case JSON_Parser<CharType>::Token::TKN_CloseBrace:
10731076
goto done;
@@ -1080,7 +1083,7 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
10801083
done:
10811084

10821085
GetNextToken(tkn);
1083-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1086+
if (!parseStatus.didSucceed) goto getNextTokenError;
10841087

10851088
if (!g_keep_json_object_unsorted) {
10861089
::std::sort(elems.begin(), elems.end(), json::object::compare_pairs);
@@ -1089,15 +1092,15 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
10891092
return obj;
10901093

10911094
error:
1092-
1093-
CreateError(tkn, _XPLATSTR("Malformed object literal"));
1095+
parseStatus.errorMsg = _XPLATSTR("Malformed object literal");
1096+
return nullptr;
10941097

10951098
getNextTokenError:
1096-
CreateError(tkn, parseAttempt.errorMsg);
1099+
return nullptr;
10971100
}
10981101

10991102
template <typename CharType>
1100-
std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(typename JSON_Parser<CharType>::Token &tkn)
1103+
std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus)
11011104
{
11021105
JsonParseStatus parseAttempt = GetNextToken(tkn);
11031106
if (!parseAttempt.didSucceed)
@@ -1112,7 +1115,10 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
11121115
while ( true )
11131116
{
11141117
// State 1: Looking for an expression.
1115-
result->m_array.m_elements.emplace_back(ParseValue(tkn));
1118+
auto value = ParseValue(tkn, parseStatus);
1119+
if (!parseAttempt.didSucceed) goto getNextTokenError;
1120+
1121+
result->m_array.m_elements.emplace_back(value);
11161122

11171123
// State 4: Looking for a comma or a closing bracket
11181124
switch (tkn.kind)
@@ -1142,27 +1148,25 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
11421148
}
11431149

11441150
template <typename CharType>
1145-
std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(typename JSON_Parser<CharType>::Token &tkn)
1151+
std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus)
11461152
{
1147-
JsonParseStatus parseAttempt;
11481153
switch (tkn.kind)
11491154
{
11501155
case JSON_Parser<CharType>::Token::TKN_OpenBrace:
11511156
{
1152-
return _ParseObject(tkn);
1157+
return _ParseObject(tkn, parseStatus);
11531158
}
11541159
case JSON_Parser<CharType>::Token::TKN_OpenBracket:
11551160
{
1156-
return _ParseArray(tkn);
1161+
return _ParseArray(tkn, parseStatus);
11571162
}
11581163
case JSON_Parser<CharType>::Token::TKN_StringLiteral:
11591164
{
11601165
auto value = utility::details::make_unique<web::json::details::_String>(std::move(tkn.string_val), tkn.has_unescape_symbol);
1161-
parseAttempt = GetNextToken(tkn);
1162-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1166+
parseStatus = GetNextToken(tkn);
1167+
if (!parseStatus.didSucceed) goto getNextTokenError;
11631168
return std::move(value);
11641169
}
1165-
11661170
case JSON_Parser<CharType>::Token::TKN_IntegerLiteral:
11671171
{
11681172
std::unique_ptr<web::json::details::_Number> value;
@@ -1171,42 +1175,40 @@ std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(t
11711175
else
11721176
value = utility::details::make_unique<web::json::details::_Number>(tkn.uint64_val);
11731177

1174-
parseAttempt = GetNextToken(tkn);
1175-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1178+
parseStatus = GetNextToken(tkn);
1179+
if (!parseStatus.didSucceed) goto getNextTokenError;
11761180
return std::move(value);
11771181
}
1178-
11791182
case JSON_Parser<CharType>::Token::TKN_NumberLiteral:
11801183
{
11811184
auto value = utility::details::make_unique<web::json::details::_Number>(tkn.double_val);
1182-
parseAttempt = GetNextToken(tkn);
1183-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1185+
parseStatus = GetNextToken(tkn);
1186+
if (!parseStatus.didSucceed) goto getNextTokenError;
11841187
return std::move(value);
11851188
}
11861189
case JSON_Parser<CharType>::Token::TKN_BooleanLiteral:
11871190
{
11881191
auto value = utility::details::make_unique<web::json::details::_Boolean>(tkn.boolean_val);
1189-
parseAttempt = GetNextToken(tkn);
1190-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1192+
parseStatus = GetNextToken(tkn);
1193+
if (!parseStatus.didSucceed) goto getNextTokenError;
11911194
return std::move(value);
11921195
}
11931196
case JSON_Parser<CharType>::Token::TKN_NullLiteral:
11941197
{
1195-
parseAttempt = GetNextToken(tkn);
1196-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1198+
parseStatus = GetNextToken(tkn);
1199+
if (!parseStatus.didSucceed) goto getNextTokenError;
11971200
return utility::details::make_unique<web::json::details::_Null>();
11981201
}
1199-
12001202
default:
12011203
{
1202-
parseAttempt.didSucceed = false;
1203-
parseAttempt.errorMsg = _XPLATSTR("Unexpected token");
1204+
parseStatus.didSucceed = false;
1205+
parseStatus.errorMsg = _XPLATSTR("Unexpected token");
12041206
goto getNextTokenError;
12051207
}
12061208
}
12071209

12081210
getNextTokenError:
1209-
CreateError(tkn, parseAttempt.errorMsg);
1211+
return nullptr;
12101212
}
12111213

12121214
}}}
@@ -1216,9 +1218,20 @@ static web::json::value _parse_stream(utility::istream_t &stream)
12161218
web::json::details::JSON_StreamParser<utility::char_t> parser(stream);
12171219

12181220
web::json::details::JSON_Parser<utility::char_t>::Token tkn;
1219-
parser.GetNextToken(tkn);
1221+
auto parseStatus = parser.GetNextToken(tkn);
1222+
1223+
if (!parseStatus.didSucceed)
1224+
{
1225+
web::json::details::CreateError(tkn, parseStatus.errorMsg);
1226+
}
1227+
1228+
auto value = parser.ParseValue(tkn, parseStatus);
1229+
1230+
if (!parseStatus.didSucceed)
1231+
{
1232+
web::json::details::CreateError(tkn, parseStatus.errorMsg);
1233+
}
12201234

1221-
auto value = parser.ParseValue(tkn);
12221235
if ( tkn.kind != web::json::details::JSON_Parser<utility::char_t>::Token::TKN_EOF )
12231236
{
12241237
web::json::details::CreateError(tkn, _XPLATSTR("Left-over characters in stream after parsing a JSON value"));
@@ -1232,9 +1245,19 @@ static web::json::value _parse_narrow_stream(std::istream &stream)
12321245
web::json::details::JSON_StreamParser<char> parser(stream);
12331246

12341247
web::json::details::JSON_StreamParser<char>::Token tkn;
1235-
parser.GetNextToken(tkn);
1248+
auto parseStatus = parser.GetNextToken(tkn);
12361249

1237-
auto value = parser.ParseValue(tkn);
1250+
if (!parseStatus.didSucceed)
1251+
{
1252+
web::json::details::CreateError(tkn, parseStatus.errorMsg);
1253+
}
1254+
1255+
auto value = parser.ParseValue(tkn, parseStatus);
1256+
1257+
if (!parseStatus.didSucceed)
1258+
{
1259+
web::json::details::CreateError(tkn, parseStatus.errorMsg);
1260+
}
12381261

12391262
if ( tkn.kind != web::json::details::JSON_Parser<char>::Token::TKN_EOF )
12401263
{
@@ -1249,14 +1272,19 @@ web::json::value web::json::value::parse(const utility::string_t& str)
12491272
web::json::details::JSON_StringParser<utility::char_t> parser(str);
12501273

12511274
web::json::details::JSON_Parser<utility::char_t>::Token tkn;
1252-
auto parseAttempt = parser.GetNextToken(tkn);
1275+
auto parseStatus = parser.GetNextToken(tkn);
12531276

1254-
if (!parseAttempt.didSucceed)
1277+
if (!parseStatus.didSucceed)
12551278
{
1256-
web::json::details::CreateError(tkn, parseAttempt.errorMsg);
1279+
web::json::details::CreateError(tkn, parseStatus.errorMsg);
12571280
}
12581281

1259-
auto value = parser.ParseValue(tkn);
1282+
auto value = parser.ParseValue(tkn, parseStatus);
1283+
1284+
if (!parseStatus.didSucceed)
1285+
{
1286+
web::json::details::CreateError(tkn, parseStatus.errorMsg);
1287+
}
12601288

12611289
if (tkn.kind != web::json::details::JSON_Parser<utility::char_t>::Token::TKN_EOF)
12621290
{
@@ -1275,7 +1303,7 @@ web::json::value web::json::value::parse(const utility::string_t& str, std::erro
12751303

12761304
if (parseAttempt.didSucceed)
12771305
{
1278-
returnObject = parser.ParseValue(tkn);
1306+
returnObject = parser.ParseValue(tkn, parseAttempt);
12791307
}
12801308
else
12811309
{

0 commit comments

Comments
 (0)