From 40b397a3d43ed3ad84957abc62012afafe1c8a0e Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 19 Jul 2022 15:17:12 -0400 Subject: [PATCH] Fixing issue 1870 (#1871) --- include/simdjson/arm64/stringparsing.h | 2 -- include/simdjson/fallback/stringparsing.h | 2 -- include/simdjson/generic/stringparsing.h | 0 include/simdjson/haswell/stringparsing.h | 2 -- include/simdjson/icelake/stringparsing.h | 2 -- include/simdjson/ppc64/stringparsing.h | 2 -- include/simdjson/westmere/stringparsing.h | 2 -- src/generic/stage2/stringparsing.h | 11 ++++++++++- tests/ondemand/ondemand_misc_tests.cpp | 12 ++++++++++++ 9 files changed, 22 insertions(+), 13 deletions(-) delete mode 100644 include/simdjson/generic/stringparsing.h diff --git a/include/simdjson/arm64/stringparsing.h b/include/simdjson/arm64/stringparsing.h index 8f56efc27..82197e30c 100644 --- a/include/simdjson/arm64/stringparsing.h +++ b/include/simdjson/arm64/stringparsing.h @@ -48,6 +48,4 @@ simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uin } // namespace SIMDJSON_IMPLEMENTATION } // namespace simdjson -#include "simdjson/generic/stringparsing.h" - #endif // SIMDJSON_ARM64_STRINGPARSING_H diff --git a/include/simdjson/fallback/stringparsing.h b/include/simdjson/fallback/stringparsing.h index ab501a6d9..c4bdbab13 100644 --- a/include/simdjson/fallback/stringparsing.h +++ b/include/simdjson/fallback/stringparsing.h @@ -31,6 +31,4 @@ simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uin } // namespace SIMDJSON_IMPLEMENTATION } // namespace simdjson -#include "simdjson/generic/stringparsing.h" - #endif // SIMDJSON_FALLBACK_STRINGPARSING_H diff --git a/include/simdjson/generic/stringparsing.h b/include/simdjson/generic/stringparsing.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/simdjson/haswell/stringparsing.h b/include/simdjson/haswell/stringparsing.h index b6028d8f2..88a4d0c8c 100644 --- a/include/simdjson/haswell/stringparsing.h +++ b/include/simdjson/haswell/stringparsing.h @@ -43,6 +43,4 @@ simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uin } // namespace SIMDJSON_IMPLEMENTATION } // namespace simdjson -#include "simdjson/generic/stringparsing.h" - #endif // SIMDJSON_HASWELL_STRINGPARSING_H diff --git a/include/simdjson/icelake/stringparsing.h b/include/simdjson/icelake/stringparsing.h index c4c664360..a617735f1 100644 --- a/include/simdjson/icelake/stringparsing.h +++ b/include/simdjson/icelake/stringparsing.h @@ -43,6 +43,4 @@ simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uin } // namespace SIMDJSON_IMPLEMENTATION } // namespace simdjson -#include "simdjson/generic/stringparsing.h" - #endif // SIMDJSON_ICELAKE_STRINGPARSING_H diff --git a/include/simdjson/ppc64/stringparsing.h b/include/simdjson/ppc64/stringparsing.h index b187919e0..9a60e449b 100644 --- a/include/simdjson/ppc64/stringparsing.h +++ b/include/simdjson/ppc64/stringparsing.h @@ -60,6 +60,4 @@ backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) { } // namespace SIMDJSON_IMPLEMENTATION } // namespace simdjson -#include "simdjson/generic/stringparsing.h" - #endif // SIMDJSON_PPC64_STRINGPARSING_H diff --git a/include/simdjson/westmere/stringparsing.h b/include/simdjson/westmere/stringparsing.h index 98e0fc5b2..6725fcf1d 100644 --- a/include/simdjson/westmere/stringparsing.h +++ b/include/simdjson/westmere/stringparsing.h @@ -41,6 +41,4 @@ simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uin } // namespace SIMDJSON_IMPLEMENTATION } // namespace simdjson -#include "simdjson/generic/stringparsing.h" - #endif // SIMDJSON_WESTMERE_STRINGPARSING_H diff --git a/src/generic/stage2/stringparsing.h b/src/generic/stage2/stringparsing.h index 696fb1110..97e0fa154 100644 --- a/src/generic/stage2/stringparsing.h +++ b/src/generic/stage2/stringparsing.h @@ -47,7 +47,12 @@ simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, // multilingual plane check uint32_t code_point = jsoncharutils::hex_to_u32_nocheck(*src_ptr + 2); *src_ptr += 6; - // check for low surrogate for characters outside the Basic + if (code_point >= 0xd800 && code_point < 0xdc00) { + } + + // If we found a high surrogate, we must + // check for low surrogate for characters + // outside the Basic // Multilingual Plane. if (code_point >= 0xd800 && code_point < 0xdc00) { if (((*src_ptr)[0] != '\\') || (*src_ptr)[1] != 'u') { @@ -67,6 +72,10 @@ simdjson_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, code_point = (((code_point - 0xd800) << 10) | (code_point_2 - 0xdc00)) + 0x10000; *src_ptr += 6; + } else if (code_point >= 0xdc00 && code_point <= 0xdfff) { + // If we encounter a low surrogate (not preceded by a high surrogate) + // then we have an error. + return false; } size_t offset = jsoncharutils::codepoint_to_utf8(code_point, *dst_ptr); *dst_ptr += offset; diff --git a/tests/ondemand/ondemand_misc_tests.cpp b/tests/ondemand/ondemand_misc_tests.cpp index b29d26c02..7325e5b44 100644 --- a/tests/ondemand/ondemand_misc_tests.cpp +++ b/tests/ondemand/ondemand_misc_tests.cpp @@ -52,6 +52,17 @@ namespace misc_tests { TEST_SUCCEED(); } + bool issue1870() { + TEST_START(); + ondemand::parser parser; + auto json = R"("\uDC00")"_padded; + ondemand::document doc; + ASSERT_SUCCESS(parser.iterate(json).get(doc)); + std::string_view view; + ASSERT_ERROR( doc.get_string().get(view), STRING_ERROR ); + TEST_SUCCEED(); + } + bool issue1660() { TEST_START(); ondemand::parser parser; @@ -447,6 +458,7 @@ namespace misc_tests { bool run() { return + issue1870() && is_alive_root_array() && is_alive_root_object() && is_alive_array() &&