mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
C++: add reason to buffer write estimations
This commit is contained in:
@@ -9,6 +9,30 @@ import semmle.code.cpp.models.interfaces.FormattingFunction
|
||||
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
|
||||
private newtype TBufferWriteEstimationReason =
|
||||
TTypeBoundsAnalysis() or
|
||||
TValueFlowAnalysis()
|
||||
|
||||
class BufferWriteEstimationReason extends TBufferWriteEstimationReason {
|
||||
BufferWriteEstimationReason() {
|
||||
this = TTypeBoundsAnalysis() or
|
||||
this = TValueFlowAnalysis()
|
||||
}
|
||||
|
||||
string toString() {
|
||||
this = TTypeBoundsAnalysis() and result = "based on type bounds" or
|
||||
this = TValueFlowAnalysis() and result = "based on flow analysis of value bounds"
|
||||
}
|
||||
|
||||
BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
|
||||
(this = TTypeBoundsAnalysis() or other = TTypeBoundsAnalysis()) and result = TTypeBoundsAnalysis() or
|
||||
(this = TValueFlowAnalysis() and other = TValueFlowAnalysis()) and result = TValueFlowAnalysis()
|
||||
}
|
||||
}
|
||||
|
||||
BufferWriteEstimationReason typeBoundsAnalysis() { result = TTypeBoundsAnalysis() }
|
||||
BufferWriteEstimationReason valueFlowAnalysis() { result = TValueFlowAnalysis() }
|
||||
|
||||
class PrintfFormatAttribute extends FormatAttribute {
|
||||
PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
|
||||
}
|
||||
@@ -990,7 +1014,7 @@ class FormatLiteral extends Literal {
|
||||
* conversion specifier of this format string; has no result if this cannot
|
||||
* be determined.
|
||||
*/
|
||||
int getMaxConvertedLength(int n) {
|
||||
int getMaxConvertedLength(int n, BufferWriteEstimationReason reason) {
|
||||
exists(int len |
|
||||
(
|
||||
(
|
||||
@@ -1002,10 +1026,10 @@ class FormatLiteral extends Literal {
|
||||
) and
|
||||
(
|
||||
this.getConversionChar(n) = "%" and
|
||||
len = 1
|
||||
len = 1 and reason = TValueFlowAnalysis()
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "c" and
|
||||
len = 1 // e.g. 'a'
|
||||
len = 1 and reason = TValueFlowAnalysis() // e.g. 'a'
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "f" and
|
||||
exists(int dot, int afterdot |
|
||||
@@ -1019,7 +1043,7 @@ class FormatLiteral extends Literal {
|
||||
afterdot = 6
|
||||
) and
|
||||
len = 1 + 309 + dot + afterdot
|
||||
) // e.g. -1e308="-100000"...
|
||||
) and reason = TTypeBoundsAnalysis() // e.g. -1e308="-100000"...
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "e" and
|
||||
exists(int dot, int afterdot |
|
||||
@@ -1033,7 +1057,7 @@ class FormatLiteral extends Literal {
|
||||
afterdot = 6
|
||||
) and
|
||||
len = 1 + 1 + dot + afterdot + 1 + 1 + 3
|
||||
) // -1e308="-1.000000e+308"
|
||||
) and reason = TTypeBoundsAnalysis() // -1e308="-1.000000e+308"
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "g" and
|
||||
exists(int dot, int afterdot |
|
||||
@@ -1056,67 +1080,78 @@ class FormatLiteral extends Literal {
|
||||
// (e.g. 123456, 0.000123456 are just OK)
|
||||
// so case %f can be at most P characters + 4 zeroes, sign, dot = P + 6
|
||||
len = (afterdot.maximum(1) + 6).maximum(1 + 1 + dot + afterdot + 1 + 1 + 3)
|
||||
) // (e.g. "-1.59203e-319")
|
||||
) and reason = TTypeBoundsAnalysis() // (e.g. "-1.59203e-319")
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = ["d", "i"] and
|
||||
// e.g. -2^31 = "-2147483648"
|
||||
len =
|
||||
min(float cand |
|
||||
exists(float typeBasedBound, float valueBasedBound |
|
||||
// The first case handles length sub-specifiers
|
||||
// Subtract one in the exponent because one bit is for the sign.
|
||||
// Add 1 to account for the possible sign in the output.
|
||||
cand = 1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1))
|
||||
or
|
||||
typeBasedBound = 1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1)) and
|
||||
// The second case uses range analysis to deduce a length that's shorter than the length
|
||||
// of the number -2^31.
|
||||
exists(Expr arg, float lower, float upper |
|
||||
exists(Expr arg, float lower, float upper, float typeLower, float typeUpper |
|
||||
arg = this.getUse().getConversionArgument(n) and
|
||||
lower = lowerBound(arg.getFullyConverted()) and
|
||||
upper = upperBound(arg.getFullyConverted())
|
||||
upper = upperBound(arg.getFullyConverted()) and
|
||||
typeLower = exprMinVal(arg.getFullyConverted()) and
|
||||
typeUpper = exprMaxVal(arg.getFullyConverted())
|
||||
|
|
||||
cand =
|
||||
max(int cand0 |
|
||||
valueBasedBound =
|
||||
max(int cand |
|
||||
// Include the sign bit in the length if it can be negative
|
||||
(
|
||||
if lower < 0
|
||||
then cand0 = 1 + lengthInBase10(lower.abs())
|
||||
else cand0 = lengthInBase10(lower)
|
||||
then cand = 1 + lengthInBase10(lower.abs())
|
||||
else cand = lengthInBase10(lower)
|
||||
)
|
||||
or
|
||||
(
|
||||
if upper < 0
|
||||
then cand0 = 1 + lengthInBase10(upper.abs())
|
||||
else cand0 = lengthInBase10(upper)
|
||||
then cand = 1 + lengthInBase10(upper.abs())
|
||||
else cand = lengthInBase10(upper)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
) and
|
||||
(
|
||||
if lower > typeLower or upper < typeUpper
|
||||
then reason = TValueFlowAnalysis()
|
||||
else reason = TTypeBoundsAnalysis()
|
||||
)
|
||||
) and
|
||||
len = valueBasedBound.minimum(typeBasedBound)
|
||||
)
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "u" and
|
||||
// e.g. 2^32 - 1 = "4294967295"
|
||||
len =
|
||||
min(float cand |
|
||||
exists(float typeBasedBound, float valueBasedBound |
|
||||
// The first case handles length sub-specifiers
|
||||
cand = 2.pow(this.getIntegralDisplayType(n).getSize() * 8)
|
||||
or
|
||||
typeBasedBound = lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8) - 1) and
|
||||
// The second case uses range analysis to deduce a length that's shorter than
|
||||
// the length of the number 2^31 - 1.
|
||||
exists(Expr arg, float lower |
|
||||
exists(Expr arg, float lower, float upper, float typeLower, float typeUpper |
|
||||
arg = this.getUse().getConversionArgument(n) and
|
||||
lower = lowerBound(arg.getFullyConverted())
|
||||
lower = lowerBound(arg.getFullyConverted()) and
|
||||
upper = upperBound(arg.getFullyConverted()) and
|
||||
typeLower = exprMinVal(arg.getFullyConverted()) and
|
||||
typeUpper = exprMaxVal(arg.getFullyConverted())
|
||||
|
|
||||
cand =
|
||||
max(float cand0 |
|
||||
valueBasedBound =
|
||||
lengthInBase10(max(float cand |
|
||||
// If lower can be negative we use `(unsigned)-1` as the candidate value.
|
||||
lower < 0 and
|
||||
cand0 = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
|
||||
cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
|
||||
or
|
||||
cand0 = upperBound(arg.getFullyConverted())
|
||||
)
|
||||
)
|
||||
|
|
||||
lengthInBase10(cand)
|
||||
)
|
||||
cand = upper
|
||||
)) and
|
||||
(
|
||||
if lower > typeLower or upper < typeUpper
|
||||
then reason = TValueFlowAnalysis()
|
||||
else reason = TTypeBoundsAnalysis()
|
||||
)
|
||||
) and
|
||||
len = valueBasedBound.minimum(typeBasedBound)
|
||||
)
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "x" and
|
||||
// e.g. "12345678"
|
||||
@@ -1135,7 +1170,7 @@ class FormatLiteral extends Literal {
|
||||
(
|
||||
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||
)
|
||||
)
|
||||
) and reason = TTypeBoundsAnalysis()
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "p" and
|
||||
exists(PointerType ptrType, int baseLen |
|
||||
@@ -1144,7 +1179,7 @@ class FormatLiteral extends Literal {
|
||||
(
|
||||
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
|
||||
)
|
||||
)
|
||||
) and reason = TValueFlowAnalysis()
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "o" and
|
||||
// e.g. 2^32 - 1 = "37777777777"
|
||||
@@ -1163,14 +1198,15 @@ class FormatLiteral extends Literal {
|
||||
(
|
||||
if this.hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
|
||||
)
|
||||
)
|
||||
) and reason = TTypeBoundsAnalysis()
|
||||
or
|
||||
this.getConversionChar(n).toLowerCase() = "s" and
|
||||
len =
|
||||
min(int v |
|
||||
v = this.getPrecision(n) or
|
||||
v = this.getUse().getFormatArgument(n).(AnalysedString).getMaxLength() - 1 // (don't count null terminator)
|
||||
)
|
||||
) and
|
||||
reason = TValueFlowAnalysis()
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -1182,10 +1218,10 @@ class FormatLiteral extends Literal {
|
||||
* determining whether a buffer overflow is caused by long float to string
|
||||
* conversions.
|
||||
*/
|
||||
int getMaxConvertedLengthLimited(int n) {
|
||||
int getMaxConvertedLengthLimited(int n, BufferWriteEstimationReason reason) {
|
||||
if this.getConversionChar(n).toLowerCase() = "f"
|
||||
then result = this.getMaxConvertedLength(n).minimum(8)
|
||||
else result = this.getMaxConvertedLength(n)
|
||||
then result = this.getMaxConvertedLength(n, reason).minimum(8)
|
||||
else result = this.getMaxConvertedLength(n, reason)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1225,29 +1261,35 @@ class FormatLiteral extends Literal {
|
||||
)
|
||||
}
|
||||
|
||||
private int getMaxConvertedLengthAfter(int n) {
|
||||
private int getMaxConvertedLengthAfter(int n, BufferWriteEstimationReason reason) {
|
||||
if n = this.getNumConvSpec()
|
||||
then result = this.getConstantSuffix().length() + 1
|
||||
then result = this.getConstantSuffix().length() + 1 and reason = TValueFlowAnalysis()
|
||||
else
|
||||
result =
|
||||
this.getConstantPart(n).length() + this.getMaxConvertedLength(n) +
|
||||
this.getMaxConvertedLengthAfter(n + 1)
|
||||
exists(BufferWriteEstimationReason headReason, BufferWriteEstimationReason tailReason |
|
||||
result =
|
||||
this.getConstantPart(n).length() + this.getMaxConvertedLength(n, headReason) +
|
||||
this.getMaxConvertedLengthAfter(n + 1, tailReason) and
|
||||
reason = headReason.combineWith(tailReason)
|
||||
)
|
||||
}
|
||||
|
||||
private int getMaxConvertedLengthAfterLimited(int n) {
|
||||
private int getMaxConvertedLengthAfterLimited(int n, BufferWriteEstimationReason reason) {
|
||||
if n = this.getNumConvSpec()
|
||||
then result = this.getConstantSuffix().length() + 1
|
||||
then result = this.getConstantSuffix().length() + 1 and reason = TValueFlowAnalysis()
|
||||
else
|
||||
exists(BufferWriteEstimationReason headReason, BufferWriteEstimationReason tailReason |
|
||||
result =
|
||||
this.getConstantPart(n).length() + this.getMaxConvertedLengthLimited(n) +
|
||||
this.getMaxConvertedLengthAfterLimited(n + 1)
|
||||
this.getConstantPart(n).length() + this.getMaxConvertedLengthLimited(n, headReason) +
|
||||
this.getMaxConvertedLengthAfterLimited(n + 1, tailReason) and
|
||||
reason = headReason.combineWith(tailReason)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum length of the string that can be produced by this format
|
||||
* string. Has no result if this cannot be determined.
|
||||
*/
|
||||
int getMaxConvertedLength() { result = this.getMaxConvertedLengthAfter(0) }
|
||||
int getMaxConvertedLength() { result = this.getMaxConvertedLengthAfter(0, _) }
|
||||
|
||||
/**
|
||||
* Gets the maximum length of the string that can be produced by this format
|
||||
@@ -1255,5 +1297,13 @@ class FormatLiteral extends Literal {
|
||||
* characters. This is helpful for determining whether a buffer overflow
|
||||
* is caused by long float to string conversions.
|
||||
*/
|
||||
int getMaxConvertedLengthLimited() { result = this.getMaxConvertedLengthAfterLimited(0) }
|
||||
int getMaxConvertedLengthLimited() { result = this.getMaxConvertedLengthAfterLimited(0, _) }
|
||||
|
||||
int getMaxConvertedLengthWithReason(BufferWriteEstimationReason reason) {
|
||||
result = this.getMaxConvertedLengthAfter(0, reason)
|
||||
}
|
||||
|
||||
int getMaxConvertedLengthLimitedWithReason(BufferWriteEstimationReason reason) {
|
||||
result = this.getMaxConvertedLengthAfterLimited(0, reason)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ abstract class BufferWrite extends Expr {
|
||||
* Gets an upper bound to the amount of data that's being written (if one
|
||||
* can be found).
|
||||
*/
|
||||
int getMaxData() { none() }
|
||||
int getMaxData() { result = max(int d | d = getMaxDataWithReason(_) | d) }
|
||||
|
||||
/**
|
||||
* Gets an upper bound to the amount of data that's being written (if one
|
||||
@@ -77,7 +77,12 @@ abstract class BufferWrite extends Expr {
|
||||
* much smaller (8 bytes) than their true maximum length. This can be
|
||||
* helpful in determining the cause of a buffer overflow issue.
|
||||
*/
|
||||
int getMaxDataLimited() { result = this.getMaxData() }
|
||||
int getMaxDataLimited() { result = max(int d | d = getMaxDataLimitedWithReason(_) | d) }
|
||||
|
||||
|
||||
int getMaxDataWithReason(BufferWriteEstimationReason reason) { none() }
|
||||
|
||||
int getMaxDataLimitedWithReason(BufferWriteEstimationReason reason) { result = getMaxDataWithReason(reason) }
|
||||
|
||||
/**
|
||||
* Gets the size of a single character of the type this
|
||||
@@ -135,7 +140,9 @@ class StrCopyBW extends BufferWriteCall {
|
||||
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
|
||||
}
|
||||
|
||||
override int getMaxData() {
|
||||
override int getMaxDataWithReason(BufferWriteEstimationReason reason) {
|
||||
// when result exists, it is an exact flow analysis
|
||||
reason = valueFlowAnalysis() and
|
||||
result =
|
||||
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
|
||||
}
|
||||
@@ -173,7 +180,9 @@ class StrCatBW extends BufferWriteCall {
|
||||
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
|
||||
}
|
||||
|
||||
override int getMaxData() {
|
||||
override int getMaxDataWithReason(BufferWriteEstimationReason reason) {
|
||||
// when result exists, it is an exact flow analysis
|
||||
reason = valueFlowAnalysis() and
|
||||
result =
|
||||
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
|
||||
}
|
||||
@@ -233,17 +242,17 @@ class SprintfBW extends BufferWriteCall {
|
||||
|
||||
override Expr getDest() { result = this.getArgument(f.getOutputParameterIndex(false)) }
|
||||
|
||||
override int getMaxData() {
|
||||
override int getMaxDataWithReason(BufferWriteEstimationReason reason) {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLength() * this.getCharSize()
|
||||
result = fl.getMaxConvertedLengthWithReason(reason) * this.getCharSize()
|
||||
)
|
||||
}
|
||||
|
||||
override int getMaxDataLimited() {
|
||||
override int getMaxDataLimitedWithReason(BufferWriteEstimationReason reason) {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
|
||||
result = fl.getMaxConvertedLengthLimitedWithReason(reason) * this.getCharSize()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -336,17 +345,17 @@ class SnprintfBW extends BufferWriteCall {
|
||||
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
|
||||
}
|
||||
|
||||
override int getMaxData() {
|
||||
override int getMaxDataWithReason(BufferWriteEstimationReason reason) {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLength() * this.getCharSize()
|
||||
result = fl.getMaxConvertedLengthWithReason(reason) * this.getCharSize()
|
||||
)
|
||||
}
|
||||
|
||||
override int getMaxDataLimited() {
|
||||
override int getMaxDataLimitedWithReason(BufferWriteEstimationReason reason) {
|
||||
exists(FormatLiteral fl |
|
||||
fl = this.(FormattingFunctionCall).getFormat() and
|
||||
result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
|
||||
result = fl.getMaxConvertedLengthLimitedWithReason(reason) * this.getCharSize()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -436,7 +445,9 @@ class ScanfBW extends BufferWrite {
|
||||
|
||||
override Expr getDest() { result = this }
|
||||
|
||||
override int getMaxData() {
|
||||
override int getMaxDataWithReason(BufferWriteEstimationReason reason) {
|
||||
// when this returns, it is based on exact flow analysis
|
||||
reason = valueFlowAnalysis() and
|
||||
exists(ScanfFunctionCall fc, ScanfFormatLiteral fl, int arg |
|
||||
this = fc.getArgument(arg) and
|
||||
fl = fc.getFormat() and
|
||||
@@ -474,7 +485,9 @@ class RealpathBW extends BufferWriteCall {
|
||||
|
||||
override Expr getASource() { result = this.getArgument(0) }
|
||||
|
||||
override int getMaxData() {
|
||||
override int getMaxDataWithReason(BufferWriteEstimationReason reason) {
|
||||
// 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
|
||||
reason = valueFlowAnalysis() and
|
||||
result = path_max() and
|
||||
this = this // Suppress a compiler warning
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@ import semmle.code.cpp.commons.Alloc
|
||||
* See CWE-120/UnboundedWrite.ql for a summary of CWE-120 alert cases.
|
||||
*/
|
||||
|
||||
from BufferWrite bw, Expr dest, int destSize
|
||||
from BufferWrite bw, Expr dest, int destSize, BufferWriteEstimationReason reason
|
||||
where
|
||||
not bw.hasExplicitLimit() and // has no explicit size limit
|
||||
dest = bw.getDest() and
|
||||
destSize = getBufferSize(dest, _) and
|
||||
// we can deduce that too much data may be copied (even without
|
||||
// long '%f' conversions)
|
||||
bw.getMaxDataLimited() > destSize
|
||||
bw.getMaxDataLimitedWithReason(reason) > destSize
|
||||
select bw,
|
||||
"This '" + bw.getBWDesc() + "' operation requires " + bw.getMaxData() +
|
||||
" bytes but the destination is only " + destSize + " bytes."
|
||||
" bytes but the destination is only " + destSize + " bytes (" + reason.toString() + ")."
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
| tests2.cpp:17:3:17:8 | call to wcscpy | This 'call to wcscpy' operation requires 12 bytes but the destination is only 8 bytes. |
|
||||
| tests2.cpp:22:3:22:8 | call to wcscpy | This 'call to wcscpy' operation requires 16 bytes but the destination is only 12 bytes. |
|
||||
| tests2.cpp:27:3:27:8 | call to wcscpy | This 'call to wcscpy' operation requires 20 bytes but the destination is only 16 bytes. |
|
||||
| tests2.cpp:31:3:31:8 | call to wcscpy | This 'call to wcscpy' operation requires 24 bytes but the destination is only 20 bytes. |
|
||||
| tests2.cpp:36:3:36:8 | call to wcscpy | This 'call to wcscpy' operation requires 28 bytes but the destination is only 24 bytes. |
|
||||
| tests2.cpp:41:3:41:8 | call to wcscpy | This 'call to wcscpy' operation requires 32 bytes but the destination is only 28 bytes. |
|
||||
| tests2.cpp:46:3:46:8 | call to wcscpy | This 'call to wcscpy' operation requires 36 bytes but the destination is only 32 bytes. |
|
||||
| tests.c:54:3:54:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||
| tests.c:58:3:58:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||
| tests.c:62:17:62:24 | buffer10 | This 'scanf string argument' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||
| tests.c:63:17:63:24 | buffer10 | This 'scanf string argument' operation requires 12 bytes but the destination is only 10 bytes. |
|
||||
| tests.c:86:3:86:8 | call to strcpy | This 'call to strcpy' operation requires 6 bytes but the destination is only 5 bytes. |
|
||||
| tests.c:93:3:93:8 | call to strcpy | This 'call to strcpy' operation requires 6 bytes but the destination is only 5 bytes. |
|
||||
| tests.c:120:3:120:9 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 1 bytes. |
|
||||
| tests.c:121:3:121:9 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 16 bytes. |
|
||||
| tests.c:136:2:136:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
|
||||
| unions.c:32:2:32:7 | call to strcpy | This 'call to strcpy' operation requires 31 bytes but the destination is only 25 bytes. |
|
||||
| var_size_struct.cpp:22:3:22:8 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 9 bytes. |
|
||||
| tests2.cpp:17:3:17:8 | call to wcscpy | This 'call to wcscpy' operation requires 12 bytes but the destination is only 8 bytes (based on flow analysis of value bounds). |
|
||||
| tests2.cpp:22:3:22:8 | call to wcscpy | This 'call to wcscpy' operation requires 16 bytes but the destination is only 12 bytes (based on flow analysis of value bounds). |
|
||||
| tests2.cpp:27:3:27:8 | call to wcscpy | This 'call to wcscpy' operation requires 20 bytes but the destination is only 16 bytes (based on flow analysis of value bounds). |
|
||||
| tests2.cpp:31:3:31:8 | call to wcscpy | This 'call to wcscpy' operation requires 24 bytes but the destination is only 20 bytes (based on flow analysis of value bounds). |
|
||||
| tests2.cpp:36:3:36:8 | call to wcscpy | This 'call to wcscpy' operation requires 28 bytes but the destination is only 24 bytes (based on flow analysis of value bounds). |
|
||||
| tests2.cpp:41:3:41:8 | call to wcscpy | This 'call to wcscpy' operation requires 32 bytes but the destination is only 28 bytes (based on flow analysis of value bounds). |
|
||||
| tests2.cpp:46:3:46:8 | call to wcscpy | This 'call to wcscpy' operation requires 36 bytes but the destination is only 32 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:54:3:54:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:58:3:58:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:62:17:62:24 | buffer10 | This 'scanf string argument' operation requires 11 bytes but the destination is only 10 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:63:17:63:24 | buffer10 | This 'scanf string argument' operation requires 12 bytes but the destination is only 10 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:86:3:86:8 | call to strcpy | This 'call to strcpy' operation requires 6 bytes but the destination is only 5 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:93:3:93:8 | call to strcpy | This 'call to strcpy' operation requires 6 bytes but the destination is only 5 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:120:3:120:9 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 1 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:121:3:121:9 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 16 bytes (based on flow analysis of value bounds). |
|
||||
| tests.c:136:2:136:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes (based on flow analysis of value bounds). |
|
||||
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes (based on flow analysis of value bounds). |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes (based on flow analysis of value bounds). |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes (based on flow analysis of value bounds). |
|
||||
| unions.c:32:2:32:7 | call to strcpy | This 'call to strcpy' operation requires 31 bytes but the destination is only 25 bytes (based on flow analysis of value bounds). |
|
||||
| var_size_struct.cpp:22:3:22:8 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 9 bytes (based on flow analysis of value bounds). |
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
| tests.cpp:258:2:258:8 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 10 bytes. |
|
||||
| tests.cpp:259:2:259:8 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 10 bytes. |
|
||||
| tests.cpp:272:2:272:8 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 8 bytes. |
|
||||
| tests.cpp:273:2:273:8 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 8 bytes. |
|
||||
| tests.cpp:308:3:308:9 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 8 bytes. |
|
||||
| tests.cpp:315:2:315:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes. |
|
||||
| tests.cpp:316:2:316:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes. |
|
||||
| tests.cpp:321:2:321:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes. |
|
||||
| tests.cpp:324:3:324:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes. |
|
||||
| tests.cpp:327:2:327:8 | call to sprintf | This 'call to sprintf' operation requires 12 bytes but the destination is only 4 bytes. |
|
||||
| tests.cpp:329:3:329:9 | call to sprintf | This 'call to sprintf' operation requires 12 bytes but the destination is only 4 bytes. |
|
||||
| tests.cpp:341:2:341:8 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes. |
|
||||
| tests.cpp:343:2:343:8 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes. |
|
||||
| tests.cpp:345:2:345:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 2 bytes. |
|
||||
| tests.cpp:347:2:347:8 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes. |
|
||||
| tests.cpp:350:2:350:8 | call to sprintf | This 'call to sprintf' operation requires 4 bytes but the destination is only 3 bytes. |
|
||||
| tests.cpp:354:2:354:8 | call to sprintf | This 'call to sprintf' operation requires 4 bytes but the destination is only 3 bytes. |
|
||||
| tests.cpp:358:2:358:8 | call to sprintf | This 'call to sprintf' operation requires 4 bytes but the destination is only 3 bytes. |
|
||||
| tests.cpp:363:2:363:8 | call to sprintf | This 'call to sprintf' operation requires 5 bytes but the destination is only 4 bytes. |
|
||||
| tests.cpp:258:2:258:8 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 10 bytes (based on type bounds). |
|
||||
| tests.cpp:259:2:259:8 | call to sprintf | This 'call to sprintf' operation requires 17 bytes but the destination is only 10 bytes (based on type bounds). |
|
||||
| tests.cpp:272:2:272:8 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 8 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:273:2:273:8 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 8 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:308:3:308:9 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 8 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:315:2:315:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes (based on type bounds). |
|
||||
| tests.cpp:316:2:316:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes (based on type bounds). |
|
||||
| tests.cpp:321:2:321:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:324:3:324:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 4 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:327:2:327:8 | call to sprintf | This 'call to sprintf' operation requires 12 bytes but the destination is only 4 bytes (based on type bounds). |
|
||||
| tests.cpp:329:3:329:9 | call to sprintf | This 'call to sprintf' operation requires 12 bytes but the destination is only 4 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:341:2:341:8 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:343:2:343:8 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:345:2:345:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 2 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:347:2:347:8 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:350:2:350:8 | call to sprintf | This 'call to sprintf' operation requires 4 bytes but the destination is only 3 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:354:2:354:8 | call to sprintf | This 'call to sprintf' operation requires 4 bytes but the destination is only 3 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:358:2:358:8 | call to sprintf | This 'call to sprintf' operation requires 4 bytes but the destination is only 3 bytes (based on flow analysis of value bounds). |
|
||||
| tests.cpp:363:2:363:8 | call to sprintf | This 'call to sprintf' operation requires 5 bytes but the destination is only 4 bytes (based on flow analysis of value bounds). |
|
||||
|
||||
Reference in New Issue
Block a user