From dab06ad47e8c9256888b9593e0aa098bfc6c7fb6 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Wed, 3 Jun 2026 11:28:48 -0400 Subject: [PATCH 1/4] Fix: Check flatbuffer integrity before parsing Updated flatbuffer to latest version to get verify buffer Use strol for key parsing to ensure exceptions do not result in a crash. --- cmake/external/flatbuffers.cmake | 6 ++-- remote_config/src/desktop/config_data.cc | 6 ++++ remote_config/src/desktop/file_manager.cc | 24 +++++++++++--- remote_config/src/desktop/metadata.cc | 17 +++++++++- .../flatbuffers/0001-remove-unused-var.patch | 32 ------------------- 5 files changed, 44 insertions(+), 41 deletions(-) delete mode 100644 scripts/git/patches/flatbuffers/0001-remove-unused-var.patch diff --git a/cmake/external/flatbuffers.cmake b/cmake/external/flatbuffers.cmake index aea3abb201..c79d686db4 100644 --- a/cmake/external/flatbuffers.cmake +++ b/cmake/external/flatbuffers.cmake @@ -18,9 +18,8 @@ if(TARGET flatbuffers OR NOT DOWNLOAD_FLATBUFFERS) return() endif() -set(version 99aa1ef21dd9dc3f9d4fb0eb82f4b59d0bb5e4c5) -set(patch_file - ${CMAKE_CURRENT_LIST_DIR}/../../scripts/git/patches/flatbuffers/0001-remove-unused-var.patch) +# Commit corresponds to Tag v25.12.19-2026-02-06-03fffb2 +set(version 95fda8c23e6e30ebd975892b5fad01efa53e039c) ExternalProject_Add( flatbuffers @@ -29,7 +28,6 @@ ExternalProject_Add( COMMAND git init flatbuffers COMMAND cd flatbuffers && git fetch --depth=1 https://github.com/google/flatbuffers.git ${version} && git reset --hard FETCH_HEAD - PATCH_COMMAND git apply ${patch_file} && git gc --aggressive PREFIX ${PROJECT_BINARY_DIR} CONFIGURE_COMMAND "" diff --git a/remote_config/src/desktop/config_data.cc b/remote_config/src/desktop/config_data.cc index 9afe8ef0f4..359f3e73f9 100644 --- a/remote_config/src/desktop/config_data.cc +++ b/remote_config/src/desktop/config_data.cc @@ -49,6 +49,9 @@ std::string NamespacedConfigData::Serialize() const { void NamespacedConfigData::Deserialize(const std::string& buffer) { const uint8_t* data = reinterpret_cast(buffer.data()); size_t size = buffer.size(); + if (!flexbuffers::VerifyBuffer(data, size)) { + return; + } auto struct_map = flexbuffers::GetRoot(data, size).AsMap(); flexbuffers::Map ns_config_map = struct_map["config_"].AsMap(); for (int i = 0, in = ns_config_map.size(); i < in; ++i) { @@ -142,6 +145,9 @@ std::string LayeredConfigs::Serialize() const { void LayeredConfigs::Deserialize(const std::string& buffer) { const uint8_t* data = reinterpret_cast(buffer.data()); size_t size = buffer.size(); + if (!flexbuffers::VerifyBuffer(data, size)) { + return; + } auto struct_map = flexbuffers::GetRoot(data, size).AsMap(); fetched.Deserialize(struct_map["fetched"].AsString().str()); active.Deserialize(struct_map["active"].AsString().str()); diff --git a/remote_config/src/desktop/file_manager.cc b/remote_config/src/desktop/file_manager.cc index f4cf5aeb5f..43bffbe430 100644 --- a/remote_config/src/desktop/file_manager.cc +++ b/remote_config/src/desktop/file_manager.cc @@ -37,10 +37,14 @@ namespace internal { RemoteConfigFileManager::RemoteConfigFileManager(const std::string& filename, const firebase::App& app) { std::string app_data_prefix = - std::string(app.options().package_name()) + "/" + app.name(); - std::string file_path = - AppDataDir(app_data_prefix.c_str(), /*should_create=*/true) + "/" + - filename; + std::string(app.options().package_name()) + "/remote_config"; + std::string error; + std::string app_dir = + AppDataDir(app_data_prefix.c_str(), /*should_create=*/true, &error); + std::string file_path; + if (error.empty() && !app_dir.empty()) { + file_path = app_dir + "/" + app.name() + "_" + filename; + } #if FIREBASE_PLATFORM_WINDOWS std::wstring_convert> utf8_to_wstring; file_path_ = utf8_to_wstring.from_bytes(file_path); @@ -50,7 +54,13 @@ RemoteConfigFileManager::RemoteConfigFileManager(const std::string& filename, } bool RemoteConfigFileManager::Load(LayeredConfigs* configs) const { + if (file_path_.empty()) { + return false; + } std::fstream input(file_path_, std::ios::in | std::ios::binary); + if (!input) { + return false; + } std::stringstream ss; ss << input.rdbuf(); configs->Deserialize(ss.str()); @@ -58,8 +68,14 @@ bool RemoteConfigFileManager::Load(LayeredConfigs* configs) const { } bool RemoteConfigFileManager::Save(const LayeredConfigs& configs) const { + if (file_path_.empty()) { + return false; + } std::string buffer = configs.Serialize(); std::fstream output(file_path_, std::ios::out | std::ios::binary); + if (!output) { + return false; + } output.write(buffer.c_str(), buffer.size()); return true; } diff --git a/remote_config/src/desktop/metadata.cc b/remote_config/src/desktop/metadata.cc index 3faf93d8de..befd20a9c5 100644 --- a/remote_config/src/desktop/metadata.cc +++ b/remote_config/src/desktop/metadata.cc @@ -14,6 +14,7 @@ #include "remote_config/src/desktop/metadata.h" +#include #include #include @@ -58,6 +59,9 @@ std::string RemoteConfigMetadata::Serialize() const { void RemoteConfigMetadata::Deserialize(const std::string& buffer) { const uint8_t* data = reinterpret_cast(buffer.data()); size_t size = buffer.size(); + if (!flexbuffers::VerifyBuffer(data, size)) { + return; + } auto struct_map = flexbuffers::GetRoot(data, size).AsMap(); flexbuffers::Map info = struct_map["info"].AsMap(); @@ -75,7 +79,18 @@ void RemoteConfigMetadata::Deserialize(const std::string& buffer) { settings_.clear(); flexbuffers::Map settings = struct_map["settings"].AsMap(); for (int i = 0, n = settings.size(); i < n; ++i) { - int int_key = std::stoi(settings.Keys()[i].AsKey()); + const char* key_str = settings.Keys()[i].AsKey(); + if (!key_str) continue; + char* endptr = nullptr; + long raw_key = std::strtol(key_str, &endptr, 10); + if (endptr == key_str || *endptr != '\0') { + continue; + } + if (raw_key < std::numeric_limits::min() || + raw_key > std::numeric_limits::max()) { + continue; + } + int int_key = static_cast(raw_key); settings_[static_cast(int_key)] = settings.Values()[i].AsString().c_str(); } diff --git a/scripts/git/patches/flatbuffers/0001-remove-unused-var.patch b/scripts/git/patches/flatbuffers/0001-remove-unused-var.patch deleted file mode 100644 index 7a3b3a70ae..0000000000 --- a/scripts/git/patches/flatbuffers/0001-remove-unused-var.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b08adb291f3ae0a2626d50eb8abecbc3a0de63d9 Mon Sep 17 00:00:00 2001 -From: "almostmatt@google.com" -Date: Fri, 21 Apr 2023 14:31:06 -0400 -Subject: [PATCH] remove unused var - ---- - src/idl_gen_rust.cpp | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp -index 55b8439b..48539d52 100644 ---- a/src/idl_gen_rust.cpp -+++ b/src/idl_gen_rust.cpp -@@ -406,7 +406,6 @@ class RustGenerator : public BaseGenerator { - // example: f(A, D::E) -> super::D::E - // does not include leaf object (typically a struct type). - -- size_t i = 0; - std::stringstream stream; - - auto s = src->components.begin(); -@@ -417,7 +416,6 @@ class RustGenerator : public BaseGenerator { - if (*s != *d) { break; } - ++s; - ++d; -- ++i; - } - - for (; s != src->components.end(); ++s) { stream << "super::"; } --- -2.40.1.606.ga4b1b128d6-goog - From 414623bf84808e01d3070266242e24162a1b8709 Mon Sep 17 00:00:00 2001 From: Austin Benoit Date: Wed, 3 Jun 2026 13:21:06 -0400 Subject: [PATCH 2/4] Update remote_config/src/desktop/metadata.cc Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- remote_config/src/desktop/metadata.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/remote_config/src/desktop/metadata.cc b/remote_config/src/desktop/metadata.cc index befd20a9c5..daf58ddff6 100644 --- a/remote_config/src/desktop/metadata.cc +++ b/remote_config/src/desktop/metadata.cc @@ -14,6 +14,8 @@ #include "remote_config/src/desktop/metadata.h" +#include +#include #include #include #include From dbc0e3df75cf80175070e4e2bfcb0c8f469d9c70 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 4 Jun 2026 10:59:53 -0400 Subject: [PATCH 3/4] Handle new FBT_MAX_TYPE in flatbuffers --- app/src/variant_util.cc | 4 ++++ database/src/desktop/persistence/flatbuffer_conversions.cc | 4 ++++ remote_config/src/desktop/remote_config_response.cc | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/app/src/variant_util.cc b/app/src/variant_util.cc index d8c03dde3d..c25433c808 100644 --- a/app/src/variant_util.cc +++ b/app/src/variant_util.cc @@ -247,6 +247,10 @@ Variant FlexbufferToVariant(const flexbuffers::Reference& ref) { case flexbuffers::FBT_BLOB: LogError("Flexbuffers containing blobs are not supported."); break; + case flexbuffers::FBT_MAX_TYPE: + LogError("Unknown or unsupported flexbuffer type: %d", + static_cast(ref.GetType())); + break; } return Variant::Null(); } diff --git a/database/src/desktop/persistence/flatbuffer_conversions.cc b/database/src/desktop/persistence/flatbuffer_conversions.cc index d10938a3fe..41efe25d85 100644 --- a/database/src/desktop/persistence/flatbuffer_conversions.cc +++ b/database/src/desktop/persistence/flatbuffer_conversions.cc @@ -101,6 +101,10 @@ Variant FlexbufferToVariant(const flexbuffers::Reference& ref) { case flexbuffers::FBT_BLOB: LogError("Flexbuffers containing blobs are not supported."); break; + case flexbuffers::FBT_MAX_TYPE: + LogError("Unknown or unsupported flexbuffer type: %d", + static_cast(ref.GetType())); + break; } return Variant::Null(); } diff --git a/remote_config/src/desktop/remote_config_response.cc b/remote_config/src/desktop/remote_config_response.cc index 397c1f5d9e..8143640bc4 100644 --- a/remote_config/src/desktop/remote_config_response.cc +++ b/remote_config/src/desktop/remote_config_response.cc @@ -81,6 +81,10 @@ Variant FlexbufferToVariant(const flexbuffers::Reference& ref) { case flexbuffers::FBT_BLOB: LogError("Flexbuffers containing blobs are not supported."); break; + case flexbuffers::FBT_MAX_TYPE: + LogError("Unknown or unsupported flexbuffer type: %d", + static_cast(ref.GetType())); + break; } return Variant::Null(); } From 05be663a7bd9ee77f2baf41d07de3927f8896f8b Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Fri, 5 Jun 2026 14:06:16 -0400 Subject: [PATCH 4/4] Fix the GenerateText response --- app/rest/request_json.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/rest/request_json.h b/app/rest/request_json.h index 964ffbd529..839a6f4e97 100644 --- a/app/rest/request_json.h +++ b/app/rest/request_json.h @@ -65,7 +65,7 @@ class RequestJson : public Request { // Generate JSON string. std::string json; bool generate_status = - GenerateText(*parser_, builder.GetBufferPointer(), &json); + GenerateText(*parser_, builder.GetBufferPointer(), &json) == nullptr; FIREBASE_ASSERT_RETURN_VOID(generate_status); set_post_fields(json.c_str());