1// Copyright (c) 2012 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#ifndef EXTENSIONS_COMMON_EXTENSION_RESOURCE_H_
6#define EXTENSIONS_COMMON_EXTENSION_RESOURCE_H_
7
8#include <string>
9
10#include "base/files/file_path.h"
11
12namespace extensions {
13
14// Represents a resource inside an extension. For example, an image, or a
15// JavaScript file. This is more complicated than just a simple FilePath
16// because extension resources can come from multiple physical file locations
17// depending on locale.
18class ExtensionResource {
19 public:
20 // SymlinkPolicy decides whether we'll allow resources to be a symlink to
21 // anywhere, or whether they must end up within the extension root.
22 enum SymlinkPolicy {
23 SYMLINKS_MUST_RESOLVE_WITHIN_ROOT,
24 FOLLOW_SYMLINKS_ANYWHERE,
25 };
26
27 ExtensionResource();
28
29 ExtensionResource(const std::string& extension_id,
30 const base::FilePath& extension_root,
31 const base::FilePath& relative_path);
32
33 ExtensionResource(const ExtensionResource& other);
34
35 ~ExtensionResource();
36
37 // set_follow_symlinks_anywhere allows the resource to be a symlink to
38 // anywhere in the filesystem. By default, resources have to be within
39 // |extension_root| after resolving symlinks.
40 void set_follow_symlinks_anywhere();
41
42 // Returns actual path to the resource (default or locale specific). In the
43 // browser process, this will DCHECK if not called on the file thread. To
44 // easily load extension images on the UI thread, see ImageLoader.
45 const base::FilePath& GetFilePath() const;
46
47 // Gets the physical file path for the extension resource, taking into account
48 // localization. In the browser process, this will DCHECK if not called on the
49 // file thread. To easily load extension images on the UI thread, see
50 // ImageLoader.
51 //
52 // The relative path must not resolve to a location outside of
53 // |extension_root|. Iff |file_can_symlink_outside_root| is true, then the
54 // file can be a symlink that links outside of |extension_root|.
55 static base::FilePath GetFilePath(const base::FilePath& extension_root,
56 const base::FilePath& relative_path,
57 SymlinkPolicy symlink_policy);
58
59 // Getters
60 const std::string& extension_id() const { return extension_id_; }
61 const base::FilePath& extension_root() const { return extension_root_; }
62 const base::FilePath& relative_path() const { return relative_path_; }
63
64 bool empty() const { return extension_root().empty(); }
65
66 // Unit test helpers.
67 base::FilePath::StringType NormalizeSeperators(
68 const base::FilePath::StringType& path) const;
69 bool ComparePathWithDefault(const base::FilePath& path) const;
70
71 private:
72 // The id of the extension that this resource is associated with.
73 std::string extension_id_;
74
75 // Extension root.
76 base::FilePath extension_root_;
77
78 // Relative path to resource.
79 base::FilePath relative_path_;
80
81 // If |follow_symlinks_anywhere_| is true then the resource itself must be
82 // within |extension_root|, but it can be a symlink to a file that is not.
83 bool follow_symlinks_anywhere_;
84
85 // Full path to extension resource. Starts empty.
86 mutable base::FilePath full_resource_path_;
87};
88
89} // namespace extensions
90
91#endif // EXTENSIONS_COMMON_EXTENSION_RESOURCE_H_
92