diff options
-rw-r--r-- | base/file_path.cc | 71 | ||||
-rw-r--r-- | base/file_path.h | 12 | ||||
-rw-r--r-- | base/file_path_unittest.cc | 96 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_file_util.cc | 10 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service_unittest.cc | 12 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/user_script_master.cc | 7 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 6 | ||||
-rw-r--r-- | chrome/common/extensions/extension_resource.cc | 72 | ||||
-rw-r--r-- | chrome/common/extensions/extension_resource.h | 11 | ||||
-rw-r--r-- | chrome/common/extensions/user_script.h | 22 | ||||
-rw-r--r-- | chrome/common/extensions/user_script_unittest.cc | 12 |
12 files changed, 247 insertions, 86 deletions
diff --git a/base/file_path.cc b/base/file_path.cc index 1d90674..2152187 100644 --- a/base/file_path.cc +++ b/base/file_path.cc @@ -158,6 +158,75 @@ bool FilePath::operator!=(const FilePath& that) const { #endif // defined(FILE_PATH_USES_DRIVE_LETTERS) } +bool FilePath::AppendAndResolveRelative(const FilePath& relative_path, + FilePath* path) const { + DCHECK(path); + if (!path || relative_path.IsAbsolute()) + return false; + + FilePath full_path = Append(relative_path); + // Is it worth looking for parent references? + if (!full_path.ReferencesParent()) { + *path = full_path; + return true; + } + + // If the parent has a drive letter, then we must not remove the first + // component, which is the drive letter. + bool drive_letter = (FindDriveLetter(full_path.path_) != + FilePath::StringType::npos); + + std::vector<FilePath::StringType> components; + full_path.GetComponents(&components); + std::vector<FilePath::StringType>::iterator it = components.begin(); + // Start by removing any kCurrentDirectory component, since they may + // fool us into not going back to the appropriate parent level. + for (; it != components.end(); ++it) { + if (*it == kCurrentDirectory) { + // erase returns an iterator to the next component. + it = components.erase(it); + // So now, go back to previous iterator, + // so that we can appropriately process the next one as we loop. + --it; + } + } + + // Now parse the component looking for kParentDirectory and remove them as + // well as the previous component. + it = components.begin(); + for (; it != components.end(); ++it) { + if (*it == kParentDirectory) { + // Did we reach the beginning? + if (it == components.begin() || + (drive_letter && (it - 1) == components.begin())) { + return false; + } + // Remove the previous component, as well as the current one. + std::vector<FilePath::StringType>::iterator previous = it - 1; + // Unless the previous is at the beginning. + if (previous == components.begin() || + (drive_letter && (previous - 1) == components.begin())) { + return false; + } + // vector::erase doesn't erase _Last, it erases [_First, _Last[, + // so we must increment current which we want erased. + it = components.erase(previous, it + 1); + // And go back to previous so that we can process the next one as we loop. + --it; + } + } + + // Now reconstruct the path with the components that were left in. + it = components.begin(); + // We start with the first component, in case it is absolute + // and absolute paths can't be appended. + *path = FilePath(*it); + for (++it; it != components.end(); ++it) + *path = path->Append(*it); + + return true; +} + bool FilePath::IsParent(const FilePath& child) const { return AppendRelativePath(child, NULL); } @@ -388,11 +457,9 @@ FilePath FilePath::Append(const StringType& component) const { // directory) or if the path component is empty (indicating nothing to // append). if (component.length() > 0 && new_path.path_.length() > 0) { - // Don't append a separator if the path still ends with a trailing // separator after stripping (indicating the root directory). if (!IsSeparator(new_path.path_[new_path.path_.length() - 1])) { - // Don't append a separator if the path is just a drive letter. if (FindDriveLetter(new_path.path_) + 1 != new_path.path_.length()) { new_path.path_.append(1, kSeparators[0]); diff --git a/base/file_path.h b/base/file_path.h index 7106c90b..5c8f183 100644 --- a/base/file_path.h +++ b/base/file_path.h @@ -178,6 +178,18 @@ class FilePath { // and BaseName().value() on each child component. void GetComponents(std::vector<FilePath::StringType>* components) const; + // Returns true, and sets *path to resulting full path, if relative_path can + // be applied to current path by resolving any '..' it may contain. Returns + // false otherwise, e.g., if relative path is absolute, or if it climbs back + // up the hierarchy too far (i.e., beyond the root of current path). + // + // Note that if the current path ends with a file name, we won't try to + // figure it out (so this method doesn't go to the disk) and we will blindly + // append relative_path at the end of the current path, including the file + // name in the current path (if any). + bool AppendAndResolveRelative(const FilePath& relative_path, + FilePath* path) const; + // Returns true if this FilePath is a strict parent of the |child|. Absolute // and relative paths are accepted i.e. is /foo parent to /foo/bar and // is foo parent to foo/bar. Does not convert paths to absolute, follow diff --git a/base/file_path_unittest.cc b/base/file_path_unittest.cc index b80d9fc..9d45170 100644 --- a/base/file_path_unittest.cc +++ b/base/file_path_unittest.cc @@ -497,6 +497,98 @@ TEST_F(FilePathTest, PathComponentsTest) { } } +TEST_F(FilePathTest, AppendAndResolveRelativeTest) { + const struct BinaryTestData cases[] = { +#if defined(FILE_PATH_USES_DRIVE_LETTERS) + { { FPL("c:/"), FPL("foo") }, FPL("c:/foo") }, + { { FPL("f:/foo/bar"), FPL("..") }, FPL("f:/foo") }, + { { FPL("f:/foo.bar"), FPL("..") }, FPL("f:/") }, + { { FPL("F:/foo/.."), FPL("./bar/.") }, FPL("F:/bar") }, + { { FPL("E:/Foo/bar"), FPL("../..") }, FPL("E:/") }, + { { FPL("E:/Foo/bar/."), FPL("../..") }, FPL("E:/") }, + { { FPL("e:/foo/.."), FPL("bar/..") }, FPL("e:/") }, + { { FPL("c:/foo/./bar/.."), FPL("../baz") }, FPL("c:/baz") }, + { { FPL("E:/./foo/bar/.."), FPL("../baz/..") }, FPL("E:/") }, + { { FPL("x:/foo/../bar/.."), FPL("baz/../boo") }, FPL("x:/boo") }, + { { FPL("E:/foo.bar/.."), FPL("../baz/..") }, FPL("") }, + { { FPL("Z:/foo"), FPL("../..") }, FPL("") }, + { { FPL("y:/"), FPL("..") }, FPL("") }, + { { FPL("B:/.."), FPL("bar/.") }, FPL("") }, + { { FPL("a:/foo/.."), FPL("..") }, FPL("") }, + { { FPL("r:/.."), FPL("..") }, FPL("") }, + { { FPL("F:/foo/.."), FPL("../..") }, FPL("") }, + { { FPL("O:/foo/bar/.."), FPL("../..") }, FPL("") }, +#endif // FILE_PATH_USES_DRIVE_LETTERS +#if defined(FILE_PATH_USES_WIN_SEPARATORS) + { { FPL("\\\\"), FPL("foo") }, FPL("\\\\foo") }, + { { FPL("\\\\foo"), FPL("bar") }, FPL("\\\\foo\\bar") }, + { { FPL("\\\\foo\\bar"), FPL("..") }, FPL("\\\\foo") }, + { { FPL("\\\\foo.bar"), FPL("..") }, FPL("\\\\") }, + { { FPL("\\\\Foo\\bar"), FPL("..\\..") }, FPL("\\\\") }, + { { FPL("\\\\Foo\\bar\\."), FPL("..\\..") }, FPL("\\\\") }, + { { FPL("\\\\foo\\bar"), FPL("foo\\..\\baz") }, FPL("\\\\foo\\bar\\baz") }, + { { FPL("\\\\foo\\.\\bar"), FPL("..\\baz\\.") }, FPL("\\\\foo\\baz") }, + { { FPL("\\\\.\\foo\\.."), FPL("bar") }, FPL("\\\\bar") }, + { { FPL("\\\\foo\\.."), FPL(".\\bar\\..") }, FPL("\\\\") }, + { { FPL("\\\\foo\\bar\\.."), FPL("..\\baz") }, FPL("\\\\baz") }, + { { FPL("\\\\foo\\bar\\.."), FPL("..\\baz\\..") }, FPL("\\\\") }, + { { FPL("\\\\foo\\..\\bar\\.."), FPL("baz\\..\\boo") }, FPL("\\\\boo"), }, + { { FPL("\\\\foo.bar\\.."), FPL("..\\baz\\..") }, FPL("") }, + { { FPL("\\\\foo"), FPL("..\\..") }, FPL("") }, + { { FPL("\\\\"), FPL("..") }, FPL("") }, + { { FPL("\\\\.."), FPL("bar\\.") }, FPL("") }, + { { FPL("\\\\foo\\.."), FPL("..") }, FPL("") }, + { { FPL("\\\\.."), FPL("..") }, FPL("") }, + { { FPL("\\\\foo\\.."), FPL("..\\..") }, FPL("") }, + { { FPL("\\\\foo\\bar\\.."), FPL("..\\..") }, FPL("") }, +#if defined(FILE_PATH_USES_DRIVE_LETTERS) + { { FPL("E:/foo"), FPL("bar") }, FPL("E:/foo\\bar") }, + { { FPL("C:/foo/bar"), FPL("foo/../baz") }, FPL("C:/foo\\bar\\baz") }, + { { FPL("e:/foo/bar"), FPL("../baz") }, FPL("e:/foo\\baz") }, +#endif +#else // FILE_PATH_USES_WIN_SEPARAORS + { { FPL("/"), FPL("foo") }, FPL("/foo") }, + { { FPL("/foo"), FPL("bar") }, FPL("/foo/bar") }, + { { FPL("/foo/bar/"), FPL("..") }, FPL("/foo") }, + { { FPL("/foo.bar"), FPL("..") }, FPL("/") }, + { { FPL("//foo"), FPL("..") }, FPL("//") }, + { { FPL("/foo/./bar"), FPL("../..") }, FPL("/") }, + { { FPL("/foo/bar/."), FPL("foo/../baz") }, FPL("/foo/bar/baz") }, + { { FPL("/./foo/bar"), FPL("../baz/.") }, FPL("/foo/baz") }, + { { FPL("/foo/.."), FPL("./bar") }, FPL("/bar") }, + { { FPL("/foo/.."), FPL("bar/..") }, FPL("/") }, + { { FPL("//foo/bar/.."), FPL("../baz") }, FPL("//baz") }, + { { FPL("/foo/bar/.."), FPL("../baz/..") }, FPL("/") }, + { { FPL("/foo/../bar/.."), FPL("baz/../boo") }, FPL("/boo") }, + { { FPL("//foo.bar/.."), FPL("../baz") }, FPL("") }, + { { FPL("/foo"), FPL("../..") }, FPL("") }, + { { FPL("//"), FPL("..") }, FPL("") }, + { { FPL("/.."), FPL("./bar") }, FPL("") }, + { { FPL("/foo/.."), FPL("..") }, FPL("") }, + { { FPL("/.."), FPL("..") }, FPL("") }, + { { FPL("/foo/.."), FPL("../..") }, FPL("") }, + { { FPL("/foo/bar/.."), FPL("../..") }, FPL("") }, +#if defined(FILE_PATH_USES_DRIVE_LETTERS) + { { FPL("E:/foo"), FPL("bar") }, FPL("E:/foo/bar") }, + { { FPL("C:/foo/bar"), FPL("foo/../baz") }, FPL("C:/foo/bar/baz") }, + { { FPL("e:/foo/bar"), FPL("../baz") }, FPL("e:/foo/baz") }, +#endif +#endif // FILE_PATH_USES_WIN_SEPARAORS + }; + + for (size_t i = 0; i < arraysize(cases); ++i) { + FilePath parent(cases[i].inputs[0]); + FilePath child(cases[i].inputs[1]); + + FilePath result; + EXPECT_EQ(cases[i].expected[0] != '\0', + parent.AppendAndResolveRelative(child, &result)) << + "i: " << i << ", parent: " << parent.value() << ", child: " << + child.value(); + EXPECT_STREQ(cases[i].expected, result.value().c_str()); + } +} + TEST_F(FilePathTest, IsParentTest) { const struct BinaryBooleanTestData cases[] = { { { FPL("/"), FPL("/foo/bar/baz") }, true}, @@ -544,8 +636,8 @@ TEST_F(FilePathTest, IsParentTest) { FilePath child(cases[i].inputs[1]); EXPECT_EQ(parent.IsParent(child), cases[i].expected) << - "i: " << i << ", parent: " << parent.value() << ", child: " << - child.value(); + "i: " << i << ", parent: " << parent.value() << ", child: " << + child.value(); } } diff --git a/chrome/browser/extensions/extension_file_util.cc b/chrome/browser/extensions/extension_file_util.cc index e5b0f85..0bd9507 100644 --- a/chrome/browser/extensions/extension_file_util.cc +++ b/chrome/browser/extensions/extension_file_util.cc @@ -184,8 +184,9 @@ bool ValidateExtension(Extension* extension, std::string* error) { const UserScript& script = extension->content_scripts()[i]; for (size_t j = 0; j < script.js_scripts().size(); j++) { - const FilePath& path = - script.js_scripts()[j].resource().GetFilePath(); + const UserScript::File& js_script = script.js_scripts()[j]; + const FilePath& path = ExtensionResource::GetFilePath( + js_script.extension_root(), js_script.relative_path()); if (path.empty()) { *error = StringPrintf("Could not load '%s' for content script.", WideToUTF8(path.ToWStringHack()).c_str()); @@ -194,8 +195,9 @@ bool ValidateExtension(Extension* extension, std::string* error) { } for (size_t j = 0; j < script.css_scripts().size(); j++) { - const FilePath& path = - script.css_scripts()[j].resource().GetFilePath(); + const UserScript::File& css_script = script.css_scripts()[j]; + const FilePath& path = ExtensionResource::GetFilePath( + css_script.extension_root(), css_script.relative_path()); if (path.empty()) { *error = StringPrintf("Could not load '%s' for content script.", WideToUTF8(path.ToWStringHack()).c_str()); diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index f1a1ede..afadd3c 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -540,14 +540,20 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) { EXPECT_EQ("https://*.google.com/*", scripts[0].url_patterns()[2].GetAsString()); EXPECT_EQ(2u, scripts[0].js_scripts().size()); - EXPECT_TRUE(scripts[0].js_scripts()[0].resource().ComparePathWithDefault( + ExtensionResource resource00(scripts[0].js_scripts()[0].extension_root(), + scripts[0].js_scripts()[0].relative_path()); + EXPECT_TRUE(resource00.ComparePathWithDefault( extension->path().AppendASCII("script1.js"))); - EXPECT_TRUE(scripts[0].js_scripts()[1].resource().ComparePathWithDefault( + ExtensionResource resource01(scripts[0].js_scripts()[1].extension_root(), + scripts[0].js_scripts()[1].relative_path()); + EXPECT_TRUE(resource01.ComparePathWithDefault( extension->path().AppendASCII("script2.js"))); EXPECT_TRUE(extension->plugins().empty()); EXPECT_EQ(1u, scripts[1].url_patterns().size()); EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString()); - EXPECT_TRUE(scripts[1].js_scripts()[0].resource().ComparePathWithDefault( + ExtensionResource resource10(scripts[1].js_scripts()[0].extension_root(), + scripts[1].js_scripts()[0].relative_path()); + EXPECT_TRUE(resource10.ComparePathWithDefault( extension->path().AppendASCII("js_files").AppendASCII("script3.js"))); const std::vector<URLPattern> permissions = extension->host_permissions(); ASSERT_EQ(2u, permissions.size()); diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc index 752a47d..d85d654 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -379,7 +379,7 @@ static void CreateScriptFileDetailValue( // TODO(cira): this information is not used on extension page yet. We // may want to display actual resource that got loaded, not default. list->Append( - new StringValue(file.resource().relative_path().value())); + new StringValue(file.relative_path().value())); } script_data->Set(key, list); } diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc index f58a9e6..024de80 100644 --- a/chrome/browser/extensions/user_script_master.cc +++ b/chrome/browser/extensions/user_script_master.cc @@ -136,7 +136,8 @@ void UserScriptMaster::ScriptReloader::NotifyMaster( static bool LoadScriptContent(UserScript::File* script_file) { std::string content; - FilePath path = script_file->resource().GetFilePath(); + const FilePath& path = ExtensionResource::GetFilePath( + script_file->extension_root(), script_file->relative_path()); if (path.empty() || !file_util::ReadFileToString(path, &content)) { LOG(WARNING) << "Failed to load user script file: " << path.value(); return false; @@ -168,8 +169,8 @@ void UserScriptMaster::ScriptReloader::LoadScriptsFromDirectory( // Push single js file in this UserScript. GURL url(std::string(chrome::kUserScriptScheme) + ":/" + net::FilePathToFileURL(file).ExtractFileName()); - ExtensionResource resource(script_dir, file.BaseName()); - user_script.js_scripts().push_back(UserScript::File(resource, url)); + user_script.js_scripts().push_back(UserScript::File( + script_dir, file.BaseName(), url)); UserScript::File& script_file = user_script.js_scripts().back(); if (!LoadScriptContent(&script_file)) result->pop_back(); diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index a7354b1..e6e5e14 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -271,7 +271,8 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, // TODO(georged): Make GetResourceURL accept wstring too GURL url = GetResourceURL(WideToUTF8(relative)); ExtensionResource resource = GetResource(WideToUTF8(relative)); - result->js_scripts().push_back(UserScript::File(resource, url)); + result->js_scripts().push_back(UserScript::File( + resource.extension_root(), resource.relative_path(), url)); } } @@ -288,7 +289,8 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, // TODO(georged): Make GetResourceURL accept wstring too GURL url = GetResourceURL(WideToUTF8(relative)); ExtensionResource resource = GetResource(WideToUTF8(relative)); - result->css_scripts().push_back(UserScript::File(resource, url)); + result->css_scripts().push_back(UserScript::File( + resource.extension_root(), resource.relative_path(), url)); } } diff --git a/chrome/common/extensions/extension_resource.cc b/chrome/common/extensions/extension_resource.cc index 4ae2b0e..b3275cb 100644 --- a/chrome/common/extensions/extension_resource.cc +++ b/chrome/common/extensions/extension_resource.cc @@ -21,66 +21,39 @@ ExtensionResource::ExtensionResource(const FilePath& extension_root, } const FilePath& ExtensionResource::GetFilePath() const { - if (extension_root_.empty() || relative_path_.empty()) + if (extension_root_.empty() || relative_path_.empty()) { + DCHECK(full_resource_path_.empty()); return full_resource_path_; + } // We've already checked, just return last value. if (!full_resource_path_.empty()) return full_resource_path_; + full_resource_path_ = GetFilePath(extension_root_, relative_path_); + return full_resource_path_; +} + +// Static version... +FilePath ExtensionResource::GetFilePath(const FilePath& extension_root, + const FilePath& relative_path) { // Stat l10n file, and return new path if it exists. FilePath l10n_relative_path = - extension_l10n_util::GetL10nRelativePath(relative_path_); - full_resource_path_ = CombinePathsSafely(extension_root_, l10n_relative_path); - if (file_util::PathExists(full_resource_path_)) { - return full_resource_path_; + extension_l10n_util::GetL10nRelativePath(relative_path); + FilePath full_path; + if (extension_root.AppendAndResolveRelative(l10n_relative_path, &full_path) && + extension_root.IsParent(full_path) && + file_util::PathExists(full_path)) { + return full_path; } // Fall back to root resource. - full_resource_path_ = CombinePathsSafely(extension_root_, relative_path_); - return full_resource_path_; -} - -FilePath ExtensionResource::CombinePathsSafely( - const FilePath& extension_path, - const FilePath& relative_resource_path) const { - // Build up a file:// URL and convert that back to a FilePath. This avoids - // URL encoding and path separator issues. - - // Convert the extension's root to a file:// URL. - GURL extension_url = net::FilePathToFileURL(extension_path); - if (!extension_url.is_valid()) - return FilePath(); - - // Append the requested path. - std::string relative_path = - WideToUTF8(relative_resource_path.ToWStringHack()); - GURL::Replacements replacements; - std::string new_path(extension_url.path()); - new_path += "/"; - new_path += relative_path; - replacements.SetPathStr(new_path); - GURL file_url = extension_url.ReplaceComponents(replacements); - if (!file_url.is_valid()) - return FilePath(); - - // Convert the result back to a FilePath. - FilePath ret_val; - if (!net::FileURLToFilePath(file_url, &ret_val)) - return FilePath(); - - // Converting the extension_url back to a path removes all .. and . references - // that may have been in extension_path that would cause isParent to break. - FilePath sanitized_extension_path; - if (!net::FileURLToFilePath(extension_url, &sanitized_extension_path)) - return FilePath(); - - // Double-check that the path we ended up with is actually inside the - // extension root. - if (!sanitized_extension_path.IsParent(ret_val)) - return FilePath(); + if (extension_root.AppendAndResolveRelative(relative_path, &full_path) && + extension_root.IsParent(full_path)) { + return full_path; + } - return ret_val; + return FilePath(); } // Unittesting helpers. @@ -97,6 +70,9 @@ FilePath::StringType ExtensionResource::NormalizeSeperators( } bool ExtensionResource::ComparePathWithDefault(const FilePath& path) const { + // Make sure we have a cached value to test against... + if (full_resource_path_.empty()) + GetFilePath(); if (NormalizeSeperators(path.value()) == NormalizeSeperators(full_resource_path_.value())) { return true; diff --git a/chrome/common/extensions/extension_resource.h b/chrome/common/extensions/extension_resource.h index 7d6e70c6..0356bec 100644 --- a/chrome/common/extensions/extension_resource.h +++ b/chrome/common/extensions/extension_resource.h @@ -22,6 +22,12 @@ class ExtensionResource { // *** MIGHT HIT FILESYSTEM. Do not call on UI thread! *** const FilePath& GetFilePath() const; + // Static version to avoid creating an instance of ExtensionResource + // when all we want is the localization code. + // *** MIGHT HIT FILESYSTEM. Do not call on UI thread! *** + static FilePath GetFilePath(const FilePath& extension_root, + const FilePath& relative_path); + // Getters const FilePath& extension_root() const { return extension_root_; } const FilePath& relative_path() const { return relative_path_; } @@ -31,11 +37,6 @@ class ExtensionResource { bool ComparePathWithDefault(const FilePath& path) const; private: - // Returns normalized full path to the resource. - // Resource doesn't have to exist. - FilePath CombinePathsSafely(const FilePath& extension_root, - const FilePath& relative_path) const; - // Extension root. FilePath extension_root_; diff --git a/chrome/common/extensions/user_script.h b/chrome/common/extensions/user_script.h index 30807e8..28b3aae 100644 --- a/chrome/common/extensions/user_script.h +++ b/chrome/common/extensions/user_script.h @@ -35,16 +35,16 @@ class UserScript { // Holds actual script file info. class File { public: - File(const ExtensionResource& resource, const GURL& url): - resource_(resource), - url_(url) { + File(const FilePath& extension_root, const FilePath& relative_path, + const GURL& url): + extension_root_(extension_root), + relative_path_(relative_path), + url_(url) { } File() {} - const ExtensionResource& resource() const { return resource_; } - void set_resource(const ExtensionResource& resource) { - resource_ = resource; - } + const FilePath& extension_root() const { return extension_root_; } + const FilePath& relative_path() const { return relative_path_; } const GURL& url() const { return url_; } void set_url(const GURL& url) { url_ = url; } @@ -64,14 +64,16 @@ class UserScript { content_.assign(content.begin(), content.end()); } - // Serialization support. The content and resource_ member will not be + // Serialization support. The content and FilePath members will not be // serialized! void Pickle(::Pickle* pickle) const; void Unpickle(const ::Pickle& pickle, void** iter); private: - // Where the script file lives on the disk. - ExtensionResource resource_; + // Where the script file lives on the disk. We keep the path split so that + // it can be localized at will. + FilePath extension_root_; + FilePath relative_path_; // The url to this scipt file. GURL url_; diff --git a/chrome/common/extensions/user_script_unittest.cc b/chrome/common/extensions/user_script_unittest.cc index 0c0bac9..b171f4e 100644 --- a/chrome/common/extensions/user_script_unittest.cc +++ b/chrome/common/extensions/user_script_unittest.cc @@ -78,16 +78,16 @@ TEST(UserScriptTest, Pickle) { UserScript script1; script1.js_scripts().push_back(UserScript::File( - ExtensionResource(FilePath(FILE_PATH_LITERAL("c:\\foo\\")), - FilePath(FILE_PATH_LITERAL("foo.user.js"))), + FilePath(FILE_PATH_LITERAL("c:\\foo\\")), + FilePath(FILE_PATH_LITERAL("foo.user.js")), GURL("chrome-user-script:/foo.user.js"))); script1.css_scripts().push_back(UserScript::File( - ExtensionResource(FilePath(FILE_PATH_LITERAL("c:\\foo\\")), - FilePath(FILE_PATH_LITERAL("foo.user.css"))), + FilePath(FILE_PATH_LITERAL("c:\\foo\\")), + FilePath(FILE_PATH_LITERAL("foo.user.css")), GURL("chrome-user-script:/foo.user.css"))); script1.css_scripts().push_back(UserScript::File( - ExtensionResource(FilePath(FILE_PATH_LITERAL("c:\\foo\\")), - FilePath(FILE_PATH_LITERAL("foo2.user.css"))), + FilePath(FILE_PATH_LITERAL("c:\\foo\\")), + FilePath(FILE_PATH_LITERAL("foo2.user.css")), GURL("chrome-user-script:/foo2.user.css"))); script1.set_run_location(UserScript::DOCUMENT_START); |