123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // Copyright (c) 2012 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 "extensions/common/extension_resource.h"
- #include "base/check.h"
- #include "base/files/file_util.h"
- namespace extensions {
- ExtensionResource::ExtensionResource() : follow_symlinks_anywhere_(false) {}
- ExtensionResource::ExtensionResource(const ExtensionId& extension_id,
- const base::FilePath& extension_root,
- const base::FilePath& relative_path)
- : extension_id_(extension_id),
- extension_root_(extension_root),
- relative_path_(relative_path),
- follow_symlinks_anywhere_(false) {}
- ExtensionResource::ExtensionResource(const ExtensionResource& other) = default;
- ExtensionResource::ExtensionResource(ExtensionResource&& other) = default;
- ExtensionResource& ExtensionResource::operator=(ExtensionResource&& other) =
- default;
- ExtensionResource::~ExtensionResource() = default;
- void ExtensionResource::set_follow_symlinks_anywhere() {
- follow_symlinks_anywhere_ = true;
- }
- const base::FilePath& ExtensionResource::GetFilePath() const {
- 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_,
- follow_symlinks_anywhere_ ?
- FOLLOW_SYMLINKS_ANYWHERE : SYMLINKS_MUST_RESOLVE_WITHIN_ROOT);
- return full_resource_path_;
- }
- // static
- base::FilePath ExtensionResource::GetFilePath(
- const base::FilePath& extension_root,
- const base::FilePath& relative_path,
- SymlinkPolicy symlink_policy) {
- // We need to resolve the parent references in the extension_root
- // path on its own because IsParent doesn't like parent references.
- base::FilePath clean_extension_root(
- base::MakeAbsoluteFilePath(extension_root));
- if (clean_extension_root.empty())
- return base::FilePath();
- base::FilePath full_path = clean_extension_root.Append(relative_path);
- // If we are allowing the file to be a symlink outside of the root, then the
- // path before resolving the symlink must still be within it.
- if (symlink_policy == FOLLOW_SYMLINKS_ANYWHERE) {
- std::vector<base::FilePath::StringType> components =
- relative_path.GetComponents();
- int depth = 0;
- for (std::vector<base::FilePath::StringType>::const_iterator
- i = components.begin(); i != components.end(); i++) {
- if (*i == base::FilePath::kParentDirectory) {
- depth--;
- } else if (*i != base::FilePath::kCurrentDirectory) {
- depth++;
- }
- if (depth < 0) {
- return base::FilePath();
- }
- }
- }
- // We must resolve the absolute path of the combined path when
- // the relative path contains references to a parent folder (i.e., '..').
- // We also check if the path exists because the posix version of
- // MakeAbsoluteFilePath will fail if the path doesn't exist, and we want the
- // same behavior on Windows... So until the posix and Windows version of
- // MakeAbsoluteFilePath are unified, we need an extra call to PathExists,
- // unfortunately.
- // TODO(mad): Fix this once MakeAbsoluteFilePath is unified.
- full_path = base::MakeAbsoluteFilePath(full_path);
- if (base::PathExists(full_path) &&
- (symlink_policy == FOLLOW_SYMLINKS_ANYWHERE ||
- clean_extension_root.IsParent(full_path))) {
- return full_path;
- }
- return base::FilePath();
- }
- } // namespace extensions
|