diff --git a/Source/cmJSONState.cxx b/Source/cmJSONState.cxx index b729009c08..bdc792df30 100644 --- a/Source/cmJSONState.cxx +++ b/Source/cmJSONState.cxx @@ -26,8 +26,6 @@ cmJSONState::cmJSONState(std::string jsonFile, Json::Value* root, this->AddError(cmStrCat("File not found: ", this->Filename)); return; } - // If there's a BOM, toss it. - cmsys::FStream::ReadBOM(fin); this->ReadJSONStream(fin, root, strictMode); } @@ -127,6 +125,9 @@ void cmJSONState::pop_stack() void cmJSONState::ReadJSONStream(std::istream& jsonIStream, Json::Value* root, StrictMode strictMode) { + // If there's a BOM, toss it. + cmsys::FStream::ReadBOM(jsonIStream); + // Save the entire document. std::streampos inBegin = jsonIStream.tellg(); this->doc = std::string(std::istreambuf_iterator(jsonIStream), diff --git a/Source/cmPlistParser.cxx b/Source/cmPlistParser.cxx index af0962470c..d02eada329 100644 --- a/Source/cmPlistParser.cxx +++ b/Source/cmPlistParser.cxx @@ -2,6 +2,9 @@ file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmPlistParser.h" +#include +#include +#include #include #include @@ -25,10 +28,16 @@ cm::optional cmParsePlist(std::string const& filename) return cm::nullopt; } - Json::Value value; + // Buffer plutil's output into a seekable stream. cmJSONState must be able + // peek at a leading BOM, which the process pipe behind cmUVIStream can't + // handle. cmUVIStream outputStream(chain.OutputStream()); - cmJSONState parseState(outputStream, &value, - cmJSONState::StrictMode::Relaxed); + std::string output{ std::istreambuf_iterator(outputStream), + std::istreambuf_iterator() }; + std::istringstream jsonStream(output); + + Json::Value value; + cmJSONState parseState(jsonStream, &value, cmJSONState::StrictMode::Relaxed); if (!parseState.errors.empty()) { return cm::nullopt; } diff --git a/Tests/Fuzzing/corpus/json/.gitattributes b/Tests/Fuzzing/corpus/json/.gitattributes index 65c9d8d3d0..4f1e99d427 100644 --- a/Tests/Fuzzing/corpus/json/.gitattributes +++ b/Tests/Fuzzing/corpus/json/.gitattributes @@ -1 +1,2 @@ array.json -text -whitespace +bom.json -text -whitespace diff --git a/Tests/Fuzzing/corpus/json/bom.json b/Tests/Fuzzing/corpus/json/bom.json new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/Tests/Fuzzing/corpus/json/bom.json @@ -0,0 +1 @@ + \ No newline at end of file