15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FPL(x) FILE_PATH_LITERAL(x)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(FILE_PATH_USES_DRIVE_LETTERS)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DRIVE FPL("C:")
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DRIVE
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemMountOption;
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::IsolatedContext;
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::kFileSystemTypeDragged;
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::kFileSystemTypeIsolated;
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::kFileSystemTypeNativeLocal;
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace content {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef IsolatedContext::MountPointInfo FileInfo;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath kTestPaths[] = {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("/a/b.txt")),
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("/c/d/e")),
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("/h/")),
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("/")),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("\\foo\\bar")),
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("\\")),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For duplicated base name test.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("/")),
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("/f/e")),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath(DRIVE FPL("/f/b.txt")),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IsolatedContextTest : public testing::Test {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IsolatedContextTest() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kTestPaths); ++i)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fileset_.insert(kTestPaths[i].NormalizePathSeparators());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IsolatedContext::FileInfoSet files;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string name;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_TRUE(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          files.AddPath(kTestPaths[i].NormalizePathSeparators(), &name));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      names_.push_back(name);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id_ = IsolatedContext::GetInstance()->RegisterDraggedFileSystem(files);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IsolatedContext::GetInstance()->AddReference(id_);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(id_.empty());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IsolatedContext::GetInstance()->RemoveReference(id_);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IsolatedContext* isolated_context() const {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return IsolatedContext::GetInstance();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id_;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::multiset<base::FilePath> fileset_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> names_;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(IsolatedContextTest);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IsolatedContextTest, RegisterAndRevokeTest) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See if the returned top-level entries match with what we registered.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<FileInfo> toplevels;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(isolated_context()->GetDraggedFileInfo(id_, &toplevels));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(fileset_.size(), toplevels.size());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < toplevels.size(); ++i) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(fileset_.find(toplevels[i].path) != fileset_.end());
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See if the name of each registered kTestPaths (that is what we
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // register in SetUp() by RegisterDraggedFileSystem) is properly cracked as
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a valid virtual path in the isolated filesystem.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .AppendASCII(names_[i]);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string cracked_id;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath cracked_path;
1056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::string cracked_inner_id;
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType cracked_type;
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    FileSystemMountOption cracked_option;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(isolated_context()->CrackVirtualPath(
1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
1106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        &cracked_path, &cracked_option));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(kTestPaths[i].NormalizePathSeparators().value(),
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              cracked_path.value());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(id_, cracked_id);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(kFileSystemTypeDragged, cracked_type);
1156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_TRUE(cracked_inner_id.empty());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure GetRegisteredPath returns false for id_ since it is
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registered for dragged files.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id_, &path));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deref the current one and registering a new one.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->RemoveReference(id_);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id2 = isolated_context()->RegisterFileSystemForPath(
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kFileSystemTypeNativeLocal, std::string(),
1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::FilePath(DRIVE FPL("/foo")), NULL);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the GetDraggedFileInfo returns false for both ones.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetDraggedFileInfo(id2, &toplevels));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetDraggedFileInfo(id_, &toplevels));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the GetRegisteredPath returns true only for the new one.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id_, &path));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try registering three more file systems for the same path as id2.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id3 = isolated_context()->RegisterFileSystemForPath(
1406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kFileSystemTypeNativeLocal, std::string(), path, NULL);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id4 = isolated_context()->RegisterFileSystemForPath(
1426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kFileSystemTypeNativeLocal, std::string(), path, NULL);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id5 = isolated_context()->RegisterFileSystemForPath(
1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kFileSystemTypeNativeLocal, std::string(), path, NULL);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove file system for id4.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->AddReference(id4);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->RemoveReference(id4);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only id4 should become invalid now.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id3, &path));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path));
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id5, &path));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revoke file system id5, after adding multiple references.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->AddReference(id5);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->AddReference(id5);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->AddReference(id5);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->RevokeFileSystem(id5);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No matter how many references we add id5 must be invalid now.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id3, &path));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id5, &path));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revoke the file systems by path.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  isolated_context()->RevokeFileSystemByPath(path);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now all the file systems associated to the path must be invalid.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id2, &path));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id3, &path));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id5, &path));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IsolatedContextTest, CrackWithRelativePaths) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const struct {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath::StringType path;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool valid;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } relatives[] = {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { FPL("foo"), true },
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { FPL("foo/bar"), true },
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { FPL(".."), false },
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { FPL("foo/.."), false },
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { FPL("foo/../bar"), false },
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define SHOULD_FAIL_WITH_WIN_SEPARATORS false
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define SHOULD_FAIL_WITH_WIN_SEPARATORS true
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { FPL("foo\\..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { FPL("foo/..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < ARRAYSIZE_UNSAFE(relatives); ++j) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SCOPED_TRACE(testing::Message() << "Testing "
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << kTestPaths[i].value() << " " << relatives[j].path);
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::FilePath virtual_path =
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          isolated_context()->CreateVirtualRootPath(id_).AppendASCII(
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              names_[i]).Append(relatives[j].path);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string cracked_id;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath cracked_path;
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemType cracked_type;
2076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      std::string cracked_inner_id;
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileSystemMountOption cracked_option;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!relatives[j].valid) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ASSERT_FALSE(isolated_context()->CrackVirtualPath(
2116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
2126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            &cracked_path, &cracked_option));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(isolated_context()->CrackVirtualPath(
2166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
2176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          &cracked_path, &cracked_option));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(kTestPaths[i].Append(relatives[j].path)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    .NormalizePathSeparators().value(),
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                cracked_path.value());
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(id_, cracked_id);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASSERT_EQ(kFileSystemTypeDragged, cracked_type);
2236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      EXPECT_TRUE(cracked_inner_id.empty());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(IsolatedContextTest, CrackURLWithRelativePaths) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const struct {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath::StringType path;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool valid;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } relatives[] = {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("foo"), true },
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("foo/bar"), true },
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL(".."), false },
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("foo/.."), false },
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("foo/../bar"), false },
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(FILE_PATH_USES_WIN_SEPARATORS)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# define SHOULD_FAIL_WITH_WIN_SEPARATORS false
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# define SHOULD_FAIL_WITH_WIN_SEPARATORS true
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("foo\\..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("foo/..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t j = 0; j < ARRAYSIZE_UNSAFE(relatives); ++j) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SCOPED_TRACE(testing::Message() << "Testing "
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   << kTestPaths[i].value() << " " << relatives[j].path);
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::FilePath virtual_path =
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          isolated_context()->CreateVirtualRootPath(id_).AppendASCII(
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              names_[i]).Append(relatives[j].path);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FileSystemURL cracked = isolated_context()->CreateCrackedFileSystemURL(
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GURL("http://chromium.org"), kFileSystemTypeIsolated, virtual_path);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(relatives[j].valid, cracked.is_valid());
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!relatives[j].valid)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(GURL("http://chromium.org"), cracked.origin());
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(kTestPaths[i].Append(relatives[j].path)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    .NormalizePathSeparators().value(),
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                cracked.path().value());
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(virtual_path.NormalizePathSeparators(), cracked.virtual_path());
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(id_, cracked.filesystem_id());
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(kFileSystemTypeDragged, cracked.type());
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_EQ(kFileSystemTypeIsolated, cracked.mount_type());
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IsolatedContextTest, TestWithVirtualRoot) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cracked_id;
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath cracked_path;
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSystemMountOption cracked_option;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trying to crack virtual root "/" returns true but with empty cracked path
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as "/" of the isolated filesystem is a pure virtual directory
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that has no corresponding platform directory.
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(isolated_context()->CrackVirtualPath(
2846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      virtual_path, &cracked_id, NULL, NULL, &cracked_path, &cracked_option));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(FPL(""), cracked_path.value());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(id_, cracked_id);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trying to crack "/foo" should fail (because "foo" is not the one
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // included in the kTestPaths).
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual_path = isolated_context()->CreateVirtualRootPath(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id_).AppendASCII("foo");
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(isolated_context()->CrackVirtualPath(
2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      virtual_path, &cracked_id, NULL, NULL, &cracked_path, &cracked_option));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(IsolatedContextTest, CanHandleURL) {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL test_origin("http://chromium.org");
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath test_path(FPL("/mount"));
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should handle isolated file system.
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(isolated_context()->HandlesFileSystemMountType(
30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeIsolated));
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Shouldn't handle the rest.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeExternal));
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeTemporary));
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypePersistent));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeTest));
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Not even if it's isolated subtype.
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeNativeLocal));
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeDragged));
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeNativeMedia));
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeDeviceMedia));
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(IsolatedContextTest, VirtualFileSystemTests) {
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Should be able to register empty and non-absolute paths
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string empty_fsid = isolated_context()->RegisterFileSystemForVirtualPath(
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypeIsolated, "_", base::FilePath());
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string relative_fsid =
32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      isolated_context()->RegisterFileSystemForVirtualPath(
33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          storage::kFileSystemTypeIsolated,
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          "_",
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::FilePath(FPL("relpath")));
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_FALSE(empty_fsid.empty());
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_FALSE(relative_fsid.empty());
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Make sure that filesystem root is not prepended to cracked virtual paths.
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FilePath database_root = base::FilePath(DRIVE FPL("/database_path"));
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string database_fsid =
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      isolated_context()->RegisterFileSystemForVirtualPath(
34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          storage::kFileSystemTypeIsolated, "_", database_root);
34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FilePath test_virtual_path =
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::FilePath().AppendASCII("virtualdir").AppendASCII("virtualfile.txt");
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FilePath whole_virtual_path =
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      isolated_context()->CreateVirtualRootPath(database_fsid)
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          .AppendASCII("_").Append(test_virtual_path);
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string cracked_id;
35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FilePath cracked_path;
3516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string cracked_inner_id;
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSystemMountOption cracked_option;
35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(isolated_context()->CrackVirtualPath(
3546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      whole_virtual_path, &cracked_id, NULL, &cracked_inner_id,
3556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      &cracked_path, &cracked_option));
35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(database_fsid, cracked_id);
35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(test_virtual_path, cracked_path);
3586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_TRUE(cracked_inner_id.empty());
35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace content
362