Skip to content

Commit 8ada928

Browse files
committed
Merge branch 'main' into snake_case_pr
2 parents 9ed9ecd + b5872fe commit 8ada928

File tree

46 files changed

+926
-192
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+926
-192
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"slevesque.vscode-zipexplorer"
55
],
66
"settings": {
7-
"codeQL.experimentalBqrsParsing": true
7+
"codeQL.runningQueries.memory": 2048
88
}
99
}

change-notes/1.26/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
1313

1414
| **Query** | **Expected impact** | **Change** |
1515
|----------------------------|------------------------|------------------------------------------------------------------|
16+
| Declaration hides parameter (`cpp/declaration-hides-parameter`) | Fewer false positive results | False positives involving template functions have been fixed. |
1617
| Inconsistent direction of for loop (`cpp/inconsistent-loop-direction`) | Fewer false positive results | The query now accounts for intentional wrapping of an unsigned loop counter. |
1718
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | | The precision of this query has been decreased from "high" to "medium". As a result, the query is still run but results are no longer displayed on LGTM by default. |
1819
| Comparison result is always the same (`cpp/constant-comparison`) | More correct results | Bounds on expressions involving multiplication can now be determined in more cases. |

change-notes/1.26/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@
3333

3434

3535
## Changes to libraries
36+
* The predicate `TypeAnnotation.hasQualifiedName` now works in more cases when the imported library was not present during extraction.

cpp/ql/src/Best Practices/Hiding/DeclarationHidesParameter.ql

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,35 @@
1111

1212
import cpp
1313

14+
/**
15+
* Gets the template that a function `f` is constructed from, or just `f` if it
16+
* is not from a template instantiation.
17+
*/
18+
Function getConstructedFrom(Function f) {
19+
f.isConstructedFrom(result)
20+
or
21+
not f.isConstructedFrom(_) and
22+
result = f
23+
}
24+
1425
/**
1526
* Gets the parameter of `f` with name `name`, which has to come from the
1627
* _definition_ of `f` and not a prototype declaration.
1728
* We also exclude names from functions that have multiple definitions.
1829
* This should not happen in a single application but since we
1930
* have a system wide view it is likely to happen for instance for
2031
* the main function.
32+
*
33+
* Note: we use `getConstructedFrom` to ensure that we look at template
34+
* functions rather than their instantiations. We get better results this way
35+
* as the instantiation is artificial and may have inherited parameter names
36+
* from the declaration rather than the definition.
2137
*/
2238
ParameterDeclarationEntry functionParameterNames(Function f, string name) {
2339
exists(FunctionDeclarationEntry fe |
2440
result.getFunctionDeclarationEntry() = fe and
25-
fe.getFunction() = f and
41+
getConstructedFrom(f).getDefinition() = fe and
2642
fe.getLocation() = f.getDefinitionLocation() and
27-
result.getFile() = fe.getFile() and // Work around CPP-331
2843
strictcount(f.getDefinitionLocation()) = 1 and
2944
result.getName() = name
3045
)

cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Provides implementation classes modeling `std::string` and other
3-
* instantiations of`std::basic_string`. See `semmle.code.cpp.models.Models`
3+
* instantiations of `std::basic_string`. See `semmle.code.cpp.models.Models`
44
* for usage information.
55
*/
66

@@ -82,6 +82,32 @@ class StdStringData extends TaintFunction {
8282
}
8383
}
8484

85+
/**
86+
* The `std::string` function `push_back`.
87+
*/
88+
class StdStringPush extends TaintFunction {
89+
StdStringPush() { this.hasQualifiedName("std", "basic_string", "push_back") }
90+
91+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
92+
// flow from parameter to qualifier
93+
input.isParameterDeref(0) and
94+
output.isQualifierObject()
95+
}
96+
}
97+
98+
/**
99+
* The `std::string` functions `front` and `back`.
100+
*/
101+
class StdStringFrontBack extends TaintFunction {
102+
StdStringFrontBack() { this.hasQualifiedName("std", "basic_string", ["front", "back"]) }
103+
104+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
105+
// flow from object to returned reference
106+
input.isQualifierObject() and
107+
output.isReturnValueDeref()
108+
}
109+
}
110+
85111
/**
86112
* The `std::string` function `operator+`.
87113
*/
@@ -138,6 +164,11 @@ class StdStringAppend extends TaintFunction {
138164
output.isQualifierObject() or
139165
output.isReturnValueDeref()
140166
)
167+
or
168+
// reverse flow from returned reference to the qualifier (for writes to
169+
// the result)
170+
input.isReturnValueDeref() and
171+
output.isQualifierObject()
141172
}
142173
}
143174

@@ -173,6 +204,11 @@ class StdStringAssign extends TaintFunction {
173204
output.isQualifierObject() or
174205
output.isReturnValueDeref()
175206
)
207+
or
208+
// reverse flow from returned reference to the qualifier (for writes to
209+
// the result)
210+
input.isReturnValueDeref() and
211+
output.isQualifierObject()
176212
}
177213
}
178214

cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,17 @@ private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
11441144
if guardLB > defLB then result = guardLB else result = defLB
11451145
)
11461146
or
1147+
exists(VariableAccess access, float neConstant, float lower |
1148+
isNEPhi(v, phi, access, neConstant) and
1149+
lower = getFullyConvertedLowerBounds(access) and
1150+
if lower = neConstant then result = lower + 1 else result = lower
1151+
)
1152+
or
1153+
exists(VariableAccess access |
1154+
isUnsupportedGuardPhi(v, phi, access) and
1155+
result = getFullyConvertedLowerBounds(access)
1156+
)
1157+
or
11471158
result = getDefLowerBounds(phi.getAPhiInput(v), v)
11481159
}
11491160

@@ -1161,6 +1172,17 @@ private float getPhiUpperBounds(StackVariable v, RangeSsaDefinition phi) {
11611172
if guardUB < defUB then result = guardUB else result = defUB
11621173
)
11631174
or
1175+
exists(VariableAccess access, float neConstant, float upper |
1176+
isNEPhi(v, phi, access, neConstant) and
1177+
upper = getFullyConvertedUpperBounds(access) and
1178+
if upper = neConstant then result = upper - 1 else result = upper
1179+
)
1180+
or
1181+
exists(VariableAccess access |
1182+
isUnsupportedGuardPhi(v, phi, access) and
1183+
result = getFullyConvertedUpperBounds(access)
1184+
)
1185+
or
11641186
result = getDefUpperBounds(phi.getAPhiInput(v), v)
11651187
}
11661188

@@ -1423,22 +1445,13 @@ private predicate linearBoundFromGuard(
14231445
// 1. x <= upperbound(RHS)
14241446
// 2. x >= lowerbound(RHS)
14251447
//
1426-
// For x != RHS, we create trivial bounds:
1427-
//
1428-
// 1. x <= typeUpperBound(RHS.getUnspecifiedType())
1429-
// 2. x >= typeLowerBound(RHS.getUnspecifiedType())
1430-
//
1431-
exists(Expr lhs, Expr rhs, boolean isEQ |
1448+
exists(Expr lhs, Expr rhs |
14321449
linearAccess(lhs, v, p, q) and
1433-
eqOpWithSwapAndNegate(guard, lhs, rhs, isEQ, branch) and
1450+
eqOpWithSwapAndNegate(guard, lhs, rhs, true, branch) and
1451+
getBounds(rhs, boundValue, isLowerBound) and
14341452
strictness = Nonstrict()
1435-
|
1436-
// True branch
1437-
isEQ = true and getBounds(rhs, boundValue, isLowerBound)
1438-
or
1439-
// False branch: set the bounds to the min/max for the type.
1440-
isEQ = false and exprTypeBounds(rhs, boundValue, isLowerBound)
14411453
)
1454+
// x != RHS and !x are handled elsewhere
14421455
}
14431456

14441457
/** Utility for `linearBoundFromGuard`. */
@@ -1455,6 +1468,42 @@ private predicate exprTypeBounds(Expr expr, float boundValue, boolean isLowerBou
14551468
isLowerBound = false and boundValue = exprMaxVal(expr.getFullyConverted())
14561469
}
14571470

1471+
/**
1472+
* Holds if `(v, phi)` ensures that `access` is not equal to `neConstant`. For
1473+
* example, the condition `if (x + 1 != 3)` ensures that `x` is not equal to 2.
1474+
* Only integral types are supported.
1475+
*/
1476+
private predicate isNEPhi(
1477+
Variable v, RangeSsaDefinition phi, VariableAccess access, float neConstant
1478+
) {
1479+
exists(
1480+
ComparisonOperation cmp, boolean branch, Expr linearExpr, Expr rExpr, float p, float q, float r
1481+
|
1482+
access.getTarget() = v and
1483+
phi.isGuardPhi(access, cmp, branch) and
1484+
eqOpWithSwapAndNegate(cmp, linearExpr, rExpr, false, branch) and
1485+
v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!=` is too imprecise
1486+
r = getValue(rExpr).toFloat() and
1487+
linearAccess(linearExpr, access, p, q) and
1488+
neConstant = (r - q) / p
1489+
)
1490+
}
1491+
1492+
/**
1493+
* Holds if `(v, phi)` constrains the value of `access` but in a way that
1494+
* doesn't allow this library to constrain the upper or lower bounds of
1495+
* `access`. An example is `if (x != y)` if neither `x` nor `y` is a
1496+
* compile-time constant.
1497+
*/
1498+
private predicate isUnsupportedGuardPhi(Variable v, RangeSsaDefinition phi, VariableAccess access) {
1499+
exists(ComparisonOperation cmp, boolean branch |
1500+
access.getTarget() = v and
1501+
phi.isGuardPhi(access, cmp, branch) and
1502+
eqOpWithSwapAndNegate(cmp, _, _, false, branch) and
1503+
not isNEPhi(v, phi, access, _)
1504+
)
1505+
}
1506+
14581507
cached
14591508
private module SimpleRangeAnalysisCached {
14601509
/**

0 commit comments

Comments
 (0)