forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFileSystem.qll
More file actions
executable file
·279 lines (252 loc) · 8.29 KB
/
FileSystem.qll
File metadata and controls
executable file
·279 lines (252 loc) · 8.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/** Provides classes for working with files and folders. */
import Location
/** A file or folder. */
class Container extends @container, Top {
/**
* Gets the absolute, canonical path of this container, using forward slashes
* as path separator.
*
* The path starts with a _root prefix_ followed by zero or more _path
* segments_ separated by forward slashes.
*
* The root prefix is of one of the following forms:
*
* 1. A single forward slash `/` (Unix-style)
* 2. An upper-case drive letter followed by a colon and a forward slash,
* such as `C:/` (Windows-style)
* 3. Two forward slashes, a computer name, and then another forward slash,
* such as `//FileServer/` (UNC-style)
*
* Path segments are never empty (that is, absolute paths never contain two
* contiguous slashes, except as part of a UNC-style root prefix). Also, path
* segments never contain forward slashes, and no path segment is of the
* form `.` (one dot) or `..` (two dots).
*
* Note that an absolute path never ends with a forward slash, except if it is
* a bare root prefix, that is, the path has no path segments. A container
* whose absolute path has no segments is always a `Folder`, not a `File`.
*/
abstract string getAbsolutePath();
/**
* Gets a URL representing the location of this container.
*
* For more information see https://lgtm.com/help/ql/locations#providing-urls.
*/
abstract string getURL();
/**
* Gets the relative path of this file or folder from the root folder of the
* analyzed source location. The relative path of the root folder itself is
* the empty string.
*
* This has no result if the container is outside the source root, that is,
* if the root folder is not a reflexive, transitive parent of this container.
*/
string getRelativePath() {
exists(string absPath, string pref |
absPath = getAbsolutePath() and sourceLocationPrefix(pref)
|
absPath = pref and result = ""
or
absPath = pref.regexpReplaceAll("/$", "") + "/" + result and
not result.matches("/%")
)
}
/**
* Gets the base name of this container including extension, that is, the last
* segment of its absolute path, or the empty string if it has no segments.
*
* Here are some examples of absolute paths and the corresponding base names
* (surrounded with quotes to avoid ambiguity):
*
* <table border="1">
* <tr><th>Absolute path</th><th>Base name</th></tr>
* <tr><td>"/tmp/tst.java"</td><td>"tst.java"</td></tr>
* <tr><td>"C:/Program Files (x86)"</td><td>"Program Files (x86)"</td></tr>
* <tr><td>"/"</td><td>""</td></tr>
* <tr><td>"C:/"</td><td>""</td></tr>
* <tr><td>"D:/"</td><td>""</td></tr>
* <tr><td>"//FileServer/"</td><td>""</td></tr>
* </table>
*/
string getBaseName() {
result = getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
}
/**
* Gets the extension of this container, that is, the suffix of its base name
* after the last dot character, if any.
*
* In particular,
*
* - if the name does not include a dot, there is no extension, so this
* predicate has no result;
* - if the name ends in a dot, the extension is the empty string;
* - if the name contains multiple dots, the extension follows the last dot.
*
* Here are some examples of absolute paths and the corresponding extensions
* (surrounded with quotes to avoid ambiguity):
*
* <table border="1">
* <tr><th>Absolute path</th><th>Extension</th></tr>
* <tr><td>"/tmp/tst.java"</td><td>"java"</td></tr>
* <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
* <tr><td>"/bin/bash"</td><td>not defined</td></tr>
* <tr><td>"/tmp/tst2."</td><td>""</td></tr>
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
* </table>
*/
string getExtension() {
result = getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
}
/**
* Gets the stem of this container, that is, the prefix of its base name up to
* (but not including) the last dot character if there is one, or the entire
* base name if there is not.
*
* Here are some examples of absolute paths and the corresponding stems
* (surrounded with quotes to avoid ambiguity):
*
* <table border="1">
* <tr><th>Absolute path</th><th>Stem</th></tr>
* <tr><td>"/tmp/tst.java"</td><td>"tst"</td></tr>
* <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
* <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
* <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
* </table>
*/
string getStem() {
result = getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
}
/** Gets the parent container of this file or folder, if any. */
Container getParentContainer() {
containerparent(result, this)
}
/** Gets a file or sub-folder in this container. */
Container getAChildContainer() {
this = result.getParentContainer()
}
/** Gets a file in this container. */
File getAFile() {
result = getAChildContainer()
}
/** Gets the file in this container that has the given `baseName`, if any. */
File getFile(string baseName) {
result = getAFile() and
result.getBaseName() = baseName
}
/** Gets a sub-folder in this container. */
Folder getAFolder() {
result = getAChildContainer()
}
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
Folder getFolder(string baseName) {
result = getAFolder() and
result.getBaseName() = baseName
}
/**
* Gets a textual representation of the path of this container.
*
* This is the absolute path of the container.
*/
override string toString() {
result = getAbsolutePath()
}
/**
* DEPRECATED: use `getAbsolutePath()`, `getBaseName()` or `getStem()` instead.
*
* Gets the name of this container.
*/
deprecated
string getName() {
result = getAbsolutePath()
}
/**
* DEPRECATED: use `getBaseName()` or `getStem()` instead.
*
* The short name of this container, excluding its path and (for files) extension.
*
* For folders, the short name includes the extension (if any), so the short name
* of the folder with absolute path `/home/user/.m2` is `.m2`.
*/
deprecated
string getShortName() {
folders(this,_,result) or
files(this,_,result,_,_)
}
/**
* DEPRECATED: use `getAbsolutePath()` instead.
*
* Gets the full name of this container, including its path and extension (if any).
*/
deprecated
string getFullName() {
result = getAbsolutePath()
}
}
/** A folder. */
class Folder extends Container, @folder {
override string getAbsolutePath() {
folders(this, result, _)
}
/** Gets the URL of this folder. */
override string getURL() {
result = "folder://" + getAbsolutePath()
}
}
/**
* A file.
*
* Note that `File` extends `Container` as it may be a `jar` file.
*/
class File extends Container, @file {
override string getAbsolutePath() {
files(this, result, _, _, _)
}
/** Gets the URL of this file. */
override string getURL() {
result = "file://" + this.getAbsolutePath() + ":0:0:0:0"
}
/**
* DEPRECATED: use `getAbsolutePath()`, `getBaseName()` or `getStem()` instead.
*
* Holds if this file has the specified `name`.
*/
deprecated
predicate hasName(string name) { name = this.getAbsolutePath() }
}
/**
* A Java archive file with a ".jar" extension.
*/
class JarFile extends File {
JarFile() {
getExtension() = "jar"
}
/**
* Gets the main attribute with the specified `key`
* from this JAR file's manifest.
*/
string getManifestMainAttribute(string key) {
jarManifestMain(this, key, result)
}
/**
* Gets the "Specification-Version" main attribute
* from this JAR file's manifest.
*/
string getSpecificationVersion() {
result = getManifestMainAttribute("Specification-Version")
}
/**
* Gets the "Implementation-Version" main attribute
* from this JAR file's manifest.
*/
string getImplementationVersion() {
result = getManifestMainAttribute("Implementation-Version")
}
/**
* Gets the per-entry attribute for the specified `entry` and `key`
* from this JAR file's manifest.
*/
string getManifestEntryAttribute(string entry, string key) {
jarManifestEntries(this, entry, key, result)
}
}