Skip to content

Commit d4f65c0

Browse files
author
Blake Gross
committed
Made exception free json parsing complete and added unit tests to verify exception free code
1 parent 8800033 commit d4f65c0

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

Release/src/json/json_parsing.cpp

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,7 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
10921092
return obj;
10931093

10941094
error:
1095+
parseStatus.didSucceed = false;
10951096
parseStatus.errorMsg = _XPLATSTR("Malformed object literal");
10961097
return nullptr;
10971098

@@ -1102,10 +1103,10 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
11021103
template <typename CharType>
11031104
std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus)
11041105
{
1105-
JsonParseStatus parseAttempt = GetNextToken(tkn);
1106-
if (!parseAttempt.didSucceed)
1106+
parseStatus = GetNextToken(tkn);
1107+
if (!parseStatus.didSucceed)
11071108
{
1108-
CreateError(tkn, parseAttempt.errorMsg);
1109+
return nullptr;
11091110
}
11101111

11111112
auto result = utility::details::make_unique<web::json::details::_Array>();
@@ -1116,35 +1117,38 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
11161117
{
11171118
// State 1: Looking for an expression.
11181119
auto value = ParseValue(tkn, parseStatus);
1119-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1120+
if (!parseStatus.didSucceed) goto getNextTokenError;
11201121

11211122
result->m_array.m_elements.emplace_back(value);
11221123

11231124
// State 4: Looking for a comma or a closing bracket
11241125
switch (tkn.kind)
11251126
{
11261127
case JSON_Parser<CharType>::Token::TKN_Comma:
1127-
parseAttempt = GetNextToken(tkn);
1128-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1128+
parseStatus = GetNextToken(tkn);
1129+
if (!parseStatus.didSucceed) goto getNextTokenError;
11291130
break;
11301131
case JSON_Parser<CharType>::Token::TKN_CloseBracket:
1131-
parseAttempt = GetNextToken(tkn);
1132-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1132+
parseStatus = GetNextToken(tkn);
1133+
if (!parseStatus.didSucceed) goto getNextTokenError;
11331134

11341135
return result;
11351136
default:
1136-
CreateError(tkn, _XPLATSTR("Malformed array literal"));
1137+
parseStatus.didSucceed = false;
1138+
parseStatus.errorMsg = _XPLATSTR("Malformed array literal");
1139+
1140+
return nullptr;
11371141
}
11381142
}
11391143
}
11401144

1141-
parseAttempt = GetNextToken(tkn);
1142-
if (!parseAttempt.didSucceed) goto getNextTokenError;
1145+
parseStatus = GetNextToken(tkn);
1146+
if (!parseStatus.didSucceed) goto getNextTokenError;
11431147

11441148
return result;
11451149

11461150
getNextTokenError:
1147-
CreateError(tkn, parseAttempt.errorMsg);
1151+
return nullptr;
11481152
}
11491153

11501154
template <typename CharType>
@@ -1298,18 +1302,25 @@ web::json::value web::json::value::parse(const utility::string_t& str, std::erro
12981302
web::json::details::JSON_StringParser<utility::char_t> parser(str);
12991303

13001304
web::json::details::JSON_Parser<utility::char_t>::Token tkn;
1301-
auto parseAttempt = parser.GetNextToken(tkn);
1305+
auto parseStatus = parser.GetNextToken(tkn);
13021306
web::json::value returnObject;
13031307

1304-
if (parseAttempt.didSucceed)
1308+
if (parseStatus.didSucceed)
13051309
{
1306-
returnObject = parser.ParseValue(tkn, parseAttempt);
1310+
returnObject = parser.ParseValue(tkn, parseStatus);
1311+
1312+
if (!parseStatus.didSucceed || tkn.kind != web::json::details::JSON_Parser<utility::char_t>::Token::TKN_EOF)
1313+
{
1314+
returnObject = web::json::value::null();
1315+
error = std::make_error_code(std::errc::protocol_error);
1316+
}
13071317
}
13081318
else
13091319
{
13101320
returnObject = web::json::value::null();
13111321
error = std::make_error_code(std::errc::protocol_error);
13121322
}
1323+
13131324
return returnObject;
13141325
}
13151326

0 commit comments

Comments
 (0)