Fix use-after-free crash in glfw embedder (#44358)
When setting up the paths to assets and ICU data, we were previously returning the underlying char* data in a temporary string returned by `std::filesystem::path::string()`. Since the return value of `string()` is never stored, there's no guarantee that the underlying data pointer is still valid later in the function. By storing the string in a local whose lifetime exceeds that of the running engine instance, we guarantee the string isn't freed until after the Flutter app terminates.
[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
diff --git a/shell/platform/glfw/flutter_glfw.cc b/shell/platform/glfw/flutter_glfw.cc
index d50871b..55968f0 100644
--- a/shell/platform/glfw/flutter_glfw.cc
+++ b/shell/platform/glfw/flutter_glfw.cc
@@ -12,6 +12,7 @@
#include <cstdlib>
#include <filesystem>
#include <iostream>
+#include <string>
#include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h"
#include "flutter/shell/platform/common/incoming_message_dispatcher.h"
@@ -755,10 +756,12 @@
if (engine_state->window_controller != nullptr) {
config.open_gl.gl_proc_resolver = EngineProcResolver;
}
+ const std::string assets_path_string = assets_path.string();
+ const std::string icu_path_string = icu_path.string();
FlutterProjectArgs args = {};
args.struct_size = sizeof(FlutterProjectArgs);
- args.assets_path = assets_path.string().c_str();
- args.icu_data_path = icu_path.string().c_str();
+ args.assets_path = assets_path_string.c_str();
+ args.icu_data_path = icu_path_string.c_str();
args.command_line_argc = static_cast<int>(argv.size());
args.command_line_argv = &argv[0];
args.platform_message_callback = EngineOnFlutterPlatformMessage;