From 703bcb6e7de592745b487aae61fc28cd9a022ece Mon Sep 17 00:00:00 2001 From: Swaroop Sridhar Date: Wed, 22 Apr 2020 23:47:05 -0700 Subject: [PATCH] Json-Parse: Parse with `RapidJson::kParseStopWhenDoneFlag` on all architectures (#35073) RapidJson's `kParseStopWhenDoneFlag` indicates that parsing should stop once the root element is parsed, and should not throw an error for any further content. This flag is useful when the input stream doesn't always have a null-terminator -- ex: an input `bytestream` (rather than a `stringstream`), files embeded within the single file bundle. The limitation of using this flag is that any actual random text after the root element is silently ignored. Currently, RapidJson is invoked with `kParseStopWhenDoneFlag` on Windows, but not on Unix. This caused `kParseErrorDocumentRootNotSingular` failure on Unix when parsing json files from single-file bundles. This change fixes this problem by passing `kParseStopWhenDoneFlag` on all platforms. This also makes the host behavior consistent across platforms. --- src/installer/corehost/cli/json_parser.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/installer/corehost/cli/json_parser.cpp b/src/installer/corehost/cli/json_parser.cpp index c6f0cbbf0c9127..65e0fd3ccfde2a 100644 --- a/src/installer/corehost/cli/json_parser.cpp +++ b/src/installer/corehost/cli/json_parser.cpp @@ -77,16 +77,15 @@ void json_parser_t::realloc_buffer(size_t size) bool json_parser_t::parse_json(char* data, int64_t size, const pal::string_t& context) { + constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag | rapidjson::ParseFlag::kParseCommentsFlag; #ifdef _WIN32 // Can't use in-situ parsing on Windows, as JSON data is encoded in // UTF-8 and the host expects wide strings. m_document will store // data in UTF-16 (with pal::char_t as the character type), but it // has to know that data is encoded in UTF-8 to convert during parsing. - constexpr auto flags = rapidjson::ParseFlag::kParseStopWhenDoneFlag - | rapidjson::ParseFlag::kParseCommentsFlag; m_document.Parse>(data); #else // _WIN32 - m_document.ParseInsitu(data); + m_document.ParseInsitu(data); #endif // _WIN32 if (m_document.HasParseError()) @@ -140,9 +139,10 @@ bool json_parser_t::parse_file(const pal::string_t& path) if (bundle::info_t::is_single_file_bundle()) { + // Due to in-situ parsing on Linux, + // * The json file is mapped as copy-on-write. + // * The mapping cannot be immediately released, and will be unmapped by the json_parser destructor. m_bundle_data = bundle::info_t::config_t::map(path, m_bundle_location); - // The mapping will be unmapped by the json_parser destructor. - // The mapping cannot be immediately released due to in-situ parsing on Linux. if (m_bundle_data != nullptr) {