@@ -70,6 +70,18 @@ void CreateError(const Token &tk, const utility::string_t &message)
70
70
throw web::json::json_exception (os.str ().c_str ());
71
71
}
72
72
73
+ struct JsonParseStatus
74
+ {
75
+ bool didSucceed;
76
+ string_t errorMsg;
77
+
78
+ JsonParseStatus () :
79
+ didSucceed (true ),
80
+ errorMsg (L" " )
81
+ {
82
+ }
83
+ };
84
+
73
85
template <typename CharType>
74
86
class JSON_Parser
75
87
{
@@ -126,7 +138,7 @@ class JSON_Parser
126
138
bool signed_number;
127
139
};
128
140
129
- void GetNextToken (Token &);
141
+ JsonParseStatus GetNextToken (Token &);
130
142
131
143
web::json::value ParseValue (typename JSON_Parser<CharType>::Token &first)
132
144
{
@@ -888,14 +900,16 @@ bool JSON_StringParser<CharType>::finish_parsing_string_with_unescape_char(typen
888
900
}
889
901
890
902
template <typename CharType>
891
- void JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharType>::Token& result)
903
+ JsonParseStatus JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharType>::Token& result)
892
904
{
905
+ JsonParseStatus parseSucceed;
906
+
893
907
try_again:
894
908
CharType ch = EatWhitespace ();
895
909
896
910
CreateToken (result, Token::TKN_EOF);
897
911
898
- if (ch == this ->m_eof ) return ;
912
+ if (ch == this ->m_eof ) return parseSucceed ;
899
913
900
914
switch (ch)
901
915
{
@@ -904,7 +918,8 @@ void JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharType>::Token&
904
918
{
905
919
if (++m_currentParsingDepth > JSON_Parser<CharType>::maxParsingDepth)
906
920
{
907
- CreateError (result, _XPLATSTR (" Nesting too deep!" ));
921
+ parseSucceed.didSucceed = false ;
922
+ parseSucceed.errorMsg = _XPLATSTR (" Nesting too deep!" );
908
923
break ;
909
924
}
910
925
@@ -917,7 +932,8 @@ void JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharType>::Token&
917
932
{
918
933
if ((signed int )(--m_currentParsingDepth) < 0 )
919
934
{
920
- CreateError (result, _XPLATSTR (" Mismatched braces!" ));
935
+ parseSucceed.didSucceed = false ;
936
+ parseSucceed.errorMsg = _XPLATSTR (" Mismatched braces!" );
921
937
break ;
922
938
}
923
939
@@ -934,20 +950,41 @@ void JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharType>::Token&
934
950
break ;
935
951
936
952
case ' t' :
937
- if (!CompleteKeywordTrue (result)) CreateError (result, _XPLATSTR (" Malformed literal" ));
953
+ if (!CompleteKeywordTrue (result))
954
+ {
955
+ parseSucceed.didSucceed = false ;
956
+ parseSucceed.errorMsg = _XPLATSTR (" Malformed literal" );
957
+ }
938
958
break ;
939
959
case ' f' :
940
- if (!CompleteKeywordFalse (result)) CreateError (result, _XPLATSTR (" Malformed literal" ));
960
+ if (!CompleteKeywordFalse (result))
961
+ {
962
+ parseSucceed.didSucceed = false ;
963
+ parseSucceed.errorMsg = _XPLATSTR (" Malformed literal" );
964
+ }
941
965
break ;
942
966
case ' n' :
943
- if (!CompleteKeywordNull (result)) CreateError (result, _XPLATSTR (" Malformed literal" ));
967
+ if (!CompleteKeywordNull (result))
968
+ {
969
+ parseSucceed.didSucceed = false ;
970
+ parseSucceed.errorMsg = _XPLATSTR (" Malformed literal" );
971
+ }
944
972
break ;
945
973
case ' /' :
946
- if ( !CompleteComment (result) ) CreateError (result, _XPLATSTR (" Malformed comment" ));
974
+ if (!CompleteComment (result))
975
+ {
976
+ parseSucceed.didSucceed = false ;
977
+ parseSucceed.errorMsg = _XPLATSTR (" Malformed comment" );
978
+ break ;
979
+ }
947
980
// For now, we're ignoring comments.
948
981
goto try_again;
949
982
case ' "' :
950
- if ( !CompleteStringLiteral (result) ) CreateError (result, _XPLATSTR (" Malformed string literal" ));
983
+ if (!CompleteStringLiteral (result))
984
+ {
985
+ parseSucceed.didSucceed = false ;
986
+ parseSucceed.errorMsg = _XPLATSTR (" Malformed string literal" );
987
+ }
951
988
break ;
952
989
953
990
case ' -' :
@@ -961,30 +998,41 @@ void JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharType>::Token&
961
998
case ' 7' :
962
999
case ' 8' :
963
1000
case ' 9' :
964
- if ( !CompleteNumberLiteral (ch, result) ) CreateError (result, _XPLATSTR (" Malformed numeric literal" ));
1001
+ if (!CompleteNumberLiteral (ch, result))
1002
+ {
1003
+ parseSucceed.didSucceed = false ;
1004
+ parseSucceed.errorMsg = _XPLATSTR (" Malformed numeric literal" );
1005
+ }
965
1006
break ;
966
1007
default :
967
- CreateError (result, _XPLATSTR (" Malformed token" ));
1008
+ parseSucceed.didSucceed = false ;
1009
+ parseSucceed.errorMsg = _XPLATSTR (" Malformed token" );
968
1010
break ;
969
1011
}
1012
+
1013
+ return parseSucceed;
970
1014
}
971
1015
972
1016
template <typename CharType>
973
1017
std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject(typename JSON_Parser<CharType>::Token &tkn)
974
1018
{
975
- GetNextToken (tkn);
1019
+ JsonParseStatus parseAttempt = GetNextToken (tkn);
1020
+ if (!parseAttempt.didSucceed )
1021
+ {
1022
+ CreateError (tkn, parseAttempt.errorMsg );
1023
+ }
976
1024
977
1025
auto obj = utility::details::make_unique<web::json::details::_Object>(g_keep_json_object_unsorted);
978
1026
auto & elems = obj->m_object .m_elements ;
979
1027
980
- if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBrace )
1028
+ if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBrace )
981
1029
{
982
1030
while ( true )
983
1031
{
984
1032
// State 1: New field or end of object, looking for field name or closing brace
985
1033
986
1034
std::basic_string<CharType> fieldName;
987
-
1035
+
988
1036
switch ( tkn.kind )
989
1037
{
990
1038
case JSON_Parser<CharType>::Token::TKN_StringLiteral:
@@ -994,14 +1042,15 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
994
1042
goto error;
995
1043
}
996
1044
997
- GetNextToken (tkn);
1045
+ parseAttempt = GetNextToken (tkn);
1046
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
998
1047
999
1048
// State 2: Looking for a colon.
1000
1049
1001
1050
if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_Colon ) goto done;
1002
1051
1003
- GetNextToken (tkn);
1004
-
1052
+ parseAttempt = GetNextToken (tkn);
1053
+ if (!parseAttempt. didSucceed ) goto getNextTokenError;
1005
1054
// State 3: Looking for an expression.
1006
1055
#ifdef ENABLE_JSON_VALUE_VISUALIZER
1007
1056
auto fieldValue = _ParseValue (tkn);
@@ -1017,7 +1066,8 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
1017
1066
switch (tkn.kind )
1018
1067
{
1019
1068
case JSON_Parser<CharType>::Token::TKN_Comma:
1020
- GetNextToken (tkn);
1069
+ parseAttempt = GetNextToken (tkn);
1070
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1021
1071
break ;
1022
1072
case JSON_Parser<CharType>::Token::TKN_CloseBrace:
1023
1073
goto done;
@@ -1030,6 +1080,7 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
1030
1080
done:
1031
1081
1032
1082
GetNextToken (tkn);
1083
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1033
1084
1034
1085
if (!g_keep_json_object_unsorted) {
1035
1086
::std::sort (elems.begin(), elems.end(), json::object::compare_pairs);
@@ -1040,16 +1091,23 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
1040
1091
error:
1041
1092
1042
1093
CreateError (tkn, _XPLATSTR (" Malformed object literal" ));
1094
+
1095
+ getNextTokenError:
1096
+ CreateError (tkn, parseAttempt.errorMsg );
1043
1097
}
1044
1098
1045
1099
template <typename CharType>
1046
1100
std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(typename JSON_Parser<CharType>::Token &tkn)
1047
1101
{
1048
- GetNextToken (tkn);
1102
+ JsonParseStatus parseAttempt = GetNextToken (tkn);
1103
+ if (!parseAttempt.didSucceed )
1104
+ {
1105
+ CreateError (tkn, parseAttempt.errorMsg );
1106
+ }
1049
1107
1050
1108
auto result = utility::details::make_unique<web::json::details::_Array>();
1051
1109
1052
- if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBracket )
1110
+ if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBracket )
1053
1111
{
1054
1112
while ( true )
1055
1113
{
@@ -1060,10 +1118,12 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
1060
1118
switch (tkn.kind )
1061
1119
{
1062
1120
case JSON_Parser<CharType>::Token::TKN_Comma:
1063
- GetNextToken (tkn);
1121
+ parseAttempt = GetNextToken (tkn);
1122
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1064
1123
break ;
1065
1124
case JSON_Parser<CharType>::Token::TKN_CloseBracket:
1066
- GetNextToken (tkn);
1125
+ parseAttempt = GetNextToken (tkn);
1126
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1067
1127
1068
1128
return result;
1069
1129
default :
@@ -1072,26 +1132,34 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
1072
1132
}
1073
1133
}
1074
1134
1075
- GetNextToken (tkn);
1135
+ parseAttempt = GetNextToken (tkn);
1136
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1076
1137
1077
1138
return result;
1139
+
1140
+ getNextTokenError:
1141
+ CreateError (tkn, parseAttempt.errorMsg );
1078
1142
}
1079
1143
1080
1144
template <typename CharType>
1081
1145
std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(typename JSON_Parser<CharType>::Token &tkn)
1082
1146
{
1147
+ JsonParseStatus parseAttempt;
1083
1148
switch (tkn.kind )
1084
1149
{
1085
1150
case JSON_Parser<CharType>::Token::TKN_OpenBrace:
1086
- return _ParseObject (tkn);
1087
-
1151
+ {
1152
+ return _ParseObject (tkn);
1153
+ }
1088
1154
case JSON_Parser<CharType>::Token::TKN_OpenBracket:
1089
- return _ParseArray (tkn);
1090
-
1155
+ {
1156
+ return _ParseArray (tkn);
1157
+ }
1091
1158
case JSON_Parser<CharType>::Token::TKN_StringLiteral:
1092
1159
{
1093
1160
auto value = utility::details::make_unique<web::json::details::_String>(std::move (tkn.string_val ), tkn.has_unescape_symbol );
1094
- GetNextToken (tkn);
1161
+ parseAttempt = GetNextToken (tkn);
1162
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1095
1163
return std::move (value);
1096
1164
}
1097
1165
@@ -1103,31 +1171,40 @@ std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(t
1103
1171
else
1104
1172
value = utility::details::make_unique<web::json::details::_Number>(tkn.uint64_val );
1105
1173
1106
- GetNextToken (tkn);
1174
+ parseAttempt = GetNextToken (tkn);
1175
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1107
1176
return std::move (value);
1108
1177
}
1109
1178
1110
- case JSON_Parser<CharType>::Token::TKN_NumberLiteral:
1179
+ case JSON_Parser<CharType>::Token::TKN_NumberLiteral:
1111
1180
{
1112
1181
auto value = utility::details::make_unique<web::json::details::_Number>(tkn.double_val );
1113
- GetNextToken (tkn);
1182
+ parseAttempt = GetNextToken (tkn);
1183
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1114
1184
return std::move (value);
1115
1185
}
1116
1186
case JSON_Parser<CharType>::Token::TKN_BooleanLiteral:
1117
1187
{
1118
1188
auto value = utility::details::make_unique<web::json::details::_Boolean>(tkn.boolean_val );
1119
- GetNextToken (tkn);
1189
+ parseAttempt = GetNextToken (tkn);
1190
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1120
1191
return std::move (value);
1121
1192
}
1122
1193
case JSON_Parser<CharType>::Token::TKN_NullLiteral:
1123
1194
{
1124
- GetNextToken (tkn);
1195
+ parseAttempt = GetNextToken (tkn);
1196
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1125
1197
return utility::details::make_unique<web::json::details::_Null>();
1126
1198
}
1127
1199
1128
1200
default :
1129
- CreateError (tkn, _XPLATSTR (" Unexpected token" ));
1201
+ {
1202
+ return utility::details::make_unique<web::json::details::_Null>();
1203
+ }
1130
1204
}
1205
+
1206
+ getNextTokenError:
1207
+ CreateError (tkn, parseAttempt.errorMsg );
1131
1208
}
1132
1209
1133
1210
}}}
@@ -1170,7 +1247,12 @@ web::json::value web::json::value::parse(const utility::string_t& str)
1170
1247
web::json::details::JSON_StringParser<utility::char_t > parser (str);
1171
1248
1172
1249
web::json::details::JSON_Parser<utility::char_t >::Token tkn;
1173
- parser.GetNextToken (tkn);
1250
+ auto parseAttempt = parser.GetNextToken (tkn);
1251
+
1252
+ if (!parseAttempt.didSucceed )
1253
+ {
1254
+ web::json::details::CreateError (tkn, parseAttempt.errorMsg );
1255
+ }
1174
1256
1175
1257
auto value = parser.ParseValue (tkn);
1176
1258
@@ -1181,6 +1263,26 @@ web::json::value web::json::value::parse(const utility::string_t& str)
1181
1263
return value;
1182
1264
}
1183
1265
1266
+ web::json::value web::json::value::parse (const utility::string_t & str, std::error_code& error)
1267
+ {
1268
+ web::json::details::JSON_StringParser<utility::char_t > parser (str);
1269
+
1270
+ web::json::details::JSON_Parser<utility::char_t >::Token tkn;
1271
+ auto parseAttempt = parser.GetNextToken (tkn);
1272
+ web::json::value returnObject;
1273
+
1274
+ if (parseAttempt.didSucceed )
1275
+ {
1276
+ returnObject = parser.ParseValue (tkn);
1277
+ }
1278
+ else
1279
+ {
1280
+ returnObject = web::json::value::null ();
1281
+ error = std::make_error_code (std::errc::protocol_error);
1282
+ }
1283
+ return returnObject;
1284
+ }
1285
+
1184
1286
web::json::value web::json::value::parse (utility::istream_t &stream)
1185
1287
{
1186
1288
return _parse_stream (stream);
0 commit comments