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:
Jason Simmons
2018-09-07 09:34:45 -07:00
committed by GitHub
parent 9cc0b111ed
commit 5ecda4b710
8 changed files with 82 additions and 9 deletions

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View 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!");
}

View File

@@ -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

View File

@@ -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

View File

@@ -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();