From d3ccd49eebb573cb37019b0cd25f033c857f24fd Mon Sep 17 00:00:00 2001 From: Tyler Yankee Date: Fri, 6 Feb 2026 12:09:39 -0500 Subject: [PATCH] cmFileAPI: Use cmJSONState to read client queries This approach will be more portable. --- Source/cmFileAPI.cxx | 39 ++++--------------- Source/cmFileAPI.h | 2 - .../RunCMake/FileAPI/ClientStateful-check.py | 2 +- 3 files changed, 8 insertions(+), 35 deletions(-) diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index ff31855155..6fb9b4b7ac 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -24,6 +24,7 @@ #include "cmFileAPIConfigureLog.h" #include "cmFileAPIToolchains.h" #include "cmGlobalGenerator.h" +#include "cmJSONState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTimestamp.h" @@ -54,14 +55,6 @@ cmFileAPI::cmFileAPI(cmake* cm) this->UserAPIv1 = cmStrCat(std::move(*cmakeConfigDir), "/api/v1"_s); } - Json::CharReaderBuilder rbuilder; - rbuilder["collectComments"] = false; - rbuilder["failIfExtra"] = true; - rbuilder["rejectDupKeys"] = false; - rbuilder["strictRoot"] = true; - this->JsonReader = - std::unique_ptr(rbuilder.newCharReader()); - Json::StreamWriterBuilder wbuilder; wbuilder["indentation"] = "\t"; this->JsonWriter = @@ -174,37 +167,19 @@ void cmFileAPI::RemoveOldReplyFiles() bool cmFileAPI::ReadJsonFile(std::string const& file, Json::Value& value, std::string& error) { - std::vector content; - - cmsys::ifstream fin; - if (!cmSystemTools::FileIsDirectory(file)) { - fin.open(file.c_str(), std::ios::binary); - } - auto finEnd = fin.rdbuf()->pubseekoff(0, std::ios::end); - if (finEnd > 0) { - size_t finSize = finEnd; - try { - // Allocate a buffer to read the whole file. - content.resize(finSize); - - // Now read the file from the beginning. - fin.seekg(0, std::ios::beg); - fin.read(content.data(), finSize); - } catch (...) { - fin.setstate(std::ios::failbit); - } - } - fin.close(); - if (!fin) { + // Verify the file exists. + if (!cmSystemTools::FileExists(file) || + cmSystemTools::FileIsDirectory(file)) { value = Json::Value(); error = "failed to read from file"; return false; } // Parse our buffer as json. - if (!this->JsonReader->parse(content.data(), content.data() + content.size(), - &value, &error)) { + cmJSONState parseState(file, &value); + if (!parseState.errors.empty()) { value = Json::Value(); + error = parseState.GetErrorMessage(); return false; } diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h index 2e2511106e..9aad2ca226 100644 --- a/Source/cmFileAPI.h +++ b/Source/cmFileAPI.h @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -169,7 +168,6 @@ private: /** Identify the situation in which WriteReplies was called. */ IndexFor ReplyIndexFor = IndexFor::Success; - std::unique_ptr JsonReader; std::unique_ptr JsonWriter; bool ReadJsonFile(std::string const& file, Json::Value& value, diff --git a/Tests/RunCMake/FileAPI/ClientStateful-check.py b/Tests/RunCMake/FileAPI/ClientStateful-check.py index 28679bbce5..8beffb12da 100644 --- a/Tests/RunCMake/FileAPI/ClientStateful-check.py +++ b/Tests/RunCMake/FileAPI/ClientStateful-check.py @@ -105,7 +105,7 @@ def check_query_json_bad_root(q): check_error_re(q, "A valid JSON document must be either an array or an object value") def check_query_json_empty(q): - check_error_re(q, "value, object or array expected") + check_error_re(q, "A JSON document cannot be empty") def check_query_json_extra(q): if bool(os.environ.get("CMake_JSONCPP_PRE_1_7_5", "")) and is_dict(q) and sorted(q.keys()) == ["responses"]: