0

Allow content-URIs in IsolatedContext, fixes webkitGetAsEntry()

Drag-drop support for files in android was recently added, however
DataTransferItem.webkitGetAsEntry() is failing.

The failure is because files are not getting registered correct
with IsolatedContext which currently checks path.IsAbsolutePath()
which returns false for a content-URI path such as
content://authority/path.

This fixes the validation to allow content-URIs.

Change-Id: I42282c3dde18f6d4e49731eb700cdf37d9398f3f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6370628
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1435869}
This commit is contained in:
Joel Hockey
2025-03-20 22:41:58 -07:00
committed by Chromium LUCI CQ
parent 50d8bd23d8
commit c847a2385b
2 changed files with 45 additions and 5 deletions

@ -26,6 +26,16 @@ namespace storage {
namespace {
// The given path should not contain any '..' and should be absolute.
bool IsPathValid(const base::FilePath& path) {
#if BUILDFLAG(IS_ANDROID)
if (path.IsContentUri()) {
return true;
}
#endif
return !path.ReferencesParent() && path.IsAbsolute();
}
base::FilePath::StringType GetRegisterNameForPath(const base::FilePath& path) {
// If it's not a root path simply return a base name.
if (path.DirName() != path)
@ -65,9 +75,9 @@ IsolatedContext::FileInfoSet::~FileInfoSet() = default;
bool IsolatedContext::FileInfoSet::AddPath(const base::FilePath& path,
std::string* registered_name) {
// The given path should not contain any '..' and should be absolute.
if (path.ReferencesParent() || !path.IsAbsolute())
if (!IsPathValid(path)) {
return false;
}
base::FilePath::StringType name = GetRegisterNameForPath(path);
std::string utf8name = base::FilePath(name).AsUTF8Unsafe();
base::FilePath normalized_path = path.NormalizePathSeparators();
@ -94,9 +104,9 @@ bool IsolatedContext::FileInfoSet::AddPath(const base::FilePath& path,
bool IsolatedContext::FileInfoSet::AddPathWithName(const base::FilePath& path,
const std::string& name) {
// The given path should not contain any '..' and should be absolute.
if (path.ReferencesParent() || !path.IsAbsolute())
if (!IsPathValid(path)) {
return false;
}
return fileset_.insert(MountPointInfo(name, path.NormalizePathSeparators()))
.second;
}
@ -274,8 +284,9 @@ IsolatedContext::ScopedFSHandle IsolatedContext::RegisterFileSystemForPath(
const base::FilePath& path_in,
std::string* register_name) {
base::FilePath path(path_in.NormalizePathSeparators());
if (path.ReferencesParent() || !path.IsAbsolute())
if (!IsPathValid(path)) {
return ScopedFSHandle();
}
std::string name;
if (register_name && !register_name->empty()) {
name = *register_name;

@ -174,6 +174,35 @@ TEST_F(IsolatedContextTest, RegisterAndRevokeTest) {
ASSERT_FALSE(isolated_context()->GetRegisteredPath(fs5.id(), &path));
}
TEST_F(IsolatedContextTest, IsPathValid) {
struct {
base::FilePath::StringViewType path;
bool expected;
} cases[]{
{DRIVE FPL("/foo"), true},
{DRIVE FPL("foo"), false},
{DRIVE FPL("/foo/../bar"), false},
#if BUILDFLAG(IS_ANDROID)
{FPL("content://authority/path"), true},
#else
{FPL("content://authority/path"), false},
#endif
};
for (const auto& tc : cases) {
base::FilePath path(tc.path);
IsolatedContext::FileInfoSet files;
std::string name;
EXPECT_EQ(tc.expected, files.AddPath(path, &name));
EXPECT_EQ(tc.expected, files.AddPathWithName(path, "name"));
IsolatedContext::ScopedFSHandle fs =
isolated_context()->RegisterFileSystemForPath(
kFileSystemTypeLocal, std::string(), path, nullptr);
EXPECT_EQ(tc.expected, fs.is_valid());
}
}
TEST_F(IsolatedContextTest, CrackWithRelativePaths) {
struct Relatives {
base::FilePath::StringType path;