• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 #include "modules/filesystem/DOMFilePath.h"
33 
34 #include "wtf/Vector.h"
35 #include "wtf/text/CString.h"
36 
37 namespace WebCore {
38 
39 const char DOMFilePath::separator = '/';
40 const char DOMFilePath::root[] = "/";
41 
append(const String & base,const String & components)42 String DOMFilePath::append(const String& base, const String& components)
43 {
44     return ensureDirectoryPath(base) + components;
45 }
46 
ensureDirectoryPath(const String & path)47 String DOMFilePath::ensureDirectoryPath(const String& path)
48 {
49     if (!DOMFilePath::endsWithSeparator(path)) {
50         String newPath = path;
51         newPath.append(DOMFilePath::separator);
52         return newPath;
53     }
54     return path;
55 }
56 
getName(const String & path)57 String DOMFilePath::getName(const String& path)
58 {
59     int index = path.reverseFind(DOMFilePath::separator);
60     if (index != -1)
61         return path.substring(index + 1);
62     return path;
63 }
64 
getDirectory(const String & path)65 String DOMFilePath::getDirectory(const String& path)
66 {
67     int index = path.reverseFind(DOMFilePath::separator);
68     if (!index)
69         return DOMFilePath::root;
70     if (index != -1)
71         return path.substring(0, index);
72     return ".";
73 }
74 
isParentOf(const String & parent,const String & mayBeChild)75 bool DOMFilePath::isParentOf(const String& parent, const String& mayBeChild)
76 {
77     ASSERT(DOMFilePath::isAbsolute(parent));
78     ASSERT(DOMFilePath::isAbsolute(mayBeChild));
79     if (parent == DOMFilePath::root && mayBeChild != DOMFilePath::root)
80         return true;
81     if (parent.length() >= mayBeChild.length() || !mayBeChild.startsWith(parent, false))
82         return false;
83     if (mayBeChild[parent.length()] != DOMFilePath::separator)
84         return false;
85     return true;
86 }
87 
removeExtraParentReferences(const String & path)88 String DOMFilePath::removeExtraParentReferences(const String& path)
89 {
90     ASSERT(DOMFilePath::isAbsolute(path));
91     Vector<String> components;
92     Vector<String> canonicalized;
93     path.split(DOMFilePath::separator, components);
94     for (size_t i = 0; i < components.size(); ++i) {
95         if (components[i] == ".")
96             continue;
97         if (components[i] == "..") {
98             if (canonicalized.size() > 0)
99                 canonicalized.removeLast();
100             continue;
101         }
102         canonicalized.append(components[i]);
103     }
104     if (canonicalized.isEmpty())
105         return DOMFilePath::root;
106     String result;
107     for (size_t i = 0; i < canonicalized.size(); ++i) {
108         result.append(DOMFilePath::separator);
109         result.append(canonicalized[i]);
110     }
111     return result;
112 }
113 
isValidPath(const String & path)114 bool DOMFilePath::isValidPath(const String& path)
115 {
116     if (path.isEmpty() || path == DOMFilePath::root)
117         return true;
118 
119     // Embedded NULs are not allowed.
120     if (path.find(static_cast<UChar>(0)) != WTF::kNotFound)
121         return false;
122 
123     // While not [yet] restricted by the spec, '\\' complicates implementation for Chromium.
124     if (path.find('\\') != WTF::kNotFound)
125         return false;
126 
127     // This method is only called on fully-evaluated absolute paths. Any sign of ".." or "." is likely an attempt to break out of the sandbox.
128     Vector<String> components;
129     path.split(DOMFilePath::separator, components);
130     for (size_t i = 0; i < components.size(); ++i) {
131         if (components[i] == ".")
132             return false;
133         if (components[i] == "..")
134             return false;
135     }
136     return true;
137 }
138 
isValidName(const String & name)139 bool DOMFilePath::isValidName(const String& name)
140 {
141     if (name.isEmpty())
142         return true;
143     // '/' is not allowed in name.
144     if (name.contains('/'))
145         return false;
146     return isValidPath(name);
147 }
148 
149 } // namespace WebCore
150