Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit ed965c7

Browse files
committed
Merge branch 'standard-lib-pt-19' into from-331-to-337
2 parents 53e0e3f + 71dbb24 commit ed965c7

File tree

3 files changed

+541
-64
lines changed

3 files changed

+541
-64
lines changed

ql/src/semmle/go/frameworks/Stdlib.qll

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import semmle.go.frameworks.stdlib.Sync
3939
import semmle.go.frameworks.stdlib.SyncAtomic
4040
import semmle.go.frameworks.stdlib.Syscall
4141
import semmle.go.frameworks.stdlib.Sort
42+
import semmle.go.frameworks.stdlib.Regexp
4243
import semmle.go.frameworks.stdlib.TextScanner
4344
import semmle.go.frameworks.stdlib.TextTabwriter
4445
import semmle.go.frameworks.stdlib.TextTemplate
@@ -624,70 +625,6 @@ module URL {
624625
}
625626
}
626627

627-
/** Provides models of commonly used APIs in the `regexp` package. */
628-
module Regexp {
629-
private class Pattern extends RegexpPattern::Range, DataFlow::ArgumentNode {
630-
string fnName;
631-
632-
Pattern() {
633-
exists(Function fn | fnName.matches("Match%") or fnName.matches("%Compile%") |
634-
fn.hasQualifiedName("regexp", fnName) and
635-
this = fn.getACall().getArgument(0)
636-
)
637-
}
638-
639-
override DataFlow::Node getAParse() { result = this.getCall() }
640-
641-
override string getPattern() { result = this.asExpr().getStringValue() }
642-
643-
override DataFlow::Node getAUse() {
644-
fnName.matches("MustCompile%") and
645-
result = this.getCall().getASuccessor*()
646-
or
647-
fnName.matches("Compile%") and
648-
result = this.getCall().getResult(0).getASuccessor*()
649-
or
650-
result = this
651-
}
652-
}
653-
654-
private class MatchFunction extends RegexpMatchFunction::Range, Function {
655-
MatchFunction() {
656-
exists(string fn | fn.matches("Match%") | this.hasQualifiedName("regexp", fn))
657-
}
658-
659-
override FunctionInput getRegexpArg() { result.isParameter(0) }
660-
661-
override FunctionInput getValue() { result.isParameter(1) }
662-
663-
override FunctionOutput getResult() { result.isResult(0) }
664-
}
665-
666-
private class MatchMethod extends RegexpMatchFunction::Range, Method {
667-
MatchMethod() {
668-
exists(string fn | fn.matches("Match%") | this.hasQualifiedName("regexp", "Regexp", fn))
669-
}
670-
671-
override FunctionInput getRegexpArg() { result.isReceiver() }
672-
673-
override FunctionInput getValue() { result.isParameter(0) }
674-
675-
override FunctionOutput getResult() { result.isResult() }
676-
}
677-
678-
private class ReplaceFunction extends RegexpReplaceFunction::Range, Method {
679-
ReplaceFunction() {
680-
exists(string fn | fn.matches("ReplaceAll%") | this.hasQualifiedName("regexp", "Regexp", fn))
681-
}
682-
683-
override FunctionInput getRegexpArg() { result.isReceiver() }
684-
685-
override FunctionInput getSource() { result.isParameter(0) }
686-
687-
override FunctionOutput getResult() { result.isResult() }
688-
}
689-
}
690-
691628
/** Provides models of commonly used functions in the `log` package. */
692629
module Log {
693630
private class LogCall extends LoggerCall::Range, DataFlow::CallNode {
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `regexp` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `regexp` package. */
8+
module Regexp {
9+
private class Pattern extends RegexpPattern::Range, DataFlow::ArgumentNode {
10+
string fnName;
11+
12+
Pattern() {
13+
exists(Function fn | fnName.matches("Match%") or fnName.matches("%Compile%") |
14+
fn.hasQualifiedName("regexp", fnName) and
15+
this = fn.getACall().getArgument(0)
16+
)
17+
}
18+
19+
override DataFlow::Node getAParse() { result = this.getCall() }
20+
21+
override string getPattern() { result = this.asExpr().getStringValue() }
22+
23+
override DataFlow::Node getAUse() {
24+
fnName.matches("MustCompile%") and
25+
result = this.getCall().getASuccessor*()
26+
or
27+
fnName.matches("Compile%") and
28+
result = this.getCall().getResult(0).getASuccessor*()
29+
or
30+
result = this
31+
}
32+
}
33+
34+
private class MatchFunction extends RegexpMatchFunction::Range, Function {
35+
MatchFunction() {
36+
exists(string fn | fn.matches("Match%") | this.hasQualifiedName("regexp", fn))
37+
}
38+
39+
override FunctionInput getRegexpArg() { result.isParameter(0) }
40+
41+
override FunctionInput getValue() { result.isParameter(1) }
42+
43+
override FunctionOutput getResult() { result.isResult(0) }
44+
}
45+
46+
private class MatchMethod extends RegexpMatchFunction::Range, Method {
47+
MatchMethod() {
48+
exists(string fn | fn.matches("Match%") | this.hasQualifiedName("regexp", "Regexp", fn))
49+
}
50+
51+
override FunctionInput getRegexpArg() { result.isReceiver() }
52+
53+
override FunctionInput getValue() { result.isParameter(0) }
54+
55+
override FunctionOutput getResult() { result.isResult() }
56+
}
57+
58+
private class ReplaceFunction extends RegexpReplaceFunction::Range, Method {
59+
ReplaceFunction() {
60+
exists(string fn | fn.matches("ReplaceAll%") | this.hasQualifiedName("regexp", "Regexp", fn))
61+
}
62+
63+
override FunctionInput getRegexpArg() { result.isReceiver() }
64+
65+
override FunctionInput getSource() { result.isParameter(0) }
66+
67+
override FunctionOutput getResult() { result.isResult() }
68+
}
69+
70+
private class FunctionModels extends TaintTracking::FunctionModel {
71+
FunctionInput inp;
72+
FunctionOutput outp;
73+
74+
FunctionModels() {
75+
// signature: func QuoteMeta(s string) string
76+
hasQualifiedName("regexp", "QuoteMeta") and
77+
(inp.isParameter(0) and outp.isResult())
78+
}
79+
80+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
81+
input = inp and output = outp
82+
}
83+
}
84+
85+
private class MethodModels extends TaintTracking::FunctionModel, Method {
86+
FunctionInput inp;
87+
FunctionOutput outp;
88+
89+
MethodModels() {
90+
// signature: func (*Regexp).Expand(dst []byte, template []byte, src []byte, match []int) []byte
91+
this.hasQualifiedName("regexp", "Regexp", "Expand") and
92+
(
93+
inp.isParameter([1, 2]) and
94+
(outp.isParameter(0) or outp.isResult())
95+
)
96+
or
97+
// signature: func (*Regexp).ExpandString(dst []byte, template string, src string, match []int) []byte
98+
this.hasQualifiedName("regexp", "Regexp", "ExpandString") and
99+
(
100+
inp.isParameter([1, 2]) and
101+
(outp.isParameter(0) or outp.isResult())
102+
)
103+
or
104+
// signature: func (*Regexp).Find(b []byte) []byte
105+
this.hasQualifiedName("regexp", "Regexp", "Find") and
106+
(inp.isParameter(0) and outp.isResult())
107+
or
108+
// signature: func (*Regexp).FindAll(b []byte, n int) [][]byte
109+
this.hasQualifiedName("regexp", "Regexp", "FindAll") and
110+
(inp.isParameter(0) and outp.isResult())
111+
or
112+
// signature: func (*Regexp).FindAllString(s string, n int) []string
113+
this.hasQualifiedName("regexp", "Regexp", "FindAllString") and
114+
(inp.isParameter(0) and outp.isResult())
115+
or
116+
// signature: func (*Regexp).FindAllStringSubmatch(s string, n int) [][]string
117+
this.hasQualifiedName("regexp", "Regexp", "FindAllStringSubmatch") and
118+
(inp.isParameter(0) and outp.isResult())
119+
or
120+
// signature: func (*Regexp).FindAllSubmatch(b []byte, n int) [][][]byte
121+
this.hasQualifiedName("regexp", "Regexp", "FindAllSubmatch") and
122+
(inp.isParameter(0) and outp.isResult())
123+
or
124+
// signature: func (*Regexp).FindString(s string) string
125+
this.hasQualifiedName("regexp", "Regexp", "FindString") and
126+
(inp.isParameter(0) and outp.isResult())
127+
or
128+
// signature: func (*Regexp).FindStringSubmatch(s string) []string
129+
this.hasQualifiedName("regexp", "Regexp", "FindStringSubmatch") and
130+
(inp.isParameter(0) and outp.isResult())
131+
or
132+
// signature: func (*Regexp).FindSubmatch(b []byte) [][]byte
133+
this.hasQualifiedName("regexp", "Regexp", "FindSubmatch") and
134+
(inp.isParameter(0) and outp.isResult())
135+
or
136+
// signature: func (*Regexp).ReplaceAll(src []byte, repl []byte) []byte
137+
this.hasQualifiedName("regexp", "Regexp", "ReplaceAll") and
138+
(inp.isParameter(_) and outp.isResult())
139+
or
140+
// signature: func (*Regexp).ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte
141+
this.hasQualifiedName("regexp", "Regexp", "ReplaceAllFunc") and
142+
(inp.isParameter(_) and outp.isResult())
143+
or
144+
// signature: func (*Regexp).ReplaceAllLiteral(src []byte, repl []byte) []byte
145+
this.hasQualifiedName("regexp", "Regexp", "ReplaceAllLiteral") and
146+
(inp.isParameter(_) and outp.isResult())
147+
or
148+
// signature: func (*Regexp).ReplaceAllLiteralString(src string, repl string) string
149+
this.hasQualifiedName("regexp", "Regexp", "ReplaceAllLiteralString") and
150+
(inp.isParameter(_) and outp.isResult())
151+
or
152+
// signature: func (*Regexp).ReplaceAllString(src string, repl string) string
153+
this.hasQualifiedName("regexp", "Regexp", "ReplaceAllString") and
154+
(inp.isParameter(_) and outp.isResult())
155+
or
156+
// signature: func (*Regexp).ReplaceAllStringFunc(src string, repl func(string) string) string
157+
this.hasQualifiedName("regexp", "Regexp", "ReplaceAllStringFunc") and
158+
(inp.isParameter(_) and outp.isResult())
159+
or
160+
// signature: func (*Regexp).Split(s string, n int) []string
161+
this.hasQualifiedName("regexp", "Regexp", "Split") and
162+
(inp.isParameter(0) and outp.isResult())
163+
}
164+
165+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
166+
input = inp and output = outp
167+
}
168+
}
169+
}

0 commit comments

Comments
 (0)