Commit aabb907b authored by Kevin Marshall's avatar Kevin Marshall Committed by Commit Bot

[web_engine] Fix leading slash issue with ContentDirectoryProvider.

The use of leading slashes causes path validation issues in VFS
implementations like vfs::PseudoDir.

This fixes the issue by discarding the leading slash from the path
component of requested URLs.

Adds a browser test which validates the use of PseudoDir and VfsFile
with ContentDirectoryProvider.

Bug: 1011180
Change-Id: I2b47ad35023be73cc32538f83b166ebaa9b85f9f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1848411
Commit-Queue: Kevin Marshall <kmarshall@chromium.org>
Reviewed-by: default avatarDavid Dorwin <ddorwin@chromium.org>
Auto-Submit: Kevin Marshall <kmarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704829}
parent 59c589d6
......@@ -3,14 +3,18 @@
// found in the LICENSE file.
#include <lib/fdio/directory.h>
#include <lib/vfs/cpp/pseudo_dir.h>
#include <lib/vfs/cpp/vmo_file.h>
#include "fuchsia/engine/test/web_engine_browser_test.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/path_service.h"
#include "base/test/bind_test_util.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_restrictions.h"
#include "fuchsia/base/frame_test_util.h"
#include "fuchsia/base/test_navigation_listener.h"
#include "fuchsia/engine/browser/content_directory_loader_factory.h"
......@@ -147,6 +151,53 @@ IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ImgSubresource) {
navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "image fetched");
}
// Reads content sourced from VFS PseudoDirs and VmoFiles.
IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, FromVfsPseudoDir) {
base::ScopedAllowBlockingForTesting allow_block;
// Get the file contents and store it in a VMO.
std::string contents;
base::FilePath pkg_path;
base::PathService::Get(base::DIR_ASSETS, &pkg_path);
ASSERT_TRUE(base::ReadFileToString(
pkg_path.AppendASCII("fuchsia/engine/test/data/title1.html"), &contents));
zx::vmo contents_vmo;
zx_status_t status = zx::vmo::create(contents.size(), 0, &contents_vmo);
ASSERT_EQ(status, ZX_OK);
status = contents_vmo.write(contents.data(), 0, contents.size());
ASSERT_EQ(status, ZX_OK);
// Build up the directory structure of a VmoFile inside a PseudoDir.
auto vmo_file = std::make_unique<vfs::VmoFile>(
std::move(contents_vmo), 0, contents.size(),
vfs::VmoFile::WriteOption::READ_ONLY, vfs::VmoFile::Sharing::CLONE_COW);
vfs::PseudoDir pseudo_dir;
status = pseudo_dir.AddEntry("title1.html", std::move(vmo_file));
ASSERT_EQ(status, ZX_OK);
// Serve the PseudoDir under the "pseudo-dir" URL.
fuchsia::web::ContentDirectoryProvider provider;
provider.set_name("pseudo-dir");
fidl::InterfaceHandle<fuchsia::io::Directory> directory_channel;
pseudo_dir.Serve(
fuchsia::io::OPEN_FLAG_DIRECTORY | fuchsia::io::OPEN_RIGHT_READABLE,
directory_channel.NewRequest().TakeChannel());
provider.set_directory(std::move(directory_channel));
std::vector<fuchsia::web::ContentDirectoryProvider> providers;
providers.emplace_back(std::move(provider));
ContentDirectoryLoaderFactory::SetContentDirectoriesForTest(
std::move(providers));
// Access the VmoFile under the PseudoDir.
const GURL kUrl("fuchsia-dir://pseudo-dir/title1.html");
fuchsia::web::FramePtr frame = CreateFrame();
fuchsia::web::NavigationControllerPtr controller;
frame->GetNavigationController(controller.NewRequest());
EXPECT_TRUE(cr_fuchsia::LoadUrlAndExpectResponse(
controller.get(), fuchsia::web::LoadUrlParams(), kUrl.spec()));
navigation_listener_.RunUntilUrlAndTitleEquals(kUrl, "title 1");
}
// Verify that resource providers are origin-isolated.
IN_PROC_BROWSER_TEST_F(ContentDirectoryTest, ScriptSrcCrossOriginBlocked) {
const GURL kUrl("fuchsia-dir://testdata/cross_origin_include_script.html");
......
......@@ -335,10 +335,23 @@ void ContentDirectoryLoaderFactory::CreateLoaderAndStart(
return;
}
std::string requested_path = request.url.path();
if (requested_path.empty()) {
client->OnComplete(
network::URLLoaderCompletionStatus(net::ERR_INVALID_URL));
return;
}
// Not all VFS implementations handle leading slashes in the same way, so
// remove it for maximum compatibility.
// TODO(fxb/38339): Update this comment when issue is resolved.
if (requested_path[0] == '/')
requested_path = requested_path.substr(1, requested_path.size() - 1);
fidl::InterfaceHandle<fuchsia::io::Node> file_handle;
net::Error open_result = OpenFileFromDirectory(
request.url.GetOrigin().host(), base::FilePath(request.url.path()),
file_handle.NewRequest());
net::Error open_result = OpenFileFromDirectory(request.url.GetOrigin().host(),
base::FilePath(requested_path),
file_handle.NewRequest());
if (open_result != net::OK) {
client->OnComplete(network::URLLoaderCompletionStatus(open_result));
return;
......@@ -351,7 +364,7 @@ void ContentDirectoryLoaderFactory::CreateLoaderAndStart(
fidl::InterfaceHandle<fuchsia::io::Node> metadata_handle;
open_result =
OpenFileFromDirectory(request.url.GetOrigin().host(),
base::FilePath(request.url.path() + "._metadata"),
base::FilePath(requested_path + "._metadata"),
metadata_handle.NewRequest());
if (open_result != net::OK) {
client->OnComplete(network::URLLoaderCompletionStatus(open_result));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment