-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathFiles.qll
More file actions
155 lines (121 loc) · 5.14 KB
/
Files.qll
File metadata and controls
155 lines (121 loc) · 5.14 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
/** Provides classes for working with files and folders. */
import go
private import codeql.util.FileSystem
private module Input implements InputSig {
abstract class ContainerBase extends @container {
abstract string getAbsolutePath();
ContainerBase getParentContainer() { containerparent(result, this) }
string toString() { result = this.getAbsolutePath() }
}
class FolderBase extends ContainerBase, @folder {
override string getAbsolutePath() { folders(this, result) }
}
class FileBase extends ContainerBase, @file {
override string getAbsolutePath() { files(this, result) }
}
predicate hasSourceLocationPrefix = sourceLocationPrefix/1;
}
private module Impl = Make<Input>;
class Container = Impl::Container;
/** A folder. */
class Folder extends Container, Impl::Folder {
/** Gets the file or subfolder in this folder that has the given `name`, if any. */
Container getChildContainer(string name) {
result = this.getAChildContainer() and
result.getBaseName() = name
}
/** Gets the file in this folder that has the given `stem` and `extension`, if any. */
File getFile(string stem, string extension) {
result = this.getAChildContainer() and
result.getStem() = stem and
result.getExtension() = extension
}
/** Gets a subfolder contained in this folder. */
Folder getASubFolder() { result = this.getAChildContainer() }
}
/** A file, including files that have not been extracted but are referred to as locations for errors. */
class ExtractedOrExternalFile extends Container, Impl::File, Documentable, ExprParent,
GoModExprParent, DeclParent, ScopeNode
{
/** Gets the number of lines in this file. */
int getNumberOfLines() { numlines(this, result, _, _) }
/** Gets the number of lines containing code in this file. */
int getNumberOfLinesOfCode() { numlines(this, _, result, _) }
/** Gets the number of lines containing comments in this file. */
int getNumberOfLinesOfComments() { numlines(this, _, _, result) }
/** Gets the package name as specified in the package clause of this file. */
Ident getPackageNameExpr() { result = this.getChildExpr(0) }
/** Gets the name of the package to which this file belongs. */
string getPackageName() { result = this.getPackageNameExpr().getName() }
/** Holds if this file contains at least one build constraint. */
pragma[noinline]
predicate hasBuildConstraints() { exists(BuildConstraintComment bc | this = bc.getFile()) }
/**
* Holds if this file contains build constraints that ensure that it
* is only built on architectures of bit size `bitSize`, which can be
* 32 or 64.
*/
predicate constrainsIntBitSize(int bitSize) {
this.explicitlyConstrainsIntBitSize(bitSize) or
this.implicitlyConstrainsIntBitSize(bitSize)
}
/**
* Holds if this file contains explicit build constraints that ensure
* that it is only built on an architecture of bit size `bitSize`,
* which can be 32 or 64.
*/
predicate explicitlyConstrainsIntBitSize(int bitSize) {
exists(BuildConstraintComment bcc | this = bcc.getFile() |
forex(string disjunct | disjunct = bcc.getADisjunct() |
disjunct.splitAt(",").(Architecture).getBitSize() = bitSize
or
disjunct.splitAt("/").(Architecture).getBitSize() = bitSize
)
)
}
/**
* Holds if this file has a name which acts as an implicit build
* constraint that ensures that it is only built on an
* architecture of bit size `bitSize`, which can be 32 or 64.
*/
predicate implicitlyConstrainsIntBitSize(int bitSize) {
exists(Architecture arch | arch.getBitSize() = bitSize |
this.getStem().regexpMatch("(?i).*_\\Q" + arch + "\\E(_test)?")
)
}
override string toString() { result = Container.super.toString() }
/** Gets the `i`th child comment group. */
CommentGroup getCommentGroup(int i) { comment_groups(result, this, i) }
/** Gets a child comment group. */
CommentGroup getACommentGroup() { result = this.getCommentGroup(_) }
/** Gets the number of child comment groups of this file. */
int getNumCommentGroups() { result = count(this.getACommentGroup()) }
override string getAPrimaryQlClass() { result = "ExtractedOrExternalFile" }
}
/** A file that has been extracted. */
class File extends ExtractedOrExternalFile {
File() {
not this.getBaseName() = "-" and
// getAChild is specifically for the Go AST and so does not apply to non-go files
// we care about all non-go extracted files, as only go files can have `@file` entries due to requiring a file entry for diagnostic errors
not this.getExtension() = "go"
or
exists(this.getAChild())
}
override string getAPrimaryQlClass() { result = "File" }
}
/** A Go file. */
class GoFile extends File {
GoFile() { this.getExtension() = "go" }
override string getAPrimaryQlClass() { result = "GoFile" }
}
/** A dummy file. */
class DummyFile extends ExtractedOrExternalFile {
DummyFile() { this.getBaseName() = "-" }
override string getAPrimaryQlClass() { result = "DummyFile" }
}
/** An HTML file. */
class HtmlFile extends File {
HtmlFile() { this.getExtension().regexpMatch("x?html?") }
override string getAPrimaryQlClass() { result = "HtmlFile" }
}