Skip to content

Commit b0242dc

Browse files
authored
C++: more idiomatic BufferWriteEstimationReason
1 parent 160635b commit b0242dc

File tree

2 files changed

+26
-30
lines changed

2 files changed

+26
-30
lines changed

cpp/ql/lib/semmle/code/cpp/commons/Printf.qll

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,30 @@ private newtype TBufferWriteEstimationReason =
1616
/**
1717
* A reason for a specific buffer write size estimate
1818
*/
19-
class BufferWriteEstimationReason extends TBufferWriteEstimationReason {
20-
BufferWriteEstimationReason() {
21-
this = TTypeBoundsAnalysis() or
22-
this = TValueFlowAnalysis()
23-
}
24-
19+
abstract class BufferWriteEstimationReason extends TBufferWriteEstimationReason {
2520
/**
2621
* Returns a human readable representation of this reason
2722
*/
28-
string toString() {
29-
this = TTypeBoundsAnalysis() and result = "based on type bounds"
30-
or
31-
this = TValueFlowAnalysis() and result = "based on flow analysis of value bounds"
32-
}
23+
abstract string toString();
3324

3425
/**
3526
* Combine estimate reasons. Used to give a reason for the size of a format string
3627
* conversion given reasons coming from its individual specifiers
3728
*/
38-
BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
39-
(this = TTypeBoundsAnalysis() or other = TTypeBoundsAnalysis()) and
40-
result = TTypeBoundsAnalysis()
41-
or
42-
(this = TValueFlowAnalysis() and other = TValueFlowAnalysis()) and
43-
result = TValueFlowAnalysis()
44-
}
29+
abstract BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other);
4530
}
4631

4732
/**
4833
* The estimation comes from rough bounds just based on the type (e.g.
4934
* `0 <= x < 2^32` for an unsigned 32 bit integer)
5035
*/
51-
BufferWriteEstimationReason typeBoundsAnalysis() { result = TTypeBoundsAnalysis() }
36+
class TypeBoundsAnalysis extends BufferWriteEstimationReason, TTypeBoundsAnalysis {
37+
override string toString() { result = "based on type bounds" }
38+
39+
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
40+
result = TTypeBoundsAnalysis() and other = other
41+
}
42+
}
5243

5344
/**
5445
* The estimation comes from non trivial bounds found via actual flow analysis.
@@ -60,7 +51,14 @@ BufferWriteEstimationReason typeBoundsAnalysis() { result = TTypeBoundsAnalysis(
6051
* }
6152
* ```
6253
*/
63-
BufferWriteEstimationReason valueFlowAnalysis() { result = TValueFlowAnalysis() }
54+
class ValueFlowAnalysis extends BufferWriteEstimationReason, TValueFlowAnalysis {
55+
override string toString() { result = "based on flow analysis of value bounds" }
56+
57+
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
58+
other = TTypeBoundsAnalysis() and result = TTypeBoundsAnalysis() or
59+
other = TValueFlowAnalysis() and result = TValueFlowAnalysis()
60+
}
61+
}
6462

6563
class PrintfFormatAttribute extends FormatAttribute {
6664
PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
@@ -1043,7 +1041,7 @@ class FormatLiteral extends Literal {
10431041
* conversion specifier of this format string; has no result if this cannot
10441042
* be determined.
10451043
*/
1046-
int getMaxConvertedLength(int n) { result = max(int l | l = getMaxConvertedLength(n, _) | l) }
1044+
int getMaxConvertedLength(int n) { result = max(getMaxConvertedLength(n, _)) }
10471045

10481046
/**
10491047
* Gets the maximum length of the string that can be produced by the nth
@@ -1263,9 +1261,7 @@ class FormatLiteral extends Literal {
12631261
* determining whether a buffer overflow is caused by long float to string
12641262
* conversions.
12651263
*/
1266-
int getMaxConvertedLengthLimited(int n) {
1267-
result = max(int l | l = getMaxConvertedLengthLimited(n, _) | l)
1268-
}
1264+
int getMaxConvertedLengthLimited(int n) { result = max(getMaxConvertedLengthLimited(n, _)) }
12691265

12701266
/**
12711267
* Gets the maximum length of the string that can be produced by the nth

cpp/ql/lib/semmle/code/cpp/security/BufferWrite.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ abstract class BufferWrite extends Expr {
6969
* Gets an upper bound to the amount of data that's being written (if one
7070
* can be found).
7171
*/
72-
int getMaxData() { result = max(int d | d = getMaxData(_) | d) }
72+
int getMaxData() { result = max(getMaxData(_)) }
7373

7474
/**
7575
* Gets an upper bound to the amount of data that's being written (if one
7676
* can be found), except that float to string conversions are assumed to be
7777
* much smaller (8 bytes) than their true maximum length. This can be
7878
* helpful in determining the cause of a buffer overflow issue.
7979
*/
80-
int getMaxDataLimited() { result = max(int d | d = getMaxDataLimited(_) | d) }
80+
int getMaxDataLimited() { result = max(getMaxDataLimited(_)) }
8181

8282
/**
8383
* Gets an upper bound to the amount of data that's being written (if one
@@ -152,7 +152,7 @@ class StrCopyBW extends BufferWriteCall {
152152

153153
override int getMaxData(BufferWriteEstimationReason reason) {
154154
// when result exists, it is an exact flow analysis
155-
reason = valueFlowAnalysis() and
155+
reason instanceof ValueFlowAnalysis and
156156
result =
157157
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
158158
}
@@ -192,7 +192,7 @@ class StrCatBW extends BufferWriteCall {
192192

193193
override int getMaxData(BufferWriteEstimationReason reason) {
194194
// when result exists, it is an exact flow analysis
195-
reason = valueFlowAnalysis() and
195+
reason instanceof ValueFlowAnalysis and
196196
result =
197197
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
198198
}
@@ -457,7 +457,7 @@ class ScanfBW extends BufferWrite {
457457

458458
override int getMaxData(BufferWriteEstimationReason reason) {
459459
// when this returns, it is based on exact flow analysis
460-
reason = valueFlowAnalysis() and
460+
reason instanceof ValueFlowAnalysis and
461461
exists(ScanfFunctionCall fc, ScanfFormatLiteral fl, int arg |
462462
this = fc.getArgument(arg) and
463463
fl = fc.getFormat() and
@@ -497,7 +497,7 @@ class RealpathBW extends BufferWriteCall {
497497

498498
override int getMaxData(BufferWriteEstimationReason reason) {
499499
// although there may be some unknown invariants guaranteeing that a real path is shorter than PATH_MAX, we can consider providing less than PATH_MAX a problem with high precision
500-
reason = valueFlowAnalysis() and
500+
reason instanceof ValueFlowAnalysis and
501501
result = path_max() and
502502
this = this // Suppress a compiler warning
503503
}

0 commit comments

Comments
 (0)