Skip to content

Commit 80be65f

Browse files
committed
Go: Implement new data flow interface
1 parent 82fcca1 commit 80be65f

14 files changed

+152
-32
lines changed

go/ql/lib/semmle/go/Files.qll

-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ class Folder extends Container, Impl::Folder {
5050
class ExtractedOrExternalFile extends Container, Impl::File, Documentable, ExprParent,
5151
GoModExprParent, DeclParent, ScopeNode
5252
{
53-
override Location getLocation() { has_location(this, result) }
54-
5553
/** Gets the number of lines in this file. */
5654
int getNumberOfLines() { numlines(this, result, _, _) }
5755

go/ql/lib/semmle/go/HTML.qll

-8
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ module HTML {
1515
class Element extends Locatable, @xmlelement {
1616
Element() { exists(HtmlFile f | xmlElements(this, _, _, _, f)) }
1717

18-
override Location getLocation() { xmllocations(this, result) }
19-
2018
/**
2119
* Gets the name of this HTML element.
2220
*
@@ -97,8 +95,6 @@ module HTML {
9795
class Attribute extends Locatable, @xmlattribute {
9896
Attribute() { xmlAttrs(this, _, _, _, _, any(HtmlFile f)) }
9997

100-
override Location getLocation() { xmllocations(this, result) }
101-
10298
/**
10399
* Gets the element to which this attribute belongs.
104100
*/
@@ -180,8 +176,6 @@ module HTML {
180176
* Holds if this text node is inside a `CDATA` tag.
181177
*/
182178
predicate isCData() { xmlChars(this, _, _, _, 1, _) }
183-
184-
override Location getLocation() { xmllocations(this, result) }
185179
}
186180

187181
/**
@@ -203,7 +197,5 @@ module HTML {
203197
string getText() { result = this.toString().regexpCapture("(?s)<!--(.*)-->", 1) }
204198

205199
override string toString() { xmlComments(this, result, _, _) }
206-
207-
override Location getLocation() { xmllocations(this, result) }
208200
}
209201
}

go/ql/lib/semmle/go/Locations.qll

+124-8
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,39 @@
22

33
import go
44

5+
cached
6+
private newtype TLocation =
7+
TDbLocation(@location loc) or
8+
TDataFlowLocation(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
9+
any(DataFlow::Node n).hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
10+
// avoid overlap with existing DB locations
11+
not exists(File f |
12+
locations_default(_, f, startline, startcolumn, endline, endcolumn) and
13+
f.getAbsolutePath() = filepath
14+
)
15+
}
16+
517
/**
618
* A location as given by a file, a start line, a start column,
719
* an end line, and an end column.
820
*
921
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
1022
*/
11-
class Location extends @location {
23+
abstract private class LocationImpl extends TLocation {
1224
/** Gets the file for this location. */
13-
File getFile() { locations_default(this, result, _, _, _, _) }
25+
abstract File getFile();
1426

1527
/** Gets the 1-based line number (inclusive) where this location starts. */
16-
int getStartLine() { locations_default(this, _, result, _, _, _) }
28+
abstract int getStartLine();
1729

1830
/** Gets the 1-based column number (inclusive) where this location starts. */
19-
int getStartColumn() { locations_default(this, _, _, result, _, _) }
31+
abstract int getStartColumn();
2032

2133
/** Gets the 1-based line number (inclusive) where this location ends. */
22-
int getEndLine() { locations_default(this, _, _, _, result, _) }
34+
abstract int getEndLine();
2335

2436
/** Gets the 1-based column number (inclusive) where this location ends. */
25-
int getEndColumn() { locations_default(this, _, _, _, _, result) }
37+
abstract int getEndColumn();
2638

2739
/** Gets the number of lines covered by this location. */
2840
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
@@ -42,23 +54,127 @@ class Location extends @location {
4254
* For more information, see
4355
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
4456
*/
57+
abstract predicate hasLocationInfo(
58+
string filepath, int startline, int startcolumn, int endline, int endcolumn
59+
);
60+
}
61+
62+
/** A subset of `Location`s that are part of the DB `@location` relation. */
63+
class DbLocation extends TDbLocation {
64+
private @location loc;
65+
66+
DbLocation() { this = TDbLocation(loc) }
67+
68+
/** Gets the file for this location. */
69+
File getFile() { locations_default(loc, result, _, _, _, _) }
70+
71+
/** Gets the 1-based line number (inclusive) where this location starts. */
72+
int getStartLine() { locations_default(loc, _, result, _, _, _) }
73+
74+
/** Gets the 1-based column number (inclusive) where this location starts. */
75+
int getStartColumn() { locations_default(loc, _, _, result, _, _) }
76+
77+
/** Gets the 1-based line number (inclusive) where this location ends. */
78+
int getEndLine() { locations_default(loc, _, _, _, result, _) }
79+
80+
/** Gets the 1-based column number (inclusive) where this location ends. */
81+
int getEndColumn() { locations_default(loc, _, _, _, _, result) }
82+
83+
/** Gets the number of lines covered by this location. */
84+
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
85+
86+
/** Gets a textual representation of this element. */
87+
string toString() {
88+
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
89+
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
90+
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
91+
)
92+
}
93+
4594
predicate hasLocationInfo(
4695
string filepath, int startline, int startcolumn, int endline, int endcolumn
4796
) {
4897
exists(File f |
49-
locations_default(this, f, startline, startcolumn, endline, endcolumn) and
98+
locations_default(loc, f, startline, startcolumn, endline, endcolumn) and
5099
filepath = f.getAbsolutePath()
51100
)
52101
}
53102
}
54103

104+
private class DbLocationImpl extends LocationImpl instanceof DbLocation {
105+
private @location loc;
106+
107+
DbLocationImpl() { this = TDbLocation(loc) }
108+
109+
override File getFile() { result = DbLocation.super.getFile() }
110+
111+
override int getStartLine() { result = DbLocation.super.getStartLine() }
112+
113+
override int getStartColumn() { result = DbLocation.super.getStartColumn() }
114+
115+
override int getEndLine() { result = DbLocation.super.getEndLine() }
116+
117+
override int getEndColumn() { result = DbLocation.super.getEndColumn() }
118+
119+
override int getNumLines() { result = LocationImpl.super.getNumLines() }
120+
121+
override string toString() { result = LocationImpl.super.toString() }
122+
123+
override predicate hasLocationInfo(
124+
string filepath, int startline, int startcolumn, int endline, int endcolumn
125+
) {
126+
DbLocation.super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
127+
}
128+
}
129+
130+
private class DataFlowLocation extends LocationImpl, TDataFlowLocation {
131+
private string filepath_;
132+
private int startline_;
133+
private int startcolumn_;
134+
private int endline_;
135+
private int endcolumn_;
136+
137+
DataFlowLocation() {
138+
this = TDataFlowLocation(filepath_, startline_, startcolumn_, endline_, endcolumn_)
139+
}
140+
141+
override File getFile() { result.getAbsolutePath() = filepath_ }
142+
143+
override int getStartLine() { result = startline_ }
144+
145+
override int getStartColumn() { result = startcolumn_ }
146+
147+
override int getEndLine() { result = endline_ }
148+
149+
override int getEndColumn() { result = endcolumn_ }
150+
151+
override predicate hasLocationInfo(
152+
string filepath, int startline, int startcolumn, int endline, int endcolumn
153+
) {
154+
filepath = filepath_ and
155+
startline = startline_ and
156+
startcolumn = startcolumn_ and
157+
endline = endline_ and
158+
endcolumn = endcolumn_
159+
}
160+
}
161+
162+
final class Location = LocationImpl;
163+
55164
/** A program element with a location. */
56165
class Locatable extends @locatable {
57166
/** Gets the file this program element comes from. */
58167
File getFile() { result = this.getLocation().getFile() }
59168

60169
/** Gets this element's location. */
61-
Location getLocation() { has_location(this, result) }
170+
final DbLocation getLocation() {
171+
exists(@location loc |
172+
has_location(this, loc) or
173+
xmllocations(this, loc)
174+
|
175+
result = TDbLocation(loc)
176+
)
177+
}
62178

63179
/** Gets the number of lines covered by this element. */
64180
int getNumLines() { result = this.getLocation().getNumLines() }

go/ql/lib/semmle/go/dataflow/DataFlow.qll

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import go
2424
module DataFlow {
2525
private import semmle.go.dataflow.internal.DataFlowImplSpecific
2626
private import codeql.dataflow.DataFlow
27-
import DataFlowMake<GoDataFlow>
27+
import DataFlowMake<Location, GoDataFlow>
2828
import semmle.go.dataflow.internal.DataFlowImpl1
2929
import Properties
3030
}

go/ql/lib/semmle/go/dataflow/TaintTracking.qll

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ module TaintTracking {
1313
import semmle.go.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
1414
private import semmle.go.dataflow.internal.DataFlowImplSpecific
1515
private import semmle.go.dataflow.internal.TaintTrackingImplSpecific
16+
private import semmle.go.Locations
1617
private import codeql.dataflow.TaintTracking
17-
import TaintFlowMake<GoDataFlow, GoTaintTracking>
18+
import TaintFlowMake<Location, GoDataFlow, GoTaintTracking>
1819
import semmle.go.dataflow.internal.tainttracking1.TaintTrackingImpl
1920
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
private import DataFlowImplSpecific
22
private import codeql.dataflow.internal.DataFlowImpl
3-
import MakeImpl<GoDataFlow>
3+
private import semmle.go.Locations
4+
import MakeImpl<Location, GoDataFlow>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
private import DataFlowImplSpecific
22
private import codeql.dataflow.internal.DataFlowImplCommon
3-
import MakeImplCommon<GoDataFlow>
3+
private import semmle.go.Locations
4+
import MakeImplCommon<Location, GoDataFlow>

go/ql/lib/semmle/go/dataflow/internal/DataFlowImplConsistency.qll

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ private import go
77
private import DataFlowImplSpecific
88
private import TaintTrackingImplSpecific
99
private import codeql.dataflow.internal.DataFlowImplConsistency
10+
private import semmle.go.dataflow.internal.DataFlowNodes
1011

11-
private module Input implements InputSig<GoDataFlow> { }
12+
private module Input implements InputSig<Location, GoDataFlow> { }
1213

13-
module Consistency = MakeConsistency<GoDataFlow, GoTaintTracking, Input>;
14+
module Consistency = MakeConsistency<Location, GoDataFlow, GoTaintTracking, Input>;

go/ql/lib/semmle/go/dataflow/internal/DataFlowImplSpecific.qll

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
private import codeql.dataflow.DataFlow
6+
private import semmle.go.Locations
67

78
module Private {
89
import DataFlowPrivate
@@ -13,7 +14,7 @@ module Public {
1314
import DataFlowUtil
1415
}
1516

16-
module GoDataFlow implements InputSig {
17+
module GoDataFlow implements InputSig<Location> {
1718
import Private
1819
import Public
1920

go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll

+8
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ module Public {
157157
endcolumn = 0
158158
}
159159

160+
/** Gets the location of this node. */
161+
Location getLocation() {
162+
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
163+
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
164+
result.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
165+
)
166+
}
167+
160168
/** Gets the file in which this node appears. */
161169
File getFile() { this.hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
162170

go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ private module FlowSummaries {
1515
private import semmle.go.dataflow.FlowSummary as F
1616
}
1717

18-
module Input implements InputSig<DataFlowImplSpecific::GoDataFlow> {
18+
module Input implements InputSig<Location, DataFlowImplSpecific::GoDataFlow> {
1919
class SummarizedCallableBase = Callable;
2020

2121
ArgumentPosition callbackSelfParameterPosition() { result = -1 }
@@ -83,7 +83,7 @@ module Input implements InputSig<DataFlowImplSpecific::GoDataFlow> {
8383
}
8484
}
8585

86-
private import Make<DataFlowImplSpecific::GoDataFlow, Input> as Impl
86+
private import Make<Location, DataFlowImplSpecific::GoDataFlow, Input> as Impl
8787

8888
private module StepsInput implements Impl::Private::StepsInputSig {
8989
DataFlowCall getACall(Public::SummarizedCallable sc) {
@@ -95,7 +95,7 @@ private module StepsInput implements Impl::Private::StepsInputSig {
9595
}
9696

9797
module SourceSinkInterpretationInput implements
98-
Impl::Private::External::SourceSinkInterpretationInputSig<Location>
98+
Impl::Private::External::SourceSinkInterpretationInputSig
9999
{
100100
class Element = SourceOrSinkElement;
101101

@@ -264,7 +264,7 @@ module Private {
264264

265265
module External {
266266
import Impl::Private::External
267-
import Impl::Private::External::SourceSinkInterpretation<Location, SourceSinkInterpretationInput>
267+
import Impl::Private::External::SourceSinkInterpretation<SourceSinkInterpretationInput>
268268
}
269269

270270
/**

go/ql/lib/semmle/go/dataflow/internal/TaintTrackingImplSpecific.qll

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
private import codeql.dataflow.TaintTracking
66
private import DataFlowImplSpecific
7+
private import semmle.go.Locations
78

8-
module GoTaintTracking implements InputSig<GoDataFlow> {
9+
module GoTaintTracking implements InputSig<Location, GoDataFlow> {
910
import TaintTrackingUtil
1011
}

go/ql/lib/semmle/go/frameworks/GoMicro.qll

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ module GoMicro {
5151

5252
ServiceInterfaceType() {
5353
this = namedType.getUnderlyingType() and
54-
namedType.hasLocationInfo(any(ProtocGeneratedFile f).getAbsolutePath(), _, _, _, _)
54+
namedType.getEntity().getDeclaration().getFile() instanceof ProtocGeneratedFile
5555
}
5656

5757
/**

go/ql/lib/semmle/go/frameworks/Twirp.qll

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module Twirp {
4848

4949
ServiceInterfaceType() {
5050
namedType.getUnderlyingType() = this and
51-
namedType.hasLocationInfo(any(ServicesGeneratedFile f).getAbsolutePath(), _, _, _, _)
51+
namedType.getEntity().getDeclaration().getFile() instanceof ServicesGeneratedFile
5252
}
5353

5454
/** Gets the name of the interface. */

0 commit comments

Comments
 (0)