diff options
author | MarcoFalke <falke.marco@gmail.com> | 2020-02-09 07:43:12 -0800 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2020-02-09 07:43:12 -0800 |
commit | 97aa5740c0e9ef433cbedafe689b641297b50f5e (patch) | |
tree | 3ebb64da63fa27ad0a305c3e83fa89a85648eb24 | |
parent | fa0b3da36cd7cf0aada22f2d459296b81274c2f9 (diff) |
Squashed 'src/univalue/' changes from 5a58a46671..98261b1e7b
98261b1e7b Merge #22: Clamp JSON object depth to PHP limit
54c4015415 Clamp JSON object depth to PHP limit
git-subtree-dir: src/univalue
git-subtree-split: 98261b1e7be4ce9820e25c8ce37d40cdef19ab20
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | lib/univalue_read.cpp | 11 | ||||
-rw-r--r-- | test/fail45.json | 1 | ||||
-rw-r--r-- | test/pass4.json | 1 | ||||
-rw-r--r-- | test/unitester.cpp | 2 |
5 files changed, 17 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index e283fc890e..0f5ba59954 100644 --- a/Makefile.am +++ b/Makefile.am @@ -95,6 +95,7 @@ TEST_FILES = \ $(TEST_DATA_DIR)/fail41.json \ $(TEST_DATA_DIR)/fail42.json \ $(TEST_DATA_DIR)/fail44.json \ + $(TEST_DATA_DIR)/fail45.json \ $(TEST_DATA_DIR)/fail3.json \ $(TEST_DATA_DIR)/fail4.json \ $(TEST_DATA_DIR)/fail5.json \ @@ -105,6 +106,7 @@ TEST_FILES = \ $(TEST_DATA_DIR)/pass1.json \ $(TEST_DATA_DIR)/pass2.json \ $(TEST_DATA_DIR)/pass3.json \ + $(TEST_DATA_DIR)/pass4.json \ $(TEST_DATA_DIR)/round1.json \ $(TEST_DATA_DIR)/round2.json \ $(TEST_DATA_DIR)/round3.json \ diff --git a/lib/univalue_read.cpp b/lib/univalue_read.cpp index 14834db24d..5c6a1acf75 100644 --- a/lib/univalue_read.cpp +++ b/lib/univalue_read.cpp @@ -8,6 +8,14 @@ #include "univalue.h" #include "univalue_utffilter.h" +/* + * According to stackexchange, the original json test suite wanted + * to limit depth to 22. Widely-deployed PHP bails at depth 512, + * so we will follow PHP's lead, which should be more than sufficient + * (further stackexchange comments indicate depth > 32 rarely occurs). + */ +static const size_t MAX_JSON_DEPTH = 512; + static bool json_isdigit(int ch) { return ((ch >= '0') && (ch <= '9')); @@ -323,6 +331,9 @@ bool UniValue::read(const char *raw, size_t size) stack.push_back(newTop); } + if (stack.size() > MAX_JSON_DEPTH) + return false; + if (utyp == VOBJ) setExpect(OBJ_NAME); else diff --git a/test/fail45.json b/test/fail45.json new file mode 100644 index 0000000000..03a30d8800 --- /dev/null +++ b/test/fail45.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] diff --git a/test/pass4.json b/test/pass4.json new file mode 100644 index 0000000000..f5a680b31c --- /dev/null +++ b/test/pass4.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] diff --git a/test/unitester.cpp b/test/unitester.cpp index 75c0dc225a..2308afbcdf 100644 --- a/test/unitester.cpp +++ b/test/unitester.cpp @@ -114,6 +114,7 @@ static const char *filenames[] = { "fail41.json", // invalid unicode: unfinished UTF-8 "fail42.json", // valid json with garbage following a nul byte "fail44.json", // unterminated string + "fail45.json", // nested beyond max depth "fail3.json", "fail4.json", // extra comma "fail5.json", @@ -124,6 +125,7 @@ static const char *filenames[] = { "pass1.json", "pass2.json", "pass3.json", + "pass4.json", "round1.json", // round-trip test "round2.json", // unicode "round3.json", // bare string |