Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/common/extensions/extension_resource.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/logging.h"
      9 #include "base/threading/thread_restrictions.h"
     10 
     11 ExtensionResource::ExtensionResource() {
     12 }
     13 
     14 ExtensionResource::ExtensionResource(const std::string& extension_id,
     15                                      const FilePath& extension_root,
     16                                      const FilePath& relative_path)
     17     : extension_id_(extension_id),
     18       extension_root_(extension_root),
     19       relative_path_(relative_path) {
     20 }
     21 
     22 ExtensionResource::~ExtensionResource() {}
     23 
     24 const FilePath& ExtensionResource::GetFilePath() const {
     25   if (extension_root_.empty() || relative_path_.empty()) {
     26     DCHECK(full_resource_path_.empty());
     27     return full_resource_path_;
     28   }
     29 
     30   // We've already checked, just return last value.
     31   if (!full_resource_path_.empty())
     32     return full_resource_path_;
     33 
     34   full_resource_path_ =
     35       GetFilePath(extension_root_, relative_path_);
     36   return full_resource_path_;
     37 }
     38 
     39 // static
     40 FilePath ExtensionResource::GetFilePath(
     41     const FilePath& extension_root, const FilePath& relative_path) {
     42   // We need to resolve the parent references in the extension_root
     43   // path on its own because IsParent doesn't like parent references.
     44   FilePath clean_extension_root(extension_root);
     45   if (!file_util::AbsolutePath(&clean_extension_root))
     46     return FilePath();
     47 
     48   FilePath full_path = clean_extension_root.Append(relative_path);
     49 
     50   // We must resolve the absolute path of the combined path when
     51   // the relative path contains references to a parent folder (i.e., '..').
     52   // We also check if the path exists because the posix version of AbsolutePath
     53   // will fail if the path doesn't exist, and we want the same behavior on
     54   // Windows... So until the posix and Windows version of AbsolutePath are
     55   // unified, we need an extra call to PathExists, unfortunately.
     56   // TODO(mad): Fix this once AbsolutePath is unified.
     57   if (file_util::AbsolutePath(&full_path) &&
     58       file_util::PathExists(full_path) &&
     59       clean_extension_root.IsParent(full_path)) {
     60     return full_path;
     61   }
     62 
     63   return FilePath();
     64 }
     65 
     66 // Unit-testing helpers.
     67 FilePath::StringType ExtensionResource::NormalizeSeperators(
     68     const FilePath::StringType& path) const {
     69 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
     70   FilePath::StringType win_path = path;
     71   for (size_t i = 0; i < win_path.length(); i++) {
     72     if (FilePath::IsSeparator(win_path[i]))
     73       win_path[i] = FilePath::kSeparators[0];
     74   }
     75   return win_path;
     76 #else
     77   return path;
     78 #endif  // FILE_PATH_USES_WIN_SEPARATORS
     79 }
     80 
     81 bool ExtensionResource::ComparePathWithDefault(const FilePath& path) const {
     82   // Make sure we have a cached value to test against...
     83   if (full_resource_path_.empty())
     84     GetFilePath();
     85   if (NormalizeSeperators(path.value()) ==
     86     NormalizeSeperators(full_resource_path_.value())) {
     87     return true;
     88   } else {
     89     return false;
     90   }
     91 }
     92