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 11ExtensionResource::ExtensionResource() { 12} 13 14ExtensionResource::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 22ExtensionResource::~ExtensionResource() {} 23 24const 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 40FilePath 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. 67FilePath::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 81bool 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