Accept file URIs as parameters in the RunInView service RPC (flutter/engine#6191)
See https://github.com/flutter/flutter/issues/21348
This commit is contained in:
@@ -481,6 +481,7 @@ LIBRARY: engine
|
||||
ORIGIN: ../../../flutter/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart + ../../../LICENSE
|
||||
TYPE: LicenseType.bsd
|
||||
FILE: ../../../flutter/flutter_kernel_transformers/lib/track_widget_constructor_locations.dart
|
||||
FILE: ../../../flutter/fml/paths_unittests.cc
|
||||
FILE: ../../../flutter/lib/ui/isolate_name_server.dart
|
||||
FILE: ../../../flutter/lib/ui/painting/image_encoding.cc
|
||||
FILE: ../../../flutter/lib/ui/painting/image_encoding.h
|
||||
|
||||
@@ -166,6 +166,7 @@ executable("fml_unittests") {
|
||||
"memory/weak_ptr_unittest.cc",
|
||||
"message_loop_unittests.cc",
|
||||
"message_unittests.cc",
|
||||
"paths_unittests.cc",
|
||||
"string_view_unittest.cc",
|
||||
"synchronization/thread_annotations_unittest.cc",
|
||||
"synchronization/thread_checker_unittest.cc",
|
||||
|
||||
@@ -29,5 +29,25 @@ std::string JoinPaths(std::initializer_list<std::string> components) {
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::string SanitizeURIEscapedCharacters(const std::string& str) {
|
||||
std::string result;
|
||||
result.reserve(str.size());
|
||||
for (std::string::size_type i = 0; i < str.size(); ++i) {
|
||||
if (str[i] == '%') {
|
||||
if (i > str.size() - 3 || !isxdigit(str[i + 1]) || !isxdigit(str[i + 2]))
|
||||
return "";
|
||||
const std::string hex = str.substr(i + 1, 2);
|
||||
const unsigned char c = strtoul(hex.c_str(), nullptr, 16);
|
||||
if (!c)
|
||||
return "";
|
||||
result += c;
|
||||
i += 2;
|
||||
} else {
|
||||
result += str[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace paths
|
||||
} // namespace fml
|
||||
|
||||
@@ -22,6 +22,12 @@ std::string AbsolutePath(const std::string& path);
|
||||
// Returns the directory name component of the given path.
|
||||
std::string GetDirectoryName(const std::string& path);
|
||||
|
||||
// Decodes a URI encoded string.
|
||||
std::string SanitizeURIEscapedCharacters(const std::string& str);
|
||||
|
||||
// Converts a file URI to a path.
|
||||
std::string FromURI(const std::string& uri);
|
||||
|
||||
} // namespace paths
|
||||
} // namespace fml
|
||||
|
||||
|
||||
17
engine/src/flutter/fml/paths_unittests.cc
Normal file
17
engine/src/flutter/fml/paths_unittests.cc
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "flutter/fml/paths.h"
|
||||
|
||||
TEST(Paths, SanitizeURI) {
|
||||
ASSERT_EQ(fml::paths::SanitizeURIEscapedCharacters("hello"), "hello");
|
||||
ASSERT_EQ(fml::paths::SanitizeURIEscapedCharacters(""), "");
|
||||
ASSERT_EQ(fml::paths::SanitizeURIEscapedCharacters("hello%20world"),
|
||||
"hello world");
|
||||
ASSERT_EQ(fml::paths::SanitizeURIEscapedCharacters(
|
||||
"%5Chello%5cworld%20foo%20bar%21"),
|
||||
"\\hello\\world foo bar!");
|
||||
}
|
||||
@@ -14,6 +14,9 @@ namespace paths {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kFileURLPrefix[] = "file://";
|
||||
constexpr size_t kFileURLPrefixLength = sizeof(kFileURLPrefix) - 1;
|
||||
|
||||
std::string GetCurrentDirectory() {
|
||||
char buffer[PATH_MAX];
|
||||
FML_CHECK(getcwd(buffer, sizeof(buffer)));
|
||||
@@ -44,5 +47,13 @@ std::string GetDirectoryName(const std::string& path) {
|
||||
return path.substr(0, separator);
|
||||
}
|
||||
|
||||
std::string FromURI(const std::string& uri) {
|
||||
if (uri.substr(0, kFileURLPrefixLength) != kFileURLPrefix)
|
||||
return uri;
|
||||
|
||||
std::string file_path = uri.substr(kFileURLPrefixLength);
|
||||
return SanitizeURIEscapedCharacters(file_path);
|
||||
}
|
||||
|
||||
} // namespace paths
|
||||
} // namespace fml
|
||||
} // namespace fml
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "flutter/fml/paths.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "flutter/fml/paths.h"
|
||||
|
||||
@@ -13,6 +14,9 @@ namespace paths {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kFileURLPrefix[] = "file:///";
|
||||
constexpr size_t kFileURLPrefixLength = sizeof(kFileURLPrefix) - 1;
|
||||
|
||||
size_t RootLength(const std::string& path) {
|
||||
if (path.size() == 0)
|
||||
return 0;
|
||||
@@ -77,5 +81,14 @@ std::string GetDirectoryName(const std::string& path) {
|
||||
return path.substr(0, separator);
|
||||
}
|
||||
|
||||
std::string FromURI(const std::string& uri) {
|
||||
if (uri.substr(0, kFileURLPrefixLength) != kFileURLPrefix)
|
||||
return uri;
|
||||
|
||||
std::string file_path = uri.substr(kFileURLPrefixLength);
|
||||
std::replace(file_path.begin(), file_path.end(), '/', '\\');
|
||||
return SanitizeURIEscapedCharacters(file_path);
|
||||
}
|
||||
|
||||
} // namespace paths
|
||||
} // namespace fml
|
||||
|
||||
@@ -865,24 +865,28 @@ bool Shell::OnServiceProtocolRunInView(
|
||||
return false;
|
||||
}
|
||||
|
||||
auto main_script_file =
|
||||
fml::paths::AbsolutePath(params.at("mainScript").ToString());
|
||||
std::string main_script_path =
|
||||
fml::paths::FromURI(params.at("mainScript").ToString());
|
||||
std::string packages_path =
|
||||
fml::paths::FromURI(params.at("packagesFile").ToString());
|
||||
std::string asset_directory_path =
|
||||
fml::paths::FromURI(params.at("assetDirectory").ToString());
|
||||
|
||||
auto main_script_file_mapping =
|
||||
std::make_unique<fml::FileMapping>(main_script_file, false);
|
||||
std::make_unique<fml::FileMapping>(main_script_path, false);
|
||||
|
||||
auto isolate_configuration =
|
||||
blink::DartVM::IsKernelMapping(main_script_file_mapping.get())
|
||||
? IsolateConfiguration::CreateForSnapshot(
|
||||
std::move(main_script_file_mapping))
|
||||
: IsolateConfiguration::CreateForSource(
|
||||
main_script_file, params.at("packagesFile").ToString());
|
||||
: IsolateConfiguration::CreateForSource(main_script_path,
|
||||
packages_path);
|
||||
|
||||
RunConfiguration configuration(std::move(isolate_configuration));
|
||||
|
||||
configuration.AddAssetResolver(std::make_unique<blink::DirectoryAssetBundle>(
|
||||
fml::OpenFile(params.at("assetDirectory").ToString().c_str(),
|
||||
fml::OpenPermission::kRead, true)));
|
||||
configuration.AddAssetResolver(
|
||||
std::make_unique<blink::DirectoryAssetBundle>(fml::OpenFile(
|
||||
asset_directory_path.c_str(), fml::OpenPermission::kRead, true)));
|
||||
|
||||
auto& allocator = response.GetAllocator();
|
||||
response.SetObject();
|
||||
|
||||
Reference in New Issue
Block a user