From 0bb1439d0dc649371e5d2aaee0c881d73e7a9483 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Tue, 1 Nov 2016 15:19:24 -0400 Subject: [PATCH] Support parsing raw literals in UniValue Fixes following test failures in https://github.com/nst/JSONTestSuite: bitcoin SHOULD_HAVE_PASSED y_structure_lonely_negative_real.json bitcoin SHOULD_HAVE_PASSED y_structure_lonely_string.json bitcoin SHOULD_HAVE_PASSED y_structure_lonely_false.json bitcoin SHOULD_HAVE_PASSED y_structure_lonely_null.json bitcoin SHOULD_HAVE_PASSED y_string_space.json bitcoin SHOULD_HAVE_PASSED y_structure_string_empty.json bitcoin SHOULD_HAVE_PASSED y_structure_lonely_int.json bitcoin SHOULD_HAVE_PASSED y_structure_lonely_true.json --- Makefile.am | 7 ++++++- lib/univalue_read.cpp | 29 +++++++++++++++++------------ test/fail1.json | 2 +- test/round3.json | 1 + test/round4.json | 1 + test/round5.json | 1 + test/round6.json | 1 + test/round7.json | 1 + test/unitester.cpp | 5 +++++ 9 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 test/round3.json create mode 100644 test/round4.json create mode 100644 test/round5.json create mode 100644 test/round6.json create mode 100644 test/round7.json diff --git a/Makefile.am b/Makefile.am index 6c1ec81e63f..122aa218f7c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,6 +88,11 @@ TEST_FILES = \ $(TEST_DATA_DIR)/pass2.json \ $(TEST_DATA_DIR)/pass3.json \ $(TEST_DATA_DIR)/round1.json \ - $(TEST_DATA_DIR)/round2.json + $(TEST_DATA_DIR)/round2.json \ + $(TEST_DATA_DIR)/round3.json \ + $(TEST_DATA_DIR)/round4.json \ + $(TEST_DATA_DIR)/round5.json \ + $(TEST_DATA_DIR)/round6.json \ + $(TEST_DATA_DIR)/round7.json EXTRA_DIST=$(TEST_FILES) $(GEN_SRCS) diff --git a/lib/univalue_read.cpp b/lib/univalue_read.cpp index 95bac6958d0..fd9f4aeb537 100644 --- a/lib/univalue_read.cpp +++ b/lib/univalue_read.cpp @@ -177,7 +177,7 @@ enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, string valStr; JSONUTF8StringFilter writer(valStr); - while (*raw) { + while (true) { if ((unsigned char)*raw < 0x20) return JTOK_ERR; @@ -371,9 +371,6 @@ bool UniValue::read(const char *raw) case JTOK_KW_NULL: case JTOK_KW_TRUE: case JTOK_KW_FALSE: { - if (!stack.size()) - return false; - UniValue tmpVal; switch (tok) { case JTOK_KW_NULL: @@ -388,6 +385,11 @@ bool UniValue::read(const char *raw) default: /* impossible */ break; } + if (!stack.size()) { + *this = tmpVal; + break; + } + UniValue *top = stack.back(); top->values.push_back(tmpVal); @@ -396,10 +398,12 @@ bool UniValue::read(const char *raw) } case JTOK_NUMBER: { - if (!stack.size()) - return false; - UniValue tmpVal(VNUM, tokenVal); + if (!stack.size()) { + *this = tmpVal; + break; + } + UniValue *top = stack.back(); top->values.push_back(tmpVal); @@ -408,17 +412,18 @@ bool UniValue::read(const char *raw) } case JTOK_STRING: { - if (!stack.size()) - return false; - - UniValue *top = stack.back(); - if (expect(OBJ_NAME)) { + UniValue *top = stack.back(); top->keys.push_back(tokenVal); clearExpect(OBJ_NAME); setExpect(COLON); } else { UniValue tmpVal(VSTR, tokenVal); + if (!stack.size()) { + *this = tmpVal; + break; + } + UniValue *top = stack.back(); top->values.push_back(tmpVal); } diff --git a/test/fail1.json b/test/fail1.json index 6216b865f10..8feb01a6d0d 100644 --- a/test/fail1.json +++ b/test/fail1.json @@ -1 +1 @@ -"A JSON payload should be an object or array, not a string." \ No newline at end of file +"This is a string that never ends, yes it goes on and on, my friends. diff --git a/test/round3.json b/test/round3.json new file mode 100644 index 00000000000..7182dc2f9b8 --- /dev/null +++ b/test/round3.json @@ -0,0 +1 @@ +"abcdefghijklmnopqrstuvwxyz" diff --git a/test/round4.json b/test/round4.json new file mode 100644 index 00000000000..7f8f011eb73 --- /dev/null +++ b/test/round4.json @@ -0,0 +1 @@ +7 diff --git a/test/round5.json b/test/round5.json new file mode 100644 index 00000000000..27ba77ddaf6 --- /dev/null +++ b/test/round5.json @@ -0,0 +1 @@ +true diff --git a/test/round6.json b/test/round6.json new file mode 100644 index 00000000000..c508d5366f7 --- /dev/null +++ b/test/round6.json @@ -0,0 +1 @@ +false diff --git a/test/round7.json b/test/round7.json new file mode 100644 index 00000000000..19765bd501b --- /dev/null +++ b/test/round7.json @@ -0,0 +1 @@ +null diff --git a/test/unitester.cpp b/test/unitester.cpp index 05f3842cd1e..bf597fe5e5b 100644 --- a/test/unitester.cpp +++ b/test/unitester.cpp @@ -125,6 +125,11 @@ static const char *filenames[] = { "pass3.json", "round1.json", // round-trip test "round2.json", // unicode + "round3.json", // bare string + "round4.json", // bare number + "round5.json", // bare true + "round6.json", // bare false + "round7.json", // bare null }; // Test \u handling