diff --git a/Source/core/JSON.h b/Source/core/JSON.h index 9952b04118..4d518262c4 100644 --- a/Source/core/JSON.h +++ b/Source/core/JSON.h @@ -3627,11 +3627,11 @@ namespace Core { { uint16_t loaded = 0; - bool completed = false, suffix = false; + bool completed = false, suffix = false, beforeStringScope = false, afterStringScope = false, stringScope = false; - uint16_t markerStartCount = 0, markerEndCount = 0, separatorCount = 0; + uint16_t markerStartCount = 0, markerEndCount = 0, separatorCount = 0, containerStartMarkerCount = 0, containerEndMarkerCount = 0; - uint16_t valueStartPos = 0;//, valueEndPos = 0; + uint16_t valueStartPos = 0, separatorPos = 0; _state = 0; @@ -3659,6 +3659,16 @@ namespace Core { continue; break; case '"' : // Quoted character sequence + if ( !suffix + && ( beforeStringScope + || afterStringScope + || (markerStartCount && markerStartCount != markerEndCount) + ) + ) { + stringScope = !stringScope; + break; + } + if (!markerStartCount && !(_state & QUOTED) && offset > 0) { _state = ERROR; error = Error{"Character '" + std::string(1, ch) + "' at unsupported position for ArrayType<>"}; @@ -3676,13 +3686,24 @@ namespace Core { _state |= suffix ? QUOTED : NONE; separatorCount -= separatorCount && !suffix ? 1 : 0; - + break; + case '{' : if (!stringScope && containerStartMarkerCount >= containerEndMarkerCount) { + ++containerStartMarkerCount; + } + break; + case '}' : if (!stringScope && containerStartMarkerCount < containerEndMarkerCount) { + ++containerEndMarkerCount; + } break; case '[' : // Start marker + if (stringScope) { + break; + } + if ( (markerStartCount == 0 && markerStartCount < markerEndCount) || (markerStartCount > 0 && markerStartCount <= markerEndCount) - ) { - _state = ERROR; + ) { + _state = ERROR; error = Error{"Character '" + std::string(1, ch) + "' at unsupported position for ArrayType<>"}; continue; } @@ -3695,10 +3716,16 @@ namespace Core { separatorCount -= separatorCount ? 1 : 0; + beforeStringScope = !stringScope; break; case ']' : // End marker - if ( (markerStartCount > 0 && markerStartCount <= markerEndCount) + if (stringScope) { + break; + } + + if ( !(markerStartCount > 0 && markerStartCount >= markerEndCount) || separatorCount + ||( separatorPos == loaded - 1) ) { _state = ERROR; error = Error{"Character '" + std::string(1, ch) + "' at unsupported position for ArrayType<>"}; @@ -3708,8 +3735,14 @@ namespace Core { ++markerEndCount; + afterStringScope = !stringScope; + FALLTHROUGH; case ',' : // Value separator + if (stringScope || containerStartMarkerCount != containerEndMarkerCount) { + break; + } + if (ch == ',' && (separatorCount || (loaded - 1 == valueStartPos) || markerStartCount == markerEndCount) ) { _state = ERROR; @@ -3719,6 +3752,7 @@ namespace Core { if (ch == ',') { ++separatorCount; + separatorPos = loaded; } if (markerStartCount == markerEndCount || ch == ',') { @@ -3742,6 +3776,8 @@ namespace Core { } valueStartPos = loaded; + + separatorCount -= separatorCount ? 1 : 0; } suffix = suffix || markerStartCount == markerEndCount; diff --git a/Tests/unit/core/test_jsontypes.cpp b/Tests/unit/core/test_jsontypes.cpp index 697f06dd24..e27d3cb7cf 100644 --- a/Tests/unit/core/test_jsontypes.cpp +++ b/Tests/unit/core/test_jsontypes.cpp @@ -1798,7 +1798,6 @@ namespace Tests { if (!malformed) { // Correctly formatted // =================== - // 'Empty' and nested JSON value arrays are allowed count += TestJSONFormat("", FromTo, !AllowChange); // Empty by definition, returns ['content of empty type'] @@ -1844,7 +1843,12 @@ namespace Tests { count += TestJSONFormat("[[{}]\u0009\u000A\u000D\u0020,[{}]]", FromTo, !AllowChange); // [[{}],[{}]] count += TestJSONFormat("[[{}]\u0009\u000A\u000D\u0020,\u0009\u000A\u000D\u0020[{}]]", FromTo, !AllowChange); // [[{}],[{}]] - count += 14; + // Scope tests + count += TestJSONFormat("[{{},{}},{{},{}}]", FromTo, AllowChange); + count += TestJSONFormat("\"[{{},{}},{{},{}}]\"", FromTo, AllowChange); + count += TestJSONFormat("\"[\"{{},{}}\",\"{{},{}}\"]\"", FromTo, AllowChange); + + count += 15; } if ( std::is_same::value @@ -1868,7 +1872,11 @@ namespace Tests { count += TestJSONFormat("[[0]\u0009\u000A\u000D\u0020,[0]]", FromTo, !AllowChange); // [[0],[0]] count += TestJSONFormat("[[0]\u0009\u000A\u000D\u0020,\u0009\u000A\u000D\u0020[0]]", FromTo, !AllowChange); // [[0],[0]] - count += 14; + // Scope tests + count += TestJSONFormat("[\"0\"]", FromTo, AllowChange); + count += TestJSONFormat("\"[\"0\"]\"", FromTo, AllowChange); + + count += 16; } if ( std::is_same::value @@ -1894,7 +1902,11 @@ namespace Tests { count += TestJSONFormat("[[0x0]\u0009\u000A\u000D\u0020,[0x0]]", FromTo, !AllowChange); // [[0x0,0x0]] count += TestJSONFormat("[[0x0]\u0009\u000A\u000D\u0020,\u0009\u000A\u000D\u0020[0x0]]", FromTo, !AllowChange); // [[0x0,0x0]] - count += 14; + // Scope tests + count += TestJSONFormat("[\"0x0\"]", FromTo, AllowChange); + count += TestJSONFormat("\"[\"0x0\"]\"", FromTo, AllowChange); + + count += 16; } if ( std::is_same::value @@ -1918,7 +1930,11 @@ namespace Tests { count += TestJSONFormat("[[00]\u0009\u000A\u000D\u0020,[00]]", FromTo, !AllowChange); // [[00,00]] count += TestJSONFormat("[[00]\u0009\u000A\u000D\u0020,\u0009\u000A\u000D\u0020[00]]", FromTo, !AllowChange); // [[00,00]] - count += 14; + // Scope tests + count += TestJSONFormat("[\"00\"]", FromTo, AllowChange); + count += TestJSONFormat("\"[\"00\"]\"", FromTo, AllowChange); + + count += 16; } if ( std::is_same::value @@ -1926,7 +1942,6 @@ namespace Tests { ) { // All re-created character sequences for arrays are not compared on float value basis but on character per character basis. // This alost always fails. - count += TestJSONFormat("[0.0]", FromTo, !AllowChange); count += TestJSONFormat("[0.0,0.0]", FromTo, !AllowChange); count += TestJSONFormat("[0.0,\u0009\u000A\u000D\u00200.0]", FromTo, !AllowChange); // [[0.0,0.0] @@ -1939,7 +1954,11 @@ namespace Tests { count += TestJSONFormat("[[0.0]\u0009\u000A\u000D\u0020,[0.0]]", FromTo, !AllowChange); // [[0.0],[0.0]] count += TestJSONFormat("[[0.0]\u0009\u000A\u000D\u0020,\u0009\u000A\u000D\u0020[0.0]]", FromTo, !AllowChange); // [[0.0],[0.0]] - count += 14; + // Scope tests + count += TestJSONFormat("[\"0.0\"]", FromTo, !AllowChange); + count += TestJSONFormat("\"[\"0.0\"]\"", FromTo, !AllowChange); + + count += 16; } if (std::is_same::value) { @@ -1958,7 +1977,11 @@ namespace Tests { // Nullifying string element count += TestJSONFormat("[\"null\"]", FromTo, AllowChange); - count += 13; + // Scope tests + count += TestJSONFormat("[\"[\"]", FromTo, AllowChange); + count += TestJSONFormat("[\"{}\"]", FromTo, AllowChange); + + count += 15; } if (std::is_same::value) { @@ -1991,6 +2014,12 @@ namespace Tests { count += TestJSONFormat("[[true],[false]]", FromTo, AllowChange); count += TestJSONFormat("[[false],[true]]", FromTo, AllowChange); + + // Scope tests + count += TestJSONFormat("[\"true\"]", FromTo, AllowChange); + count += TestJSONFormat("\"[\"true\"]\"", FromTo, AllowChange); + count += TestJSONFormat("[\"false\"]", FromTo, AllowChange); + count += TestJSONFormat("\"[\"false\"]\"", FromTo, AllowChange); } } else { // Malformed @@ -2004,7 +2033,7 @@ namespace Tests { count += !TestJSONFormat("[[],]", FromTo, AllowChange); count += !TestJSONFormat("[[][]]", FromTo, AllowChange); count += !TestJSONFormat("[[].[]]", FromTo, AllowChange); // Any character not being , - +ASSERT((count == 7) || (count == (17+7))); // Mismatch opening and closing count += !TestJSONFormat("[", FromTo, AllowChange); count += !TestJSONFormat("]", FromTo, AllowChange); @@ -2013,15 +2042,16 @@ namespace Tests { count += !TestJSONFormat("{]", FromTo, AllowChange); count += !TestJSONFormat("[}", FromTo, AllowChange); count += !TestJSONFormat("()", FromTo, AllowChange); - +ASSERT((count == 14) || (count == (17+14))); // Values that cannot be used count += !TestJSONFormat("{}", FromTo, AllowChange); count += !TestJSONFormat("true", FromTo, AllowChange); count += !TestJSONFormat("false", FromTo, AllowChange); +ASSERT((count == 17) || (count == (17+17))); } } while (FromTo); - return !malformed ? count == 90 + return !malformed ? count == 98 : count == 34 ; } @@ -3315,130 +3345,130 @@ namespace Tests { uint8_t count = 0; EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); EXPECT_TRUE(TestArrayFromString(malformed, count)); - EXPECT_EQ(count, 90); + EXPECT_EQ(count, 98); EXPECT_TRUE(TestArrayFromString(!malformed, count)); EXPECT_EQ(count, 34); }