Skip to content

Commit c705e02

Browse files
committed
Go: Implement new data flow interface
1 parent eedde7a commit c705e02

18 files changed

+186
-36
lines changed

go/ql/lib/semmle/go/DiagnosticsReporting.qll

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** Provides classes for working with errors and warnings recorded during extraction. */
22

33
import go
4+
private import semmle.go.internal.Locations
45

56
/** Gets the SARIF severity level that indicates an error. */
67
private int getErrorSeverity() { result = 2 }
@@ -29,7 +30,9 @@ private class Diagnostic extends @diagnostic {
2930
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
3031
*/
3132
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
32-
exists(Location l | diagnostics(this, _, _, _, _, l) | l.hasLocationInfo(path, sl, sc, el, ec))
33+
exists(DbLocationImpl l | diagnostics(this, _, _, _, _, l.getDbLocation()) |
34+
l.hasLocationInfo(path, sl, sc, el, ec)
35+
)
3336
}
3437

3538
string toString() { result = this.getMessage() }

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

+24-8
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
11
/** Provides classes for working with locations and program elements that have locations. */
22

33
import go
4+
private import internal.Locations
45

56
/**
67
* A location as given by a file, a start line, a start column,
78
* an end line, and an end column.
89
*
10+
* This class is restricted to locations created by the extractor.
11+
*
912
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
1013
*/
11-
class Location extends @location {
14+
class DbLocation extends TDbLocation {
15+
private @location loc;
16+
17+
DbLocation() { this = TDbLocation(loc) }
18+
1219
/** Gets the file for this location. */
13-
File getFile() { locations_default(this, result, _, _, _, _) }
20+
File getFile() { locations_default(loc, result, _, _, _, _) }
1421

1522
/** Gets the 1-based line number (inclusive) where this location starts. */
16-
int getStartLine() { locations_default(this, _, result, _, _, _) }
23+
int getStartLine() { locations_default(loc, _, result, _, _, _) }
1724

1825
/** Gets the 1-based column number (inclusive) where this location starts. */
19-
int getStartColumn() { locations_default(this, _, _, result, _, _) }
26+
int getStartColumn() { locations_default(loc, _, _, result, _, _) }
2027

2128
/** Gets the 1-based line number (inclusive) where this location ends. */
22-
int getEndLine() { locations_default(this, _, _, _, result, _) }
29+
int getEndLine() { locations_default(loc, _, _, _, result, _) }
2330

2431
/** Gets the 1-based column number (inclusive) where this location ends. */
25-
int getEndColumn() { locations_default(this, _, _, _, _, result) }
32+
int getEndColumn() { locations_default(loc, _, _, _, _, result) }
2633

2734
/** Gets the number of lines covered by this location. */
2835
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
@@ -46,19 +53,28 @@ class Location extends @location {
4653
string filepath, int startline, int startcolumn, int endline, int endcolumn
4754
) {
4855
exists(File f |
49-
locations_default(this, f, startline, startcolumn, endline, endcolumn) and
56+
locations_default(loc, f, startline, startcolumn, endline, endcolumn) and
5057
filepath = f.getAbsolutePath()
5158
)
5259
}
5360
}
5461

62+
final class Location = LocationImpl;
63+
5564
/** A program element with a location. */
5665
class Locatable extends @locatable {
5766
/** Gets the file this program element comes from. */
5867
File getFile() { result = this.getLocation().getFile() }
5968

6069
/** Gets this element's location. */
61-
Location getLocation() { has_location(this, result) }
70+
final DbLocation getLocation() {
71+
exists(@location loc |
72+
has_location(this, loc) or
73+
xmllocations(this, loc)
74+
|
75+
result = TDbLocation(loc)
76+
)
77+
}
6278

6379
/** Gets the number of lines covered by this element. */
6480
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
}
+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/** Provides classes for working with locations and program elements that have locations. */
2+
3+
import go
4+
5+
cached
6+
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+
17+
/**
18+
* A location as given by a file, a start line, a start column,
19+
* an end line, and an end column.
20+
*
21+
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
22+
*/
23+
abstract class LocationImpl extends TLocation {
24+
/** Gets the file for this location. */
25+
abstract File getFile();
26+
27+
/** Gets the 1-based line number (inclusive) where this location starts. */
28+
abstract int getStartLine();
29+
30+
/** Gets the 1-based column number (inclusive) where this location starts. */
31+
abstract int getStartColumn();
32+
33+
/** Gets the 1-based line number (inclusive) where this location ends. */
34+
abstract int getEndLine();
35+
36+
/** Gets the 1-based column number (inclusive) where this location ends. */
37+
abstract int getEndColumn();
38+
39+
/** Gets the number of lines covered by this location. */
40+
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
41+
42+
/** Gets a textual representation of this element. */
43+
string toString() {
44+
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
45+
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
46+
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
47+
)
48+
}
49+
50+
/**
51+
* Holds if this element is at the specified location.
52+
* The location spans column `startcolumn` of line `startline` to
53+
* column `endcolumn` of line `endline` in file `filepath`.
54+
* For more information, see
55+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
56+
*/
57+
abstract predicate hasLocationInfo(
58+
string filepath, int startline, int startcolumn, int endline, int endcolumn
59+
);
60+
}
61+
62+
class DbLocationImpl extends LocationImpl instanceof DbLocation {
63+
private @location loc;
64+
65+
DbLocationImpl() { this = TDbLocation(loc) }
66+
67+
@location getDbLocation() { result = loc }
68+
69+
override File getFile() { result = DbLocation.super.getFile() }
70+
71+
override int getStartLine() { result = DbLocation.super.getStartLine() }
72+
73+
override int getStartColumn() { result = DbLocation.super.getStartColumn() }
74+
75+
override int getEndLine() { result = DbLocation.super.getEndLine() }
76+
77+
override int getEndColumn() { result = DbLocation.super.getEndColumn() }
78+
79+
override predicate hasLocationInfo(
80+
string filepath, int startline, int startcolumn, int endline, int endcolumn
81+
) {
82+
DbLocation.super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
83+
}
84+
}
85+
86+
class DataFlowLocationImpl extends LocationImpl, TDataFlowLocation {
87+
private string filepath_;
88+
private int startline_;
89+
private int startcolumn_;
90+
private int endline_;
91+
private int endcolumn_;
92+
93+
DataFlowLocationImpl() {
94+
this = TDataFlowLocation(filepath_, startline_, startcolumn_, endline_, endcolumn_)
95+
}
96+
97+
override File getFile() { result.getAbsolutePath() = filepath_ }
98+
99+
override int getStartLine() { result = startline_ }
100+
101+
override int getStartColumn() { result = startcolumn_ }
102+
103+
override int getEndLine() { result = endline_ }
104+
105+
override int getEndColumn() { result = endcolumn_ }
106+
107+
override predicate hasLocationInfo(
108+
string filepath, int startline, int startcolumn, int endline, int endcolumn
109+
) {
110+
filepath = filepath_ and
111+
startline = startline_ and
112+
startcolumn = startcolumn_ and
113+
endline = endline_ and
114+
endcolumn = endcolumn_
115+
}
116+
}

go/ql/src/Security/CWE-338/InsecureRandomness.ql

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ where
2525
min(InsecureRandomness::Flow::PathNode sink2, int line |
2626
InsecureRandomness::Flow::flowPath(_, sink2) and
2727
sink2.getNode().getRoot() = sink.getNode().getRoot() and
28-
sink2.hasLocationInfo(_, line, _, _, _)
28+
line = sink2.getLocation().getStartLine()
2929
|
3030
sink2 order by line
3131
)

go/ql/test/TestUtilities/InlineFlowTest.qll

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ private import semmle.go.dataflow.internal.DataFlowImplSpecific
99
private import semmle.go.dataflow.internal.TaintTrackingImplSpecific
1010
private import internal.InlineExpectationsTestImpl
1111

12-
private module FlowTestImpl implements InputSig<GoDataFlow> {
12+
private module FlowTestImpl implements InputSig<Location, GoDataFlow> {
1313
predicate defaultSource(DataFlow::Node source) {
1414
exists(Function fn | fn.hasQualifiedName(_, ["source", "taint"]) |
1515
source = fn.getACall().getResult()
@@ -26,4 +26,4 @@ private module FlowTestImpl implements InputSig<GoDataFlow> {
2626
}
2727
}
2828

29-
import InlineFlowTestMake<GoDataFlow, GoTaintTracking, Impl, FlowTestImpl>
29+
import InlineFlowTestMake<Location, GoDataFlow, GoTaintTracking, Impl, FlowTestImpl>

0 commit comments

Comments
 (0)