Skip to content

Commit d6892ea

Browse files
authored
Merge pull request #21900 from github/bazookamusic/range-analysis-bound-move-to-shared
Bound.qll - Replace utility for range analysis duplicate across java and cs with shared file
2 parents 3da195f + d2972cb commit d6892ea

7 files changed

Lines changed: 150 additions & 161 deletions

File tree

config/identical-files.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@
1111
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
1212
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
1313
],
14-
"Bound Java/C#": [
15-
"java/ql/lib/semmle/code/java/dataflow/Bound.qll",
16-
"csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll"
17-
],
1814
"ModulusAnalysis Java/C#": [
1915
"java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll",
2016
"csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll"

csharp/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies:
99
codeql/controlflow: ${workspace}
1010
codeql/dataflow: ${workspace}
1111
codeql/mad: ${workspace}
12+
codeql/rangeanalysis: ${workspace}
1213
codeql/ssa: ${workspace}
1314
codeql/threat-models: ${workspace}
1415
codeql/tutorial: ${workspace}

csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll

Lines changed: 18 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,67 +4,31 @@
44
overlay[local?]
55
module;
66

7-
private import internal.rangeanalysis.BoundSpecific
7+
private import csharp as CS
8+
private import semmle.code.csharp.dataflow.SSA::Ssa
9+
private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU
10+
private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU
11+
private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU
12+
private import codeql.rangeanalysis.Bound as SharedBound
813

9-
private newtype TBound =
10-
TBoundZero() or
11-
TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or
12-
TBoundExpr(Expr e) {
13-
interestingExprBound(e) and
14-
not exists(SsaVariable v | e = v.getAUse())
15-
}
14+
/** Provides C#-specific definitions for bounds. */
15+
private module BoundDefs implements SharedBound::BoundDefinitions<CS::Location> {
16+
class Type = CS::Type;
1617

17-
/**
18-
* A bound that may be inferred for an expression plus/minus an integer delta.
19-
*/
20-
abstract class Bound extends TBound {
21-
/** Gets a textual representation of this bound. */
22-
abstract string toString();
18+
class SsaVariable = SU::SsaVariable;
2319

24-
/** Gets an expression that equals this bound plus `delta`. */
25-
abstract Expr getExpr(int delta);
20+
class SsaSourceVariable = SourceVariable;
2621

27-
/** Gets an expression that equals this bound. */
28-
Expr getExpr() { result = this.getExpr(0) }
22+
class Expr = CS::ControlFlowNodes::ExprNode;
2923

30-
/** Gets the location of this bound. */
31-
abstract Location getLocation();
32-
}
24+
class IntegralType = CS::IntegralType;
3325

34-
/**
35-
* The bound that corresponds to the integer 0. This is used to represent all
36-
* integer bounds as bounds are always accompanied by an added integer delta.
37-
*/
38-
class ZeroBound extends Bound, TBoundZero {
39-
override string toString() { result = "0" }
26+
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
4027

41-
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
42-
43-
override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) }
28+
/** Holds if `e` is a bound expression and it is not an SSA variable read. */
29+
predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) }
4430
}
4531

46-
/**
47-
* A bound corresponding to the value of an SSA variable.
48-
*/
49-
class SsaBound extends Bound, TBoundSsa {
50-
/** Gets the SSA variable that equals this bound. */
51-
SsaVariable getSsa() { this = TBoundSsa(result) }
52-
53-
override string toString() { result = this.getSsa().toString() }
32+
module BoundImpl = SharedBound::Bound<CS::Location, BoundDefs>;
5433

55-
override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 }
56-
57-
override Location getLocation() { result = this.getSsa().getLocation() }
58-
}
59-
60-
/**
61-
* A bound that corresponds to the value of a specific expression that might be
62-
* interesting, but isn't otherwise represented by the value of an SSA variable.
63-
*/
64-
class ExprBound extends Bound, TBoundExpr {
65-
override string toString() { result = this.getExpr().toString() }
66-
67-
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
68-
69-
override Location getLocation() { result = this.getExpr().getLocation() }
70-
}
34+
import BoundImpl

csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll

Lines changed: 0 additions & 22 deletions
This file was deleted.

java/ql/lib/semmle/code/java/dataflow/Bound.qll

Lines changed: 20 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,67 +4,33 @@
44
overlay[local?]
55
module;
66

7-
private import internal.rangeanalysis.BoundSpecific
8-
9-
private newtype TBound =
10-
TBoundZero() or
11-
TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or
12-
TBoundExpr(Expr e) {
13-
interestingExprBound(e) and
14-
not exists(SsaVariable v | e = v.getAUse())
7+
private import java as J
8+
private import semmle.code.java.dataflow.SSA
9+
private import semmle.code.java.dataflow.RangeUtils as RU
10+
private import codeql.rangeanalysis.Bound as SharedBound
11+
12+
private module BoundDefs implements SharedBound::BoundDefinitions<J::Location> {
13+
class SsaVariable extends Ssa::SsaDefinition {
14+
/** Gets a use of this variable. */
15+
Expr getAUse() { result = super.getARead() }
1516
}
1617

17-
/**
18-
* A bound that may be inferred for an expression plus/minus an integer delta.
19-
*/
20-
abstract class Bound extends TBound {
21-
/** Gets a textual representation of this bound. */
22-
abstract string toString();
23-
24-
/** Gets an expression that equals this bound plus `delta`. */
25-
abstract Expr getExpr(int delta);
26-
27-
/** Gets an expression that equals this bound. */
28-
Expr getExpr() { result = this.getExpr(0) }
18+
class SsaSourceVariable = Ssa::SourceVariable;
2919

30-
/** Gets the location of this bound. */
31-
abstract Location getLocation();
32-
}
20+
class Type = J::Type;
3321

34-
/**
35-
* The bound that corresponds to the integer 0. This is used to represent all
36-
* integer bounds as bounds are always accompanied by an added integer delta.
37-
*/
38-
class ZeroBound extends Bound, TBoundZero {
39-
override string toString() { result = "0" }
22+
class Expr = J::Expr;
4023

41-
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
24+
class IntegralType = J::IntegralType;
4225

43-
override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) }
44-
}
26+
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
4527

46-
/**
47-
* A bound corresponding to the value of an SSA variable.
48-
*/
49-
class SsaBound extends Bound, TBoundSsa {
50-
/** Gets the SSA variable that equals this bound. */
51-
SsaVariable getSsa() { this = TBoundSsa(result) }
52-
53-
override string toString() { result = this.getSsa().toString() }
54-
55-
override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 }
56-
57-
override Location getLocation() { result = this.getSsa().getLocation() }
28+
/** Holds if `e` is a bound expression and it is not an SSA variable read. */
29+
predicate interestingExprBound(Expr e) {
30+
e.(J::FieldRead).getField() instanceof J::ArrayLengthField
31+
}
5832
}
5933

60-
/**
61-
* A bound that corresponds to the value of a specific expression that might be
62-
* interesting, but isn't otherwise represented by the value of an SSA variable.
63-
*/
64-
class ExprBound extends Bound, TBoundExpr {
65-
override string toString() { result = this.getExpr().toString() }
34+
module BoundImpl = SharedBound::Bound<J::Location, BoundDefs>;
6635

67-
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
68-
69-
override Location getLocation() { result = this.getExpr().getLocation() }
70-
}
36+
import BoundImpl

java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* Provides classes for representing abstract bounds for use in, for example, range analysis.
3+
*/
4+
overlay[local?]
5+
module;
6+
7+
private import codeql.util.Location
8+
9+
signature module BoundDefinitions<LocationSig Location> {
10+
class Type;
11+
12+
class IntegralType extends Type;
13+
14+
class ConstantIntegerExpr extends Expr {
15+
int getIntValue();
16+
}
17+
18+
class SsaSourceVariable {
19+
Type getType();
20+
}
21+
22+
class SsaVariable {
23+
SsaSourceVariable getSourceVariable();
24+
25+
string toString();
26+
27+
Location getLocation();
28+
29+
Expr getAUse();
30+
}
31+
32+
class Expr {
33+
string toString();
34+
35+
Location getLocation();
36+
}
37+
38+
predicate interestingExprBound(Expr e);
39+
}
40+
41+
/**
42+
* Provides classes for representing abstract bounds for use in, for example, range analysis.
43+
* This is a generic implementation of bounds that relies on language specific modules to provide language-specific definitions of expressions, SSA variables, etc.
44+
*/
45+
overlay[local?]
46+
module Bound<LocationSig Location, BoundDefinitions<Location> Defs> {
47+
private import Defs
48+
49+
private newtype TBound =
50+
TBoundZero() or
51+
TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or
52+
TBoundExpr(Expr e) {
53+
interestingExprBound(e) and
54+
not exists(SsaVariable v | e = v.getAUse())
55+
}
56+
57+
/**
58+
* A bound that may be inferred for an expression plus/minus an integer delta.
59+
*/
60+
abstract class Bound extends TBound {
61+
/** Gets a textual representation of this bound. */
62+
abstract string toString();
63+
64+
/** Gets an expression that equals this bound plus `delta`. */
65+
abstract Expr getExpr(int delta);
66+
67+
/** Gets an expression that equals this bound. */
68+
Expr getExpr() { result = this.getExpr(0) }
69+
70+
/** Gets the location of this bound. */
71+
abstract Location getLocation();
72+
}
73+
74+
/**
75+
* The bound that corresponds to the integer 0. This is used to represent all
76+
* integer bounds as bounds are always accompanied by an added integer delta.
77+
*/
78+
class ZeroBound extends Bound, TBoundZero {
79+
override string toString() { result = "0" }
80+
81+
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
82+
83+
override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) }
84+
}
85+
86+
/**
87+
* A bound corresponding to the value of an SSA variable.
88+
*/
89+
class SsaBound extends Bound, TBoundSsa {
90+
/** Gets the SSA variable that equals this bound. */
91+
SsaVariable getSsa() { this = TBoundSsa(result) }
92+
93+
override string toString() { result = this.getSsa().toString() }
94+
95+
override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 }
96+
97+
override Location getLocation() { result = this.getSsa().getLocation() }
98+
}
99+
100+
/**
101+
* A bound that corresponds to the value of a specific expression that might be
102+
* interesting, but isn't otherwise represented by the value of an SSA variable.
103+
*/
104+
class ExprBound extends Bound, TBoundExpr {
105+
override string toString() { result = this.getExpr().toString() }
106+
107+
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
108+
109+
override Location getLocation() { result = this.getExpr().getLocation() }
110+
}
111+
}

0 commit comments

Comments
 (0)