Skip to content

Commit 9f64a7b

Browse files
authored
Merge pull request #326 from neumannt/json-crash
defend against excessive recursion in json::load
2 parents 2807953 + 9689688 commit 9f64a7b

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

include/crow/json.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,9 @@ namespace crow
820820

821821
inline rvalue load_nocopy_internal(char* data, size_t size)
822822
{
823+
// Defend against excessive recursion
824+
static constexpr unsigned max_depth = 10000;
825+
823826
//static const char* escaped = "\"\\/\b\f\n\r\t";
824827
struct Parser
825828
{
@@ -902,10 +905,10 @@ namespace crow
902905
return {};
903906
}
904907

905-
rvalue decode_list()
908+
rvalue decode_list(unsigned depth)
906909
{
907910
rvalue ret(type::List);
908-
if (crow_json_unlikely(!consume('[')))
911+
if (crow_json_unlikely(!consume('[')) || crow_json_unlikely(depth > max_depth))
909912
{
910913
ret.set_error();
911914
return ret;
@@ -919,7 +922,7 @@ namespace crow
919922

920923
while (1)
921924
{
922-
auto v = decode_value();
925+
auto v = decode_value(depth + 1);
923926
if (crow_json_unlikely(!v))
924927
{
925928
ret.set_error();
@@ -1068,14 +1071,15 @@ namespace crow
10681071
return {};
10691072
}
10701073

1071-
rvalue decode_value()
1074+
1075+
rvalue decode_value(unsigned depth)
10721076
{
10731077
switch (*data)
10741078
{
10751079
case '[':
1076-
return decode_list();
1080+
return decode_list(depth + 1);
10771081
case '{':
1078-
return decode_object();
1082+
return decode_object(depth + 1);
10791083
case '"':
10801084
return decode_string();
10811085
case 't':
@@ -1122,10 +1126,10 @@ namespace crow
11221126
return {};
11231127
}
11241128

1125-
rvalue decode_object()
1129+
rvalue decode_object(unsigned depth)
11261130
{
11271131
rvalue ret(type::Object);
1128-
if (crow_json_unlikely(!consume('{')))
1132+
if (crow_json_unlikely(!consume('{')) || crow_json_unlikely(depth > max_depth))
11291133
{
11301134
ret.set_error();
11311135
return ret;
@@ -1160,7 +1164,7 @@ namespace crow
11601164
auto key = t.s();
11611165

11621166
ws_skip();
1163-
auto v = decode_value();
1167+
auto v = decode_value(depth + 1);
11641168
if (crow_json_unlikely(!v))
11651169
{
11661170
ret.set_error();
@@ -1188,7 +1192,7 @@ namespace crow
11881192
rvalue parse()
11891193
{
11901194
ws_skip();
1191-
auto ret = decode_value(); // or decode object?
1195+
auto ret = decode_value(0); // or decode object?
11921196
ws_skip();
11931197
if (ret && *data != '\0')
11941198
ret.set_error();

0 commit comments

Comments
 (0)