From 61903ea8dbd9cfde395505a7eed2266b336d1a5d Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Wed, 3 Jun 2026 11:28:48 -0400 Subject: [PATCH 1/7] 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 | 19 ++++++++++- .../flatbuffers/0001-remove-unused-var.patch | 32 ------------------- 5 files changed, 46 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 a676f9a40a..7d0fdbb14d 100644 --- a/remote_config/src/desktop/config_data.cc +++ b/remote_config/src/desktop/config_data.cc @@ -51,6 +51,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) { @@ -144,6 +147,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 ceca1c07fa..dad657398f 100644 --- a/remote_config/src/desktop/metadata.cc +++ b/remote_config/src/desktop/metadata.cc @@ -14,7 +14,10 @@ #include "remote_config/src/desktop/metadata.h" +#include #include +#include +#include #include #include @@ -59,6 +62,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(); @@ -76,7 +82,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 4984282c60fd97d825434c3bc4923f52d0d7f596 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Thu, 4 Jun 2026 10:59:53 -0400 Subject: [PATCH 2/7] 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 ca9249e08d..b729cfabf4 100644 --- a/app/src/variant_util.cc +++ b/app/src/variant_util.cc @@ -250,6 +250,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 b8946309b9..c3e7157af4 100644 --- a/database/src/desktop/persistence/flatbuffer_conversions.cc +++ b/database/src/desktop/persistence/flatbuffer_conversions.cc @@ -103,6 +103,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 44f1fd375e5e5b8c827f86b1d62c0a03761475a5 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Fri, 5 Jun 2026 14:06:16 -0400 Subject: [PATCH 3/7] 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 8f3cfc9fc8..a42ca27851 100644 --- a/app/rest/request_json.h +++ b/app/rest/request_json.h @@ -66,7 +66,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()); From 0d97bdd89d1231bdf3bdab8501eb2abdd9ed140e Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Mon, 8 Jun 2026 14:56:30 -0400 Subject: [PATCH 4/7] Patch flatbuffers to resolve ERROR macro conflict on Windows --- cmake/external/flatbuffers.cmake | 3 ++ .../flatbuffers/0001-fix-error-macro.patch | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 scripts/git/patches/flatbuffers/0001-fix-error-macro.patch diff --git a/cmake/external/flatbuffers.cmake b/cmake/external/flatbuffers.cmake index c79d686db4..c2c8c7e34e 100644 --- a/cmake/external/flatbuffers.cmake +++ b/cmake/external/flatbuffers.cmake @@ -20,6 +20,8 @@ endif() # Commit corresponds to Tag v25.12.19-2026-02-06-03fffb2 set(version 95fda8c23e6e30ebd975892b5fad01efa53e039c) +set(patch_file + ${CMAKE_CURRENT_LIST_DIR}/../../scripts/git/patches/flatbuffers/0001-fix-error-macro.patch) ExternalProject_Add( flatbuffers @@ -28,6 +30,7 @@ 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} PREFIX ${PROJECT_BINARY_DIR} CONFIGURE_COMMAND "" diff --git a/scripts/git/patches/flatbuffers/0001-fix-error-macro.patch b/scripts/git/patches/flatbuffers/0001-fix-error-macro.patch new file mode 100644 index 0000000000..068ed0fdac --- /dev/null +++ b/scripts/git/patches/flatbuffers/0001-fix-error-macro.patch @@ -0,0 +1,35 @@ +From: Antigravity +Subject: Patch flatbuffers to resolve ERROR macro conflict on Windows + +Workaround for conflict between ProtoIdGapAction::ERROR in idl.h and the +Windows global ERROR macro defined in wingdi.h/windows.h. + +See Flatbuffers Issue: https://github.com/google/flatbuffers/issues/8483 + +diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h +index 95fda8c2..6da1c6e3 100644 +--- a/include/flatbuffers/idl.h ++++ b/include/flatbuffers/idl.h +@@ -17,6 +17,12 @@ + #ifndef FLATBUFFERS_IDL_H_ + #define FLATBUFFERS_IDL_H_ + ++#ifdef ERROR ++#pragma push_macro("ERROR") ++#undef ERROR ++#define FLATBUFFERS_POP_ERROR_MACRO ++#endif ++ + #include + #include + #include +@@ -1325,4 +1331,9 @@ extern bool GenerateTSGRPC(const Parser& parser, const std::string& path, + const std::string& file_name); + } // namespace flatbuffers + ++#ifdef FLATBUFFERS_POP_ERROR_MACRO ++#pragma pop_macro("ERROR") ++#undef FLATBUFFERS_POP_ERROR_MACRO ++#endif ++ + #endif // FLATBUFFERS_IDL_H_ From 7519598f1d7240ecede58cf5ded206dd7fa9ef66 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Mon, 8 Jun 2026 16:59:32 -0400 Subject: [PATCH 5/7] Add release notes --- release_build_files/readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/release_build_files/readme.md b/release_build_files/readme.md index da38f4ad68..fe7db62f57 100644 --- a/release_build_files/readme.md +++ b/release_build_files/readme.md @@ -613,6 +613,10 @@ workflow use only during the development of your app, not for publicly shipping code. ## Release Notes +### Upcoming +- Changes + - Remote Config (Desktop): Updated Flatbuffers to latest version to support buffer verification. Added flexbuffer integrity checks before parsing to prevent crashes on invalid/malformed data. + ### 13.8.0 - Changes - General (Android): Update to Firebase Android BoM version 34.14.0. From 6f038ec938ed1dee70b748e8d879a0ff715acf9a Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Mon, 8 Jun 2026 19:58:01 -0400 Subject: [PATCH 6/7] Restore 0001-remove-unused-var.patch for Android flatbuffers v1.12.0 build --- .../flatbuffers/0001-remove-unused-var.patch | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 scripts/git/patches/flatbuffers/0001-remove-unused-var.patch diff --git a/scripts/git/patches/flatbuffers/0001-remove-unused-var.patch b/scripts/git/patches/flatbuffers/0001-remove-unused-var.patch new file mode 100644 index 0000000000..6bd51cbd5c --- /dev/null +++ b/scripts/git/patches/flatbuffers/0001-remove-unused-var.patch @@ -0,0 +1,31 @@ +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 5774ae0aa5e6c2236f3351e0e8d37a35fbfe8081 Mon Sep 17 00:00:00 2001 From: AustinBenoit Date: Tue, 9 Jun 2026 09:46:00 -0400 Subject: [PATCH 7/7] Use cp -RL on Windows to avoid symbolic link creation failure --- build_scripts/android/build.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build_scripts/android/build.sh b/build_scripts/android/build.sh index 0f4d63cb94..e2809a6a55 100755 --- a/build_scripts/android/build.sh +++ b/build_scripts/android/build.sh @@ -81,6 +81,5 @@ if [[ $(uname) == "Linux" ]] || [[ $(uname) == "Darwin" ]]; then else # rsync has to be specifically installed on windows bash (including github runners) # Also, rsync with absolute destination path doesn't work on Windows. - # Using a simple copy instead of rsync on Windows. - cp -R --parents "${paths[@]}" "${absbuildpath}" + cp -RL --parents "${paths[@]}" "${absbuildpath}" fi