Skip to content

Commit dab06ad

Browse files
committed
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.
1 parent 9ae22e9 commit dab06ad

5 files changed

Lines changed: 44 additions & 41 deletions

File tree

cmake/external/flatbuffers.cmake

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ if(TARGET flatbuffers OR NOT DOWNLOAD_FLATBUFFERS)
1818
return()
1919
endif()
2020

21-
set(version 99aa1ef21dd9dc3f9d4fb0eb82f4b59d0bb5e4c5)
22-
set(patch_file
23-
${CMAKE_CURRENT_LIST_DIR}/../../scripts/git/patches/flatbuffers/0001-remove-unused-var.patch)
21+
# Commit corresponds to Tag v25.12.19-2026-02-06-03fffb2
22+
set(version 95fda8c23e6e30ebd975892b5fad01efa53e039c)
2423

2524
ExternalProject_Add(
2625
flatbuffers
@@ -29,7 +28,6 @@ ExternalProject_Add(
2928
COMMAND git init flatbuffers
3029
COMMAND cd flatbuffers && git fetch --depth=1 https://github.com/google/flatbuffers.git ${version} && git reset --hard FETCH_HEAD
3130

32-
PATCH_COMMAND git apply ${patch_file} && git gc --aggressive
3331
PREFIX ${PROJECT_BINARY_DIR}
3432

3533
CONFIGURE_COMMAND ""

remote_config/src/desktop/config_data.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ std::string NamespacedConfigData::Serialize() const {
4949
void NamespacedConfigData::Deserialize(const std::string& buffer) {
5050
const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.data());
5151
size_t size = buffer.size();
52+
if (!flexbuffers::VerifyBuffer(data, size)) {
53+
return;
54+
}
5255
auto struct_map = flexbuffers::GetRoot(data, size).AsMap();
5356
flexbuffers::Map ns_config_map = struct_map["config_"].AsMap();
5457
for (int i = 0, in = ns_config_map.size(); i < in; ++i) {
@@ -142,6 +145,9 @@ std::string LayeredConfigs::Serialize() const {
142145
void LayeredConfigs::Deserialize(const std::string& buffer) {
143146
const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.data());
144147
size_t size = buffer.size();
148+
if (!flexbuffers::VerifyBuffer(data, size)) {
149+
return;
150+
}
145151
auto struct_map = flexbuffers::GetRoot(data, size).AsMap();
146152
fetched.Deserialize(struct_map["fetched"].AsString().str());
147153
active.Deserialize(struct_map["active"].AsString().str());

remote_config/src/desktop/file_manager.cc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@ namespace internal {
3737
RemoteConfigFileManager::RemoteConfigFileManager(const std::string& filename,
3838
const firebase::App& app) {
3939
std::string app_data_prefix =
40-
std::string(app.options().package_name()) + "/" + app.name();
41-
std::string file_path =
42-
AppDataDir(app_data_prefix.c_str(), /*should_create=*/true) + "/" +
43-
filename;
40+
std::string(app.options().package_name()) + "/remote_config";
41+
std::string error;
42+
std::string app_dir =
43+
AppDataDir(app_data_prefix.c_str(), /*should_create=*/true, &error);
44+
std::string file_path;
45+
if (error.empty() && !app_dir.empty()) {
46+
file_path = app_dir + "/" + app.name() + "_" + filename;
47+
}
4448
#if FIREBASE_PLATFORM_WINDOWS
4549
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> utf8_to_wstring;
4650
file_path_ = utf8_to_wstring.from_bytes(file_path);
@@ -50,16 +54,28 @@ RemoteConfigFileManager::RemoteConfigFileManager(const std::string& filename,
5054
}
5155

5256
bool RemoteConfigFileManager::Load(LayeredConfigs* configs) const {
57+
if (file_path_.empty()) {
58+
return false;
59+
}
5360
std::fstream input(file_path_, std::ios::in | std::ios::binary);
61+
if (!input) {
62+
return false;
63+
}
5464
std::stringstream ss;
5565
ss << input.rdbuf();
5666
configs->Deserialize(ss.str());
5767
return true;
5868
}
5969

6070
bool RemoteConfigFileManager::Save(const LayeredConfigs& configs) const {
71+
if (file_path_.empty()) {
72+
return false;
73+
}
6174
std::string buffer = configs.Serialize();
6275
std::fstream output(file_path_, std::ios::out | std::ios::binary);
76+
if (!output) {
77+
return false;
78+
}
6379
output.write(buffer.c_str(), buffer.size());
6480
return true;
6581
}

remote_config/src/desktop/metadata.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "remote_config/src/desktop/metadata.h"
1616

17+
#include <limits>
1718
#include <map>
1819
#include <string>
1920

@@ -58,6 +59,9 @@ std::string RemoteConfigMetadata::Serialize() const {
5859
void RemoteConfigMetadata::Deserialize(const std::string& buffer) {
5960
const uint8_t* data = reinterpret_cast<const uint8_t*>(buffer.data());
6061
size_t size = buffer.size();
62+
if (!flexbuffers::VerifyBuffer(data, size)) {
63+
return;
64+
}
6165
auto struct_map = flexbuffers::GetRoot(data, size).AsMap();
6266

6367
flexbuffers::Map info = struct_map["info"].AsMap();
@@ -75,7 +79,18 @@ void RemoteConfigMetadata::Deserialize(const std::string& buffer) {
7579
settings_.clear();
7680
flexbuffers::Map settings = struct_map["settings"].AsMap();
7781
for (int i = 0, n = settings.size(); i < n; ++i) {
78-
int int_key = std::stoi(settings.Keys()[i].AsKey());
82+
const char* key_str = settings.Keys()[i].AsKey();
83+
if (!key_str) continue;
84+
char* endptr = nullptr;
85+
long raw_key = std::strtol(key_str, &endptr, 10);
86+
if (endptr == key_str || *endptr != '\0') {
87+
continue;
88+
}
89+
if (raw_key < std::numeric_limits<int>::min() ||
90+
raw_key > std::numeric_limits<int>::max()) {
91+
continue;
92+
}
93+
int int_key = static_cast<int>(raw_key);
7994
settings_[static_cast<ConfigSetting>(int_key)] =
8095
settings.Values()[i].AsString().c_str();
8196
}

scripts/git/patches/flatbuffers/0001-remove-unused-var.patch

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)