Merge pull request #275 from owen-mc/incorrect-integer-conversion

Incorrect integer conversion
This commit is contained in:
Max Schaefer
2020-08-13 20:19:47 +01:00
committed by GitHub
25 changed files with 1189 additions and 772 deletions

View File

@@ -107,6 +107,7 @@ ql/src/go.dbscheme.stats: ql/src/go.dbscheme build/stats/src.stamp extractor
test: all build/testdb/check-upgrade-path
codeql test run ql/test --search-path .
env GOARCH=386 codeql$(EXE) test run ql/test/query-tests/Security/CWE-681 --search-path .
cd extractor; go test -mod=vendor ./... | grep -vF "[no test files]"
.PHONY: build/testdb/check-upgrade-path

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Query "Incorrect integer conversion" (`go/incorrect-integer-conversion`) is promoted from experimental status. This checks for parsing a string to an integer and then assigning it to an integer type of a smaller bit size.

View File

@@ -0,0 +1,74 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If a string is parsed into an int using <code>strconv.Atoi</code>, and subsequently that int
is converted into another integer type of a smaller size, the result can produce unexpected values.
</p>
<p>
This also applies to the results of <code>strconv.ParseInt</code> and <code>strconv.ParseUint</code> when
the specified size is larger than the size of the type that number is converted to.
</p>
</overview>
<recommendation>
<p>
If you need to parse integer values with specific bit sizes, avoid <code>strconv.Atoi</code>, and instead
use <code>strconv.ParseInt</code> or <code>strconv.ParseUint</code>, which also allow specifying the
bit size.
</p>
<p>
When using those functions, be careful to not convert the result to another type with a smaller bit size than
the bit size you specified when parsing the number.
</p>
<p>
If this is not possible, then add upper (and lower) bound checks specific to each type and
bit size (you can find the minimum and maximum value for each type in the <code>math</code> package).
</p>
</recommendation>
<example>
<p>
In the first example, assume that an input string is passed to <code>parseAllocateBad1</code> function,
parsed by <code>strconv.Atoi</code>, and then converted into an <code>int32</code> type:
</p>
<sample src="IncorrectIntegerConversion.go"/>
<p>
The bounds are not checked, so this means that if the provided number is greater than the maximum value of type <code>int32</code>,
the resulting value from the conversion will be different from the actual provided value.
</p>
<p>
To avoid unexpected values, you should either use the other functions provided by the <code>strconv</code>
package to parse the specific types and bit sizes as shown in the
<code>parseAllocateGood2</code> function; or check bounds as in the <code>parseAllocateGood1</code>
function.
</p>
<sample src="IncorrectIntegerConversionGood.go"/>
</example>
<example>
<p>
In the second example, assume that an input string is passed to <code>parseAllocateBad2</code> function,
parsed by <code>strconv.ParseInt</code> with a bit size set to 64, and then converted into an <code>int32</code> type:
</p>
<sample src="IncorrectIntegerConversion.go"/>
<p>
If the provided number is greater than the maximum value of type <code>int32</code>, the resulting value from the conversion will be
different from the actual provided value.
</p>
<p>
To avoid unexpected values, you should specify the correct bit size as in <code>parseAllocateGood3</code>;
or check bounds before making the conversion as in <code>parseAllocateGood4</code>.
</p>
<sample src="IncorrectIntegerConversionGood.go"/>
</example>
<references>
<li>Wikipedia <a href="https://en.wikipedia.org/wiki/Integer_overflow">Integer overflow</a>.</li>
<li>Go language specification <a href="https://golang.org/ref/spec#Integer_overflow">Integer overflow</a>.</li>
<li>Documentation for <a href="https://golang.org/pkg/strconv/#Atoi"><code>strconv.Atoi</code></a>.</li>
<li>Documentation for <a href="https://golang.org/pkg/strconv/#ParseInt"><code>strconv.ParseInt</code></a>.</li>
<li>Documentation for <a href="https://golang.org/pkg/strconv/#ParseUint"><code>strconv.ParseUint</code></a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,203 @@
/**
* @name Incorrect conversion between integer types
* @description Converting the result of `strconv.Atoi`, `strconv.ParseInt`,
* and `strconv.ParseUint` to integer types of smaller bit size
* can produce unexpected values.
* @kind path-problem
* @problem.severity warning
* @id go/incorrect-integer-conversion
* @tags security
* external/cwe/cwe-190
* external/cwe/cwe-681
* @precision very-high
*/
import go
import DataFlow::PathGraph
/**
* Gets the maximum value of an integer (signed if `isSigned`
* is true, unsigned otherwise) with `bitSize` bits.
*/
float getMaxIntValue(int bitSize, boolean isSigned) {
bitSize in [8, 16, 32] and
(
isSigned = true and result = 2.pow(bitSize - 1) - 1
or
isSigned = false and result = 2.pow(bitSize) - 1
)
}
/**
* Get the size of `int` or `uint` in `file`, or 0 if it is
* architecture-specific.
*/
int getIntTypeBitSize(File file) {
file.constrainsIntBitSize(result)
or
not file.constrainsIntBitSize(_) and
result = 0
}
/**
* Holds if converting from an integer types with size `sourceBitSize` to
* one with size `sinkBitSize` can produce unexpected values, where 0 means
* architecture-dependent.
*
* Architecture-dependent bit sizes can be 32 or 64. To catch flows that
* only manifest on 64-bit architectures we consider an
* architecture-dependent source bit size to be 64. To catch flows that
* only happen on 32-bit architectures we consider an
* architecture-dependent sink bit size to be 32. We exclude the case where
* both source and sink have architecture-dependent bit sizes.
*/
private predicate isIncorrectIntegerConversion(int sourceBitSize, int sinkBitSize) {
sourceBitSize in [16, 32, 64] and
sinkBitSize in [8, 16, 32] and
sourceBitSize > sinkBitSize
or
// Treat `sourceBitSize = 0` like `sourceBitSize = 64`, and exclude `sinkBitSize = 0`
sourceBitSize = 0 and
sinkBitSize in [8, 16, 32]
or
// Treat `sinkBitSize = 0` like `sinkBitSize = 32`, and exclude `sourceBitSize = 0`
sourceBitSize = 64 and
sinkBitSize = 0
}
/**
* A taint-tracking configuration for reasoning about when an integer
* obtained from parsing a string flows to a type conversion to a smaller
* integer types, which could cause unexpected values.
*/
class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration {
boolean sourceIsSigned;
int sourceBitSize;
int sinkBitSize;
ConversionWithoutBoundsCheckConfig() {
sourceIsSigned in [true, false] and
isIncorrectIntegerConversion(sourceBitSize, sinkBitSize) and
this = "ConversionWithoutBoundsCheckConfig" + sourceBitSize + sourceIsSigned + sinkBitSize
}
/** Gets the bit size of the source. */
int getSourceBitSize() { result = sourceBitSize }
override predicate isSource(DataFlow::Node source) {
exists(
DataFlow::CallNode c, IntegerParser::Range ip, int apparentBitSize, int effectiveBitSize
|
c.getTarget() = ip and source = c.getResult(0)
|
(
if ip.getResultType(0) instanceof SignedIntegerType
then sourceIsSigned = true
else sourceIsSigned = false
) and
(
apparentBitSize = ip.getTargetBitSize()
or
// If we are reading a variable, check if it is
// `strconv.IntSize`, and use 0 if it is.
exists(DataFlow::Node rawBitSize | rawBitSize = ip.getTargetBitSizeInput().getNode(c) |
if rawBitSize = any(StrConv::IntSize intSize).getARead()
then apparentBitSize = 0
else apparentBitSize = rawBitSize.getIntValue()
)
) and
(
if apparentBitSize = 0
then effectiveBitSize = getIntTypeBitSize(source.getFile())
else effectiveBitSize = apparentBitSize
) and
// `effectiveBitSize` could be any value between 0 and 64, but we
// can round it up to the nearest size of an integer type without
// changing behaviour.
sourceBitSize = min(int b | b in [0, 8, 16, 32, 64] and b >= effectiveBitSize)
)
}
/**
* Holds if `sink` is a typecast to an integer type with size `bitSize` (where
* 0 represents architecture-dependent) and the expression being typecast is
* not also in a right-shift expression. We allow this case because it is
* a common pattern to serialise `byte(v)`, `byte(v >> 8)`, and so on.
*/
predicate isSink(DataFlow::TypeCastNode sink, int bitSize) {
exists(IntegerType integerType | sink.getType().getUnderlyingType() = integerType |
bitSize = integerType.getSize()
or
not exists(integerType.getSize()) and
bitSize = getIntTypeBitSize(sink.getFile())
) and
not exists(ShrExpr shrExpr |
shrExpr.getLeftOperand().getGlobalValueNumber() =
sink.getOperand().asExpr().getGlobalValueNumber() or
shrExpr.getLeftOperand().(AndExpr).getAnOperand().getGlobalValueNumber() =
sink.getOperand().asExpr().getGlobalValueNumber()
)
}
override predicate isSink(DataFlow::Node sink) { isSink(sink, sinkBitSize) }
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
// To catch flows that only happen on 32-bit architectures we
// consider an architecture-dependent sink bit size to be 32.
exists(int bitSize | if sinkBitSize != 0 then bitSize = sinkBitSize else bitSize = 32 |
guard.(UpperBoundCheckGuard).getBound() <= getMaxIntValue(bitSize, sourceIsSigned)
)
}
override predicate isSanitizerOut(DataFlow::Node node) {
exists(int bitSize | isIncorrectIntegerConversion(sourceBitSize, bitSize) |
isSink(node, bitSize)
)
}
}
/** An upper bound check that compares a variable to a constant value. */
class UpperBoundCheckGuard extends DataFlow::BarrierGuard, DataFlow::RelationalComparisonNode {
UpperBoundCheckGuard() { count(expr.getAnOperand().getIntValue()) = 1 }
/**
* Gets the constant value which this upper bound check ensures the
* other value is less than or equal to.
*/
float getBound() {
exists(int strictnessOffset |
if expr.isStrict() then strictnessOffset = 1 else strictnessOffset = 0
|
result = expr.getAnOperand().getExactValue().toFloat() - strictnessOffset
)
}
override predicate checks(Expr e, boolean branch) {
this.leq(branch, DataFlow::exprNode(e), _, _) and
not exists(e.getIntValue())
}
}
/** Gets a string describing the size of the integer parsed. */
string describeBitSize(int bitSize, int intTypeBitSize) {
intTypeBitSize in [0, 32, 64] and
if bitSize != 0
then bitSize in [8, 16, 32, 64] and result = "a " + bitSize + "-bit integer"
else
if intTypeBitSize = 0
then result = "an integer with architecture-dependent bit size"
else
result =
"a number with architecture-dependent bit-width, which is constrained to be " +
intTypeBitSize + "-bit by build constraints,"
}
from
DataFlow::PathNode source, DataFlow::PathNode sink, ConversionWithoutBoundsCheckConfig cfg,
DataFlow::CallNode call
where cfg.hasFlowPath(source, sink) and call.getResult(0) = source.getNode()
select sink.getNode(), source, sink,
"Incorrect conversion of " +
describeBitSize(cfg.getSourceBitSize(), getIntTypeBitSize(source.getNode().getFile())) +
" from $@ to a lower bit size type " + sink.getNode().getType().getUnderlyingType().getName() +
" without an upper bound check.", source, call.getTarget().getQualifiedName()

View File

@@ -16,7 +16,7 @@ func parseAllocateGood1(desired string) int32 {
if err != nil {
return DefaultAllocate
}
// GOOD: check for lower and uppper bounds
// GOOD: check for lower and upper bounds
if parsed > 0 && parsed <= math.MaxInt32 {
return int32(parsed)
}

View File

@@ -1,65 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If a numeric value string is parsed using <code>strconv.Atoi</code> into an int, and subsequently that int
is converted into another type of a smaller size, the result can produce unexpected values.
</p>
<p>
This also applies to the results of <code>strconv.ParseFloat</code>, <code>strconv.ParseInt</code>,
and <code>strconv.ParseUint</code> when the specified size is larger than the size of the
type that number is converted to.
</p>
</overview>
<recommendation>
<p>
If you need to parse numeric values with specific bit sizes, avoid <code>strconv.Atoi</code>, and instead
use the functions specific to each type (<code>strconv.ParseFloat</code>, <code>strconv.ParseInt</code>,
<code>strconv.ParseUint</code>) that also allow to specify the wanted bit size.
</p>
<p>
When using those functions, be careful to not convert the result to another type with a smaller bit size than
the bit size you specified when parsing the number.
</p>
<p>
If this is not possible, then add upper (and lower) bound checks specific to each type and
bit size (you can find the minimum and maximum value for each type in the `math` package).
</p>
</recommendation>
<example>
<p>
In the first example, assume that an input string is passed to <code>parseAllocateBad1</code> function,
parsed by <code>strconv.Atoi</code>, and then converted into an <code>int32</code> type:
</p>
<sample src="IncorrectNumericConversion.go"/>
<p>
The bounds are not checked, so this means that if the provided number is greater than the maximum value of type <code>int32</code>,
the resulting value from the conversion will be different from the actual provided value.
</p>
<p>
To avoid unexpected values, you should either use the other functions provided by the <code>strconv</code>
package to parse the specific types and bit sizes as shown in the
<code>parseAllocateGood2</code> function; or check bounds as in the <code>parseAllocateGood1</code>
function.
</p>
<sample src="IncorrectNumericConversionGood.go"/>
</example>
<example>
<p>
In the second example, assume that an input string is passed to <code>parseAllocateBad2</code> function,
parsed by <code>strconv.ParseInt</code> with a bit size set to 64, and then converted into an <code>int32</code> type:
</p>
<sample src="IncorrectNumericConversion.go"/>
<p>
If the provided number is greater than the maximum value of type <code>int32</code>, the resulting value from the conversion will be
different from the actual provided value.
</p>
<p>
To avoid unexpected values, you should specify the correct bit size as in <code>parseAllocateGood3</code>;
or check bounds before making the conversion as in <code>parseAllocateGood4</code>.
</p>
<sample src="IncorrectNumericConversionGood.go"/>
</example>
</qhelp>

View File

@@ -1,266 +0,0 @@
/**
* @name Incorrect conversion between numeric types
* @description Converting the result of strconv.Atoi (and other parsers from strconv package)
* to numeric types of smaller bit size can produce unexpected values.
* @kind path-problem
* @problem.severity warning
* @id go/incorrect-numeric-conversion
* @tags security
* external/cwe/cwe-190
* external/cwe/cwe-681
*/
import go
import DataFlow::PathGraph
/** A function that parses integers. */
class Atoi extends Function {
Atoi() { this.hasQualifiedName("strconv", "Atoi") }
}
/** A function that parses floating-point numbers. */
class ParseFloat extends Function {
ParseFloat() { this.hasQualifiedName("strconv", "ParseFloat") }
}
/** A function that parses integers with a specifiable bitSize. */
class ParseInt extends Function {
ParseInt() { this.hasQualifiedName("strconv", "ParseInt") }
}
/** A function that parses unsigned integers with a specifiable bitSize. */
class ParseUint extends Function {
ParseUint() { this.hasQualifiedName("strconv", "ParseUint") }
}
/** Provides a class for modeling calls to number-parsing functions. */
module ParserCall {
/**
* A data-flow call node that parses a number.
*/
abstract class Range extends DataFlow::CallNode {
/** Gets the bit size of the result number. */
abstract int getTargetBitSize();
/** Gets the name of the parser function. */
abstract string getParserName();
}
}
class ParserCall extends DataFlow::CallNode {
ParserCall::Range self;
ParserCall() { this = self }
int getTargetBitSize() { result = self.getTargetBitSize() }
string getParserName() { result = self.getParserName() }
}
class AtoiCall extends DataFlow::CallNode, ParserCall::Range {
AtoiCall() { exists(Atoi atoi | this = atoi.getACall()) }
override int getTargetBitSize() { result = 0 }
override string getParserName() { result = "strconv.Atoi" }
}
class ParseIntCall extends DataFlow::CallNode, ParserCall::Range {
ParseIntCall() { exists(ParseInt parseInt | this = parseInt.getACall()) }
override int getTargetBitSize() { result = this.getArgument(2).getIntValue() }
override string getParserName() { result = "strconv.ParseInt" }
}
class ParseUintCall extends DataFlow::CallNode, ParserCall::Range {
ParseUintCall() { exists(ParseUint parseUint | this = parseUint.getACall()) }
override int getTargetBitSize() { result = this.getArgument(2).getIntValue() }
override string getParserName() { result = "strconv.ParseUint" }
}
class ParseFloatCall extends DataFlow::CallNode, ParserCall::Range {
ParseFloatCall() { exists(ParseFloat parseFloat | this = parseFloat.getACall()) }
override int getTargetBitSize() { result = this.getArgument(1).getIntValue() }
override string getParserName() { result = "strconv.ParseFloat" }
}
class NumericConversionExpr extends ConversionExpr {
string fullTypeName;
int bitSize;
NumericConversionExpr() {
exists(NumericType conv |
conv = getTypeExpr().getType().getUnderlyingType() and
fullTypeName = conv.getName() and
bitSize = conv.getSize()
)
}
string getFullTypeName() { result = fullTypeName }
int getBitSize() { result = bitSize }
}
/**
* An `if` statement with the condition being either a relational comparison,
* or one or more `&&`.
*/
class IfRelationalComparison extends IfStmt {
IfRelationalComparison() {
this.getCond() instanceof RelationalComparisonExpr or this.getCond() instanceof LandExpr
}
RelationalComparisonExpr getComparison() { result = this.getCond().(RelationalComparisonExpr) }
LandExpr getLandExpr() { result = this.getCond().(LandExpr) }
}
/**
* Flow of result of parsing a 64 bit number, to conversion to lower bit numbers.
*/
class Lt64BitFlowConfig extends TaintTracking::Configuration, DataFlow::Configuration {
Lt64BitFlowConfig() { this = "Lt64BitFlowConfig" }
override predicate isSource(DataFlow::Node source) {
exists(ParserCall call | call.getTargetBitSize() = [0, 64] | source = call)
}
override predicate isSink(DataFlow::Node sink) {
exists(NumericConversionExpr conv | conv.getBitSize() = [32, 16, 8] | sink.asExpr() = conv)
}
override predicate isSanitizerIn(DataFlow::Node node) { isSanitizedInsideAnIfBoundCheck(node) }
}
/**
* Flow of result of parsing a 32 bit number, to conversion to lower bit numbers.
*/
class Lt32BitFlowConfig extends TaintTracking::Configuration, DataFlow::Configuration {
Lt32BitFlowConfig() { this = "Lt32BitFlowConfig" }
override predicate isSource(DataFlow::Node source) {
// NOTE: target bit size 0 is already addressed in Lt64BitFlowConfig.
exists(ParserCall call | call.getTargetBitSize() = [/*0,*/ 32] | source = call)
}
override predicate isSink(DataFlow::Node sink) {
exists(NumericConversionExpr conv | conv.getBitSize() = [16, 8] | sink.asExpr() = conv)
}
override predicate isSanitizerIn(DataFlow::Node node) { isSanitizedInsideAnIfBoundCheck(node) }
}
/**
* Flow of result of parsing a 16 bit number, to conversion to lower bit numbers.
*/
class Lt16BitFlowConfig extends TaintTracking::Configuration, DataFlow::Configuration {
Lt16BitFlowConfig() { this = "Lt16BitFlowConfig" }
override predicate isSource(DataFlow::Node source) {
exists(ParserCall call | call.getTargetBitSize() = 16 | source = call)
}
override predicate isSink(DataFlow::Node sink) {
exists(NumericConversionExpr conv | conv.getBitSize() = 8 | sink.asExpr() = conv)
}
override predicate isSanitizerIn(DataFlow::Node node) { isSanitizedInsideAnIfBoundCheck(node) }
}
/**
* Check if the node is a numeric conversion inside an `if` body, where
* the `if` condition contains an upper bound check on the conversion operand.
*/
predicate isSanitizedInsideAnIfBoundCheck(DataFlow::Node node) {
exists(IfRelationalComparison comp, NumericConversionExpr conv |
conv = node.asExpr().(NumericConversionExpr) and
conv.getBitSize() = [8, 16, 32] and
comp.getThen().getAChild*() = conv and
(
// If the conversion is inside an `if` block that compares the source as
// `source > 0` or `source >= 0`, then that sanitizes conversion of int to int32;
conv.getFullTypeName() = "int32" and
comp.getComparison().getLesserOperand().getNumericValue() = 0 and
comp.getComparison().getGreaterOperand().getGlobalValueNumber() =
conv.getOperand().getGlobalValueNumber()
or
comparisonGreaterOperandValueIsEqual("int8", comp, conv, getMaxInt8())
or
comparisonGreaterOperandValueIsEqual("int16", comp, conv, getMaxInt16())
or
comparisonGreaterOperandValueIsEqual("int32", comp, conv, getMaxInt32())
or
comparisonGreaterOperandValueIsEqual("uint8", comp, conv, getMaxUint8())
or
comparisonGreaterOperandValueIsEqual("uint16", comp, conv, getMaxUint16())
)
)
}
int getMaxInt8() { result = 2.pow(7) - 1 }
int getMaxInt16() { result = 2.pow(15) - 1 }
int getMaxInt32() { result = 2.pow(31) - 1 }
int getMaxUint8() { result = 2.pow(8) - 1 }
int getMaxUint16() { result = 2.pow(16) - 1 }
/**
* The `if` relational comparison (which can also be inside a `LandExpr`) stating that
* the greater operand is equal to `value`, and the lesses operand is the conversion operand.
*/
predicate comparisonGreaterOperandValueIsEqual(
string typeName, IfRelationalComparison ifExpr, NumericConversionExpr conv, int value
) {
conv.getFullTypeName() = typeName and
(
// exclude cases like: if parsed < math.MaxInt8 {return int8(parsed)}
exists(RelationalComparisonExpr comp | comp = ifExpr.getComparison() |
// greater operand is equal to value:
comp.getGreaterOperand().getNumericValue() = value and
// and lesser is the conversion operand:
comp.getLesserOperand().getGlobalValueNumber() = conv.getOperand().getGlobalValueNumber()
)
or
// exclude cases like: if err == nil && parsed < math.MaxInt8 {return int8(parsed)}
exists(RelationalComparisonExpr andExpr |
andExpr = ifExpr.getLandExpr().getAnOperand().(RelationalComparisonExpr)
|
// greater operand is equal to value:
andExpr.getGreaterOperand().getNumericValue() = value and
// and lesser is the conversion operand:
andExpr.getLesserOperand().getGlobalValueNumber() = conv.getOperand().getGlobalValueNumber()
)
)
}
string formatBitSize(ParserCall call) {
call.getTargetBitSize() = 0 and result = "(arch-dependent)"
or
call.getTargetBitSize() > 0 and result = call.getTargetBitSize().toString()
}
from DataFlow::PathNode source, DataFlow::PathNode sink
where
(
exists(Lt64BitFlowConfig cfg | cfg.hasFlowPath(source, sink))
or
exists(Lt32BitFlowConfig cfg | cfg.hasFlowPath(source, sink))
or
exists(Lt16BitFlowConfig cfg | cfg.hasFlowPath(source, sink))
) and
// Exclude results in test files:
exists(File fl | fl = sink.getNode().asExpr().(NumericConversionExpr).getFile() |
not fl instanceof TestFile
)
select source.getNode(), source, sink,
"Incorrect conversion of a " + formatBitSize(source.getNode().(ParserCall)) + "-bit number from " +
source.getNode().(ParserCall).getParserName() + " result to a lower bit size type " +
sink.getNode().asExpr().(NumericConversionExpr).getFullTypeName()

View File

@@ -3,6 +3,7 @@
*/
import Customizations
import semmle.go.Architectures
import semmle.go.AST
import semmle.go.Comments
import semmle.go.Concepts

View File

@@ -0,0 +1,27 @@
/** Provides classes for working with architectures. */
import go
/**
* An architecture that is valid in a build constraint.
*
* Information obtained from
* https://github.com/golang/go/blob/98cbf45cfc6a5a50cc6ac2367f9572cb198b57c7/src/go/types/gccgosizes.go
* where the first field of the struct is 4 for 32-bit architectures
* and 8 for 64-bit architectures.
*/
class Architecture extends string {
int bitSize;
Architecture() {
this in ["386", "amd64p32", "arm", "armbe", "mips", "mipsle", "mips64p32", "mips64p32le", "ppc",
"s390", "sparc"] and
bitSize = 32
or
this in ["amd64", "arm64", "arm64be", "ppc64", "ppc64le", "mips64", "mips64le", "s390x",
"sparc64"] and
bitSize = 64
}
int getBitSize() { result = bitSize }
}

View File

@@ -211,4 +211,10 @@ class BuildConstraintComment extends LineComment {
}
override string getAPrimaryQlClass() { result = "BuildConstraintComment" }
/** Gets the body of this build constraint. */
string getConstraintBody() { result = getText().splitAt("+build ", 1) }
/** Gets a disjunct of this build constraint. */
string getADisjunct() { result = getConstraintBody().splitAt(" ") }
}

View File

@@ -203,6 +203,40 @@ class File extends Container, @file, Documentable, ExprParent, GoModExprParent,
pragma[noinline]
predicate hasBuildConstraints() { exists(BuildConstraintComment bc | this = bc.getFile()) }
/**
* Holds if this file contains build constraints that ensure that it
* is only built on architectures of bit size `bitSize`, which can be
* 32 or 64.
*/
predicate constrainsIntBitSize(int bitSize) {
explicitlyConstrainsIntBitSize(bitSize) or
implicitlyConstrainsIntBitSize(bitSize)
}
/**
* Holds if this file contains explicit build constraints that ensure
* that it is only built on an architecture of bit size `bitSize`,
* which can be 32 or 64.
*/
predicate explicitlyConstrainsIntBitSize(int bitSize) {
exists(BuildConstraintComment bcc | this = bcc.getFile() |
forex(string disjunct | disjunct = bcc.getADisjunct() |
disjunct.splitAt(",").(Architecture).getBitSize() = bitSize
)
)
}
/**
* Holds if this file has a name which acts as an implicit build
* constraint that ensures that it is only built on an
* architecture of bit size `bitSize`, which can be 32 or 64.
*/
predicate implicitlyConstrainsIntBitSize(int bitSize) {
exists(Architecture arch | arch.getBitSize() = bitSize |
this.getStem().regexpMatch("(?i).*_\\Q" + arch + "\\E(_test)?")
)
}
override string toString() { result = Container.super.toString() }
/** Gets the URL of this file. */

View File

@@ -168,7 +168,7 @@ module ControlFlow {
}
/**
* A control-flow node recording the fact that a certain expression is has a known
* A control-flow node recording the fact that a certain expression has a known
* Boolean value at this point in the program.
*/
class ConditionGuardNode extends IR::Instruction, MkConditionGuardNode {

View File

@@ -512,6 +512,65 @@ module Path {
}
}
/** Provides a class for modeling functions which convert strings into integers. */
module IntegerParser {
/**
* A function that converts strings into integers.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `IntegerParser` instead.
*/
abstract class Range extends Function {
/**
* Gets the maximum bit size of the return value, if this makes
* sense, where 0 represents the bit size of `int` and `uint`.
*/
int getTargetBitSize() { none() }
/**
* Gets the `FunctionInput` containing the maximum bit size of the
* return value, if this makes sense. Note that if the value of the
* input is 0 then it means the bit size of `int` and `uint`.
*/
FunctionInput getTargetBitSizeInput() { none() }
}
}
/**
* Provides classes for some functions in the `strconv` package for
* converting strings to numbers.
*/
module StrConv {
/** The `Atoi` function. */
class Atoi extends IntegerParser::Range {
Atoi() { this.hasQualifiedName("strconv", "Atoi") }
override int getTargetBitSize() { result = 0 }
}
/** The `ParseInt` function. */
class ParseInt extends IntegerParser::Range {
ParseInt() { this.hasQualifiedName("strconv", "ParseInt") }
override FunctionInput getTargetBitSizeInput() { result.isParameter(2) }
}
/** The `ParseUint` function. */
class ParseUint extends IntegerParser::Range {
ParseUint() { this.hasQualifiedName("strconv", "ParseUint") }
override FunctionInput getTargetBitSizeInput() { result.isParameter(2) }
}
/**
* The `IntSize` constant, that gives the size in bits of an `int` or
* `uint` value on the current architecture (32 or 64).
*/
class IntSize extends DeclaredConstant {
IntSize() { this.hasQualifiedName("strconv", "IntSize") }
}
}
/** Provides models of commonly used functions in the `strings` package. */
module Strings {
/** The `Join` function. */

View File

@@ -1,83 +0,0 @@
edges
| IncorrectNumericConversion.go:26:14:26:28 | call to Atoi : tuple type | IncorrectNumericConversion.go:35:41:35:50 | type conversion |
| IncorrectNumericConversion.go:53:18:53:47 | call to ParseFloat : tuple type | IncorrectNumericConversion.go:57:7:57:19 | type conversion |
| IncorrectNumericConversion.go:60:18:60:47 | call to ParseFloat : tuple type | IncorrectNumericConversion.go:64:7:64:19 | type conversion |
| IncorrectNumericConversion.go:69:18:69:49 | call to ParseInt : tuple type | IncorrectNumericConversion.go:73:7:73:18 | type conversion |
| IncorrectNumericConversion.go:76:18:76:49 | call to ParseInt : tuple type | IncorrectNumericConversion.go:80:7:80:19 | type conversion |
| IncorrectNumericConversion.go:83:18:83:49 | call to ParseInt : tuple type | IncorrectNumericConversion.go:87:7:87:19 | type conversion |
| IncorrectNumericConversion.go:90:18:90:48 | call to ParseInt : tuple type | IncorrectNumericConversion.go:94:7:94:19 | type conversion |
| IncorrectNumericConversion.go:99:18:99:50 | call to ParseUint : tuple type | IncorrectNumericConversion.go:103:7:103:18 | type conversion |
| IncorrectNumericConversion.go:106:18:106:50 | call to ParseUint : tuple type | IncorrectNumericConversion.go:110:7:110:19 | type conversion |
| IncorrectNumericConversion.go:113:18:113:50 | call to ParseUint : tuple type | IncorrectNumericConversion.go:117:7:117:19 | type conversion |
| IncorrectNumericConversion.go:120:18:120:49 | call to ParseUint : tuple type | IncorrectNumericConversion.go:124:7:124:19 | type conversion |
| IncorrectNumericConversion.go:208:18:208:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:212:7:212:18 | type conversion |
| IncorrectNumericConversion.go:215:18:215:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:219:7:219:19 | type conversion |
| IncorrectNumericConversion.go:222:18:222:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:226:7:226:19 | type conversion |
| IncorrectNumericConversion.go:229:18:229:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:233:7:233:19 | type conversion |
| IncorrectNumericConversion.go:236:18:236:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:240:7:240:20 | type conversion |
| IncorrectNumericConversion.go:243:18:243:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:247:7:247:20 | type conversion |
| IncorrectNumericConversion.go:250:18:250:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:254:7:254:21 | type conversion |
| IncorrectNumericConversion.go:257:18:257:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:262:7:262:18 | type conversion |
| IncorrectNumericConversion.go:266:18:266:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:270:7:270:23 | type conversion |
nodes
| IncorrectNumericConversion.go:26:14:26:28 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:35:41:35:50 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:53:18:53:47 | call to ParseFloat : tuple type | semmle.label | call to ParseFloat : tuple type |
| IncorrectNumericConversion.go:57:7:57:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:60:18:60:47 | call to ParseFloat : tuple type | semmle.label | call to ParseFloat : tuple type |
| IncorrectNumericConversion.go:64:7:64:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:69:18:69:49 | call to ParseInt : tuple type | semmle.label | call to ParseInt : tuple type |
| IncorrectNumericConversion.go:73:7:73:18 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:76:18:76:49 | call to ParseInt : tuple type | semmle.label | call to ParseInt : tuple type |
| IncorrectNumericConversion.go:80:7:80:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:83:18:83:49 | call to ParseInt : tuple type | semmle.label | call to ParseInt : tuple type |
| IncorrectNumericConversion.go:87:7:87:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:90:18:90:48 | call to ParseInt : tuple type | semmle.label | call to ParseInt : tuple type |
| IncorrectNumericConversion.go:94:7:94:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:99:18:99:50 | call to ParseUint : tuple type | semmle.label | call to ParseUint : tuple type |
| IncorrectNumericConversion.go:103:7:103:18 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:106:18:106:50 | call to ParseUint : tuple type | semmle.label | call to ParseUint : tuple type |
| IncorrectNumericConversion.go:110:7:110:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:113:18:113:50 | call to ParseUint : tuple type | semmle.label | call to ParseUint : tuple type |
| IncorrectNumericConversion.go:117:7:117:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:120:18:120:49 | call to ParseUint : tuple type | semmle.label | call to ParseUint : tuple type |
| IncorrectNumericConversion.go:124:7:124:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:208:18:208:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:212:7:212:18 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:215:18:215:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:219:7:219:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:222:18:222:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:226:7:226:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:229:18:229:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:233:7:233:19 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:236:18:236:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:240:7:240:20 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:243:18:243:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:247:7:247:20 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:250:18:250:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:254:7:254:21 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:257:18:257:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:262:7:262:18 | type conversion | semmle.label | type conversion |
| IncorrectNumericConversion.go:266:18:266:36 | call to Atoi : tuple type | semmle.label | call to Atoi : tuple type |
| IncorrectNumericConversion.go:270:7:270:23 | type conversion | semmle.label | type conversion |
#select
| IncorrectNumericConversion.go:26:14:26:28 | call to Atoi | IncorrectNumericConversion.go:26:14:26:28 | call to Atoi : tuple type | IncorrectNumericConversion.go:35:41:35:50 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type int32 |
| IncorrectNumericConversion.go:53:18:53:47 | call to ParseFloat | IncorrectNumericConversion.go:53:18:53:47 | call to ParseFloat : tuple type | IncorrectNumericConversion.go:57:7:57:19 | type conversion | Incorrect conversion of a 32-bit number from strconv.ParseFloat result to a lower bit size type int16 |
| IncorrectNumericConversion.go:60:18:60:47 | call to ParseFloat | IncorrectNumericConversion.go:60:18:60:47 | call to ParseFloat : tuple type | IncorrectNumericConversion.go:64:7:64:19 | type conversion | Incorrect conversion of a 64-bit number from strconv.ParseFloat result to a lower bit size type int32 |
| IncorrectNumericConversion.go:69:18:69:49 | call to ParseInt | IncorrectNumericConversion.go:69:18:69:49 | call to ParseInt : tuple type | IncorrectNumericConversion.go:73:7:73:18 | type conversion | Incorrect conversion of a 16-bit number from strconv.ParseInt result to a lower bit size type int8 |
| IncorrectNumericConversion.go:76:18:76:49 | call to ParseInt | IncorrectNumericConversion.go:76:18:76:49 | call to ParseInt : tuple type | IncorrectNumericConversion.go:80:7:80:19 | type conversion | Incorrect conversion of a 32-bit number from strconv.ParseInt result to a lower bit size type int16 |
| IncorrectNumericConversion.go:83:18:83:49 | call to ParseInt | IncorrectNumericConversion.go:83:18:83:49 | call to ParseInt : tuple type | IncorrectNumericConversion.go:87:7:87:19 | type conversion | Incorrect conversion of a 64-bit number from strconv.ParseInt result to a lower bit size type int32 |
| IncorrectNumericConversion.go:90:18:90:48 | call to ParseInt | IncorrectNumericConversion.go:90:18:90:48 | call to ParseInt : tuple type | IncorrectNumericConversion.go:94:7:94:19 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.ParseInt result to a lower bit size type int32 |
| IncorrectNumericConversion.go:99:18:99:50 | call to ParseUint | IncorrectNumericConversion.go:99:18:99:50 | call to ParseUint : tuple type | IncorrectNumericConversion.go:103:7:103:18 | type conversion | Incorrect conversion of a 16-bit number from strconv.ParseUint result to a lower bit size type int8 |
| IncorrectNumericConversion.go:106:18:106:50 | call to ParseUint | IncorrectNumericConversion.go:106:18:106:50 | call to ParseUint : tuple type | IncorrectNumericConversion.go:110:7:110:19 | type conversion | Incorrect conversion of a 32-bit number from strconv.ParseUint result to a lower bit size type int16 |
| IncorrectNumericConversion.go:113:18:113:50 | call to ParseUint | IncorrectNumericConversion.go:113:18:113:50 | call to ParseUint : tuple type | IncorrectNumericConversion.go:117:7:117:19 | type conversion | Incorrect conversion of a 64-bit number from strconv.ParseUint result to a lower bit size type int32 |
| IncorrectNumericConversion.go:120:18:120:49 | call to ParseUint | IncorrectNumericConversion.go:120:18:120:49 | call to ParseUint : tuple type | IncorrectNumericConversion.go:124:7:124:19 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.ParseUint result to a lower bit size type int32 |
| IncorrectNumericConversion.go:208:18:208:36 | call to Atoi | IncorrectNumericConversion.go:208:18:208:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:212:7:212:18 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type int8 |
| IncorrectNumericConversion.go:215:18:215:36 | call to Atoi | IncorrectNumericConversion.go:215:18:215:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:219:7:219:19 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type int16 |
| IncorrectNumericConversion.go:222:18:222:36 | call to Atoi | IncorrectNumericConversion.go:222:18:222:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:226:7:226:19 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type int32 |
| IncorrectNumericConversion.go:229:18:229:36 | call to Atoi | IncorrectNumericConversion.go:229:18:229:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:233:7:233:19 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type uint8 |
| IncorrectNumericConversion.go:236:18:236:36 | call to Atoi | IncorrectNumericConversion.go:236:18:236:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:240:7:240:20 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type uint16 |
| IncorrectNumericConversion.go:243:18:243:36 | call to Atoi | IncorrectNumericConversion.go:243:18:243:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:247:7:247:20 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type uint32 |
| IncorrectNumericConversion.go:250:18:250:36 | call to Atoi | IncorrectNumericConversion.go:250:18:250:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:254:7:254:21 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type float32 |
| IncorrectNumericConversion.go:257:18:257:36 | call to Atoi | IncorrectNumericConversion.go:257:18:257:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:262:7:262:18 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type uint8 |
| IncorrectNumericConversion.go:266:18:266:36 | call to Atoi | IncorrectNumericConversion.go:266:18:266:36 | call to Atoi : tuple type | IncorrectNumericConversion.go:270:7:270:23 | type conversion | Incorrect conversion of a (arch-dependent)-bit number from strconv.Atoi result to a lower bit size type int16 |

View File

@@ -1,355 +0,0 @@
package main
import (
"math"
"strconv"
)
func main() {
}
type Something struct {
}
type Config struct {
}
type Registry struct {
}
func LookupTarget(conf *Config, num int32) (int32, error) {
return 567, nil
}
func LookupNumberByName(reg *Registry, name string) (int32, error) {
return 567, nil
}
func lab(s string) (*Something, error) {
num, err := strconv.Atoi(s)
if err != nil {
number, err := LookupNumberByName(&Registry{}, s)
if err != nil {
return nil, err
}
num = int(number)
}
target, err := LookupTarget(&Config{}, int32(num))
if err != nil {
return nil, err
}
// convert the resolved target number back to a string
s = strconv.Itoa(int(target))
return nil, nil
}
const CustomMaxInt16 = 1<<15 - 1
type CustomInt int16
func badParseFloat() {
{
parsed, err := strconv.ParseFloat("1.32", 32)
if err != nil {
panic(err)
}
_ = int16(parsed)
}
{
parsed, err := strconv.ParseFloat("1.32", 64)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
}
func badParseInt() {
{
parsed, err := strconv.ParseInt("3456", 10, 16)
if err != nil {
panic(err)
}
_ = int8(parsed)
}
{
parsed, err := strconv.ParseInt("3456", 10, 32)
if err != nil {
panic(err)
}
_ = int16(parsed)
}
{
parsed, err := strconv.ParseInt("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
{
parsed, err := strconv.ParseInt("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
}
func badParseUint() {
{
parsed, err := strconv.ParseUint("3456", 10, 16)
if err != nil {
panic(err)
}
_ = int8(parsed)
}
{
parsed, err := strconv.ParseUint("3456", 10, 32)
if err != nil {
panic(err)
}
_ = int16(parsed)
}
{
parsed, err := strconv.ParseUint("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
{
parsed, err := strconv.ParseUint("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
}
func goodParseFloat() {
{
parsed, err := strconv.ParseFloat("1.32", 32)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
{
parsed, err := strconv.ParseFloat("1.32", 64)
if err != nil {
panic(err)
}
_ = int64(parsed)
}
}
func goodParseInt() {
{
parsed, err := strconv.ParseInt("3456", 10, 16)
if err != nil {
panic(err)
}
_ = int16(parsed)
}
{
parsed, err := strconv.ParseInt("3456", 10, 32)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
{
parsed, err := strconv.ParseInt("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int64(parsed)
}
{
parsed, err := strconv.ParseInt("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int64(parsed)
}
}
func goodParseUint() {
{
parsed, err := strconv.ParseUint("3456", 10, 16)
if err != nil {
panic(err)
}
_ = int16(parsed)
}
{
parsed, err := strconv.ParseUint("3456", 10, 32)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
{
parsed, err := strconv.ParseUint("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int64(parsed)
}
{
parsed, err := strconv.ParseUint("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int64(parsed)
}
}
// these should be caught:
func upperBoundIsNOTChecked(input string) {
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = int8(parsed)
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = int16(parsed)
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = int32(parsed)
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = uint8(parsed)
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = uint16(parsed)
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = uint32(parsed)
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = float32(parsed)
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
// NOTE: byte is uint8
_ = byte(parsed)
}
{
// using custom type:
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
_ = CustomInt(parsed)
}
}
// these should NOT be caught:
func upperBoundIsChecked(input string) {
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed < math.MaxInt8 {
_ = int8(parsed)
}
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed < math.MaxInt16 {
_ = int16(parsed)
}
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed > 0 {
_ = int32(parsed)
}
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed < math.MaxInt32 {
_ = int32(parsed)
}
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed < math.MaxUint8 {
_ = uint8(parsed)
}
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed < math.MaxUint16 {
_ = uint16(parsed)
}
}
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed < math.MaxUint8 {
_ = byte(parsed)
}
}
{ // multiple `and` conditions
parsed, err := strconv.Atoi(input)
if err == nil && 1 == 1 && parsed < math.MaxInt8 {
_ = int8(parsed)
}
}
{ // custom maxInt16
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed < CustomMaxInt16 {
_ = int16(parsed)
}
}
}

View File

@@ -1 +0,0 @@
experimental/CWE-681/IncorrectNumericConversion.ql

View File

@@ -0,0 +1,247 @@
edges
| IncorrectIntegerConversion.go:26:2:26:28 | ... := ...[0] : int | IncorrectIntegerConversion.go:35:41:35:50 | type conversion |
| IncorrectIntegerConversion.go:65:3:65:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:69:7:69:18 | type conversion |
| IncorrectIntegerConversion.go:65:3:65:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:70:7:70:19 | type conversion |
| IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:85:7:85:18 | type conversion |
| IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:86:7:86:19 | type conversion |
| IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:87:7:87:19 | type conversion |
| IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:88:7:88:20 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:101:7:101:18 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:102:7:102:19 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:103:7:103:19 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:104:7:104:20 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:105:7:105:19 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:106:7:106:20 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:109:7:109:17 | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:110:7:110:18 | type conversion |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:117:7:117:18 | type conversion |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:118:7:118:19 | type conversion |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:119:7:119:19 | type conversion |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:120:7:120:20 | type conversion |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:121:7:121:19 | type conversion |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:122:7:122:20 | type conversion |
| IncorrectIntegerConversion.go:148:3:148:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:152:7:152:18 | type conversion |
| IncorrectIntegerConversion.go:148:3:148:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:153:7:153:19 | type conversion |
| IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:168:7:168:18 | type conversion |
| IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:169:7:169:19 | type conversion |
| IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:170:7:170:19 | type conversion |
| IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:171:7:171:20 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:184:7:184:18 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:185:7:185:19 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:186:7:186:19 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:187:7:187:20 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:188:7:188:19 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:189:7:189:20 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:192:7:192:17 | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:193:7:193:18 | type conversion |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:200:7:200:18 | type conversion |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:201:7:201:19 | type conversion |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:202:7:202:19 | type conversion |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:203:7:203:20 | type conversion |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:204:7:204:19 | type conversion |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:205:7:205:20 | type conversion |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:218:6:218:17 | type conversion |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:219:6:219:18 | type conversion |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:220:6:220:18 | type conversion |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:221:6:221:19 | type conversion |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:222:6:222:18 | type conversion |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:223:6:223:19 | type conversion |
| IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:240:7:240:18 | type conversion |
| IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:241:7:241:23 | type conversion |
| IncorrectIntegerConversion.go:247:3:247:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:261:8:261:19 | type conversion |
| IncorrectIntegerConversion.go:268:3:268:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:282:8:282:21 | type conversion |
| IncorrectIntegerConversion.go:319:3:319:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:323:7:323:18 | type conversion |
| IncorrectIntegerConversion.go:330:3:330:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:334:9:334:21 | type conversion |
| IncorrectIntegerConversion.go:338:3:338:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:342:8:342:20 | type conversion |
| IncorrectIntegerConversion.go:346:3:346:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:350:9:350:21 | type conversion : int64 |
| IncorrectIntegerConversion.go:350:9:350:21 | type conversion : int64 | IncorrectIntegerConversion.go:351:9:351:17 | type conversion |
| IncorrectIntegerConversion.go:355:3:355:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:359:9:359:21 | type conversion : int64 |
| IncorrectIntegerConversion.go:359:9:359:21 | type conversion : int64 | IncorrectIntegerConversion.go:360:9:360:17 | type conversion : int64 |
| IncorrectIntegerConversion.go:360:9:360:17 | type conversion : int64 | IncorrectIntegerConversion.go:361:9:361:17 | type conversion : int64 |
| IncorrectIntegerConversion.go:361:9:361:17 | type conversion : int64 | IncorrectIntegerConversion.go:362:7:362:14 | type conversion |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:371:6:371:17 | type conversion |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:372:6:372:18 | type conversion |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:373:6:373:18 | type conversion |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:374:6:374:19 | type conversion |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:375:6:375:18 | type conversion |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:376:6:376:19 | type conversion |
| TestNoArchitectureBuildConstraints.go:12:3:12:48 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:16:7:16:19 | type conversion |
| TestNoArchitectureBuildConstraints.go:12:3:12:48 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:17:7:17:20 | type conversion |
| TestNoArchitectureBuildConstraints.go:20:3:20:49 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:24:7:24:17 | type conversion |
| TestNoArchitectureBuildConstraints.go:20:3:20:49 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:25:7:25:18 | type conversion |
nodes
| IncorrectIntegerConversion.go:26:2:26:28 | ... := ...[0] : int | semmle.label | ... := ...[0] : int |
| IncorrectIntegerConversion.go:35:41:35:50 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:65:3:65:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:69:7:69:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:70:7:70:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:85:7:85:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:86:7:86:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:87:7:87:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:88:7:88:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:101:7:101:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:102:7:102:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:103:7:103:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:104:7:104:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:105:7:105:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:106:7:106:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:109:7:109:17 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:110:7:110:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:117:7:117:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:118:7:118:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:119:7:119:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:120:7:120:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:121:7:121:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:122:7:122:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:148:3:148:50 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:152:7:152:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:153:7:153:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:168:7:168:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:169:7:169:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:170:7:170:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:171:7:171:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:184:7:184:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:185:7:185:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:186:7:186:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:187:7:187:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:188:7:188:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:189:7:189:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:192:7:192:17 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:193:7:193:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:200:7:200:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:201:7:201:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:202:7:202:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:203:7:203:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:204:7:204:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:205:7:205:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | semmle.label | ... := ...[0] : int |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | semmle.label | ... := ...[0] : int |
| IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | semmle.label | ... := ...[0] : int |
| IncorrectIntegerConversion.go:218:6:218:17 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:219:6:219:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:220:6:220:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:221:6:221:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:222:6:222:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:223:6:223:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:240:7:240:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:241:7:241:23 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:247:3:247:36 | ... := ...[0] : int | semmle.label | ... := ...[0] : int |
| IncorrectIntegerConversion.go:261:8:261:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:268:3:268:49 | ... := ...[0] : uint64 | semmle.label | ... := ...[0] : uint64 |
| IncorrectIntegerConversion.go:282:8:282:21 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:319:3:319:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:323:7:323:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:330:3:330:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:334:9:334:21 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:338:3:338:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:342:8:342:20 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:346:3:346:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:350:9:350:21 | type conversion : int64 | semmle.label | type conversion : int64 |
| IncorrectIntegerConversion.go:351:9:351:17 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:355:3:355:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:359:9:359:21 | type conversion : int64 | semmle.label | type conversion : int64 |
| IncorrectIntegerConversion.go:360:9:360:17 | type conversion : int64 | semmle.label | type conversion : int64 |
| IncorrectIntegerConversion.go:361:9:361:17 | type conversion : int64 | semmle.label | type conversion : int64 |
| IncorrectIntegerConversion.go:362:7:362:14 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| IncorrectIntegerConversion.go:371:6:371:17 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:372:6:372:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:373:6:373:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:374:6:374:19 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:375:6:375:18 | type conversion | semmle.label | type conversion |
| IncorrectIntegerConversion.go:376:6:376:19 | type conversion | semmle.label | type conversion |
| TestNoArchitectureBuildConstraints.go:12:3:12:48 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| TestNoArchitectureBuildConstraints.go:16:7:16:19 | type conversion | semmle.label | type conversion |
| TestNoArchitectureBuildConstraints.go:17:7:17:20 | type conversion | semmle.label | type conversion |
| TestNoArchitectureBuildConstraints.go:20:3:20:49 | ... := ...[0] : int64 | semmle.label | ... := ...[0] : int64 |
| TestNoArchitectureBuildConstraints.go:24:7:24:17 | type conversion | semmle.label | type conversion |
| TestNoArchitectureBuildConstraints.go:25:7:25:18 | type conversion | semmle.label | type conversion |
#select
| IncorrectIntegerConversion.go:35:41:35:50 | type conversion | IncorrectIntegerConversion.go:26:2:26:28 | ... := ...[0] : int | IncorrectIntegerConversion.go:35:41:35:50 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int32 without an upper bound check. | IncorrectIntegerConversion.go:26:2:26:28 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:69:7:69:18 | type conversion | IncorrectIntegerConversion.go:65:3:65:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:69:7:69:18 | type conversion | Incorrect conversion of a 16-bit integer from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:65:3:65:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:70:7:70:19 | type conversion | IncorrectIntegerConversion.go:65:3:65:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:70:7:70:19 | type conversion | Incorrect conversion of a 16-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:65:3:65:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:85:7:85:18 | type conversion | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:85:7:85:18 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:86:7:86:19 | type conversion | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:86:7:86:19 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:87:7:87:19 | type conversion | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:87:7:87:19 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:88:7:88:20 | type conversion | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:88:7:88:20 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:81:3:81:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:101:7:101:18 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:101:7:101:18 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:102:7:102:19 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:102:7:102:19 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:103:7:103:19 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:103:7:103:19 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:104:7:104:20 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:104:7:104:20 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:105:7:105:19 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:105:7:105:19 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int32 without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:106:7:106:20 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:106:7:106:20 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint32 without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:109:7:109:17 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:109:7:109:17 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:110:7:110:18 | type conversion | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:110:7:110:18 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint without an upper bound check. | IncorrectIntegerConversion.go:97:3:97:49 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:117:7:117:18 | type conversion | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:117:7:117:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:118:7:118:19 | type conversion | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:118:7:118:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:119:7:119:19 | type conversion | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:119:7:119:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:120:7:120:20 | type conversion | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:120:7:120:20 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:121:7:121:19 | type conversion | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:121:7:121:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int32 without an upper bound check. | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:122:7:122:20 | type conversion | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:122:7:122:20 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint32 without an upper bound check. | IncorrectIntegerConversion.go:113:3:113:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:152:7:152:18 | type conversion | IncorrectIntegerConversion.go:148:3:148:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:152:7:152:18 | type conversion | Incorrect conversion of a 16-bit integer from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:148:3:148:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:153:7:153:19 | type conversion | IncorrectIntegerConversion.go:148:3:148:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:153:7:153:19 | type conversion | Incorrect conversion of a 16-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:148:3:148:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:168:7:168:18 | type conversion | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:168:7:168:18 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:169:7:169:19 | type conversion | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:169:7:169:19 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:170:7:170:19 | type conversion | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:170:7:170:19 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:171:7:171:20 | type conversion | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:171:7:171:20 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:164:3:164:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:184:7:184:18 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:184:7:184:18 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:185:7:185:19 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:185:7:185:19 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:186:7:186:19 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:186:7:186:19 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:187:7:187:20 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:187:7:187:20 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:188:7:188:19 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:188:7:188:19 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int32 without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:189:7:189:20 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:189:7:189:20 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint32 without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:192:7:192:17 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:192:7:192:17 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:193:7:193:18 | type conversion | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:193:7:193:18 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint without an upper bound check. | IncorrectIntegerConversion.go:180:3:180:50 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:200:7:200:18 | type conversion | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:200:7:200:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:201:7:201:19 | type conversion | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:201:7:201:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:202:7:202:19 | type conversion | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:202:7:202:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:203:7:203:20 | type conversion | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:203:7:203:20 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:204:7:204:19 | type conversion | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:204:7:204:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int32 without an upper bound check. | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:205:7:205:20 | type conversion | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:205:7:205:20 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint32 without an upper bound check. | IncorrectIntegerConversion.go:196:3:196:49 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:218:6:218:17 | type conversion | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:218:6:218:17 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:219:6:219:18 | type conversion | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:219:6:219:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:220:6:220:18 | type conversion | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:220:6:220:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:221:6:221:19 | type conversion | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:221:6:221:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:222:6:222:18 | type conversion | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:222:6:222:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int32 without an upper bound check. | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:223:6:223:19 | type conversion | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:223:6:223:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint32 without an upper bound check. | IncorrectIntegerConversion.go:214:2:214:36 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:240:7:240:18 | type conversion | IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:240:7:240:18 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:241:7:241:23 | type conversion | IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:241:7:241:23 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:235:3:235:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:261:8:261:19 | type conversion | IncorrectIntegerConversion.go:247:3:247:36 | ... := ...[0] : int | IncorrectIntegerConversion.go:261:8:261:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:247:3:247:36 | ... := ...[0] : int | strconv.Atoi |
| IncorrectIntegerConversion.go:282:8:282:21 | type conversion | IncorrectIntegerConversion.go:268:3:268:49 | ... := ...[0] : uint64 | IncorrectIntegerConversion.go:282:8:282:21 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:268:3:268:49 | ... := ...[0] : uint64 | strconv.ParseUint |
| IncorrectIntegerConversion.go:323:7:323:18 | type conversion | IncorrectIntegerConversion.go:319:3:319:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:323:7:323:18 | type conversion | Incorrect conversion of a 16-bit integer from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:319:3:319:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:334:9:334:21 | type conversion | IncorrectIntegerConversion.go:330:3:330:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:334:9:334:21 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:330:3:330:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:342:8:342:20 | type conversion | IncorrectIntegerConversion.go:338:3:338:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:342:8:342:20 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:338:3:338:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:351:9:351:17 | type conversion | IncorrectIntegerConversion.go:346:3:346:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:351:9:351:17 | type conversion | Incorrect conversion of a 32-bit integer from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:346:3:346:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:362:7:362:14 | type conversion | IncorrectIntegerConversion.go:355:3:355:48 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:362:7:362:14 | type conversion | Incorrect conversion of a 16-bit integer from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:355:3:355:48 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:371:6:371:17 | type conversion | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:371:6:371:17 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int8 without an upper bound check. | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:372:6:372:18 | type conversion | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:372:6:372:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint8 without an upper bound check. | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:373:6:373:18 | type conversion | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:373:6:373:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int16 without an upper bound check. | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:374:6:374:19 | type conversion | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:374:6:374:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint16 without an upper bound check. | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:375:6:375:18 | type conversion | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:375:6:375:18 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int32 without an upper bound check. | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | strconv.ParseInt |
| IncorrectIntegerConversion.go:376:6:376:19 | type conversion | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | IncorrectIntegerConversion.go:376:6:376:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint32 without an upper bound check. | IncorrectIntegerConversion.go:367:2:367:60 | ... := ...[0] : int64 | strconv.ParseInt |
| TestNoArchitectureBuildConstraints.go:16:7:16:19 | type conversion | TestNoArchitectureBuildConstraints.go:12:3:12:48 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:16:7:16:19 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type int32 without an upper bound check. | TestNoArchitectureBuildConstraints.go:12:3:12:48 | ... := ...[0] : int64 | strconv.ParseInt |
| TestNoArchitectureBuildConstraints.go:17:7:17:20 | type conversion | TestNoArchitectureBuildConstraints.go:12:3:12:48 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:17:7:17:20 | type conversion | Incorrect conversion of an integer with architecture-dependent bit size from $@ to a lower bit size type uint32 without an upper bound check. | TestNoArchitectureBuildConstraints.go:12:3:12:48 | ... := ...[0] : int64 | strconv.ParseInt |
| TestNoArchitectureBuildConstraints.go:24:7:24:17 | type conversion | TestNoArchitectureBuildConstraints.go:20:3:20:49 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:24:7:24:17 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type int without an upper bound check. | TestNoArchitectureBuildConstraints.go:20:3:20:49 | ... := ...[0] : int64 | strconv.ParseInt |
| TestNoArchitectureBuildConstraints.go:25:7:25:18 | type conversion | TestNoArchitectureBuildConstraints.go:20:3:20:49 | ... := ...[0] : int64 | TestNoArchitectureBuildConstraints.go:25:7:25:18 | type conversion | Incorrect conversion of a 64-bit integer from $@ to a lower bit size type uint without an upper bound check. | TestNoArchitectureBuildConstraints.go:20:3:20:49 | ... := ...[0] : int64 | strconv.ParseInt |

View File

@@ -0,0 +1,381 @@
package main
import (
"math"
"strconv"
)
func main() {
}
type something struct {
}
type config struct {
}
type registry struct {
}
func lookupTarget(conf *config, num int32) (int32, error) {
return 567, nil
}
func lookupNumberByName(reg *registry, name string) (int32, error) {
return 567, nil
}
func lab(s string) (*something, error) {
num, err := strconv.Atoi(s)
if err != nil {
number, err := lookupNumberByName(&registry{}, s)
if err != nil {
return nil, err
}
num = int(number)
}
target, err := lookupTarget(&config{}, int32(num)) // NOT OK
if err != nil {
return nil, err
}
// convert the resolved target number back to a string
s = strconv.Itoa(int(target))
return nil, nil
}
func testParseInt() {
{
parsed, err := strconv.ParseInt("3456", 10, 8)
if err != nil {
panic(err)
}
_ = int8(parsed) // OK
_ = uint8(parsed) // OK
_ = int16(parsed) // OK
_ = uint16(parsed) // OK
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseInt("3456", 10, 16)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // OK
_ = uint16(parsed) // OK
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseInt("3456", 10, 32)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseInt("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // NOT OK
_ = uint32(parsed) // NOT OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // NOT OK
_ = uint(parsed) // NOT OK
}
{
parsed, err := strconv.ParseInt("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // NOT OK
_ = uint32(parsed) // NOT OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
}
func testParseUint() {
{
parsed, err := strconv.ParseUint("3456", 10, 8)
if err != nil {
panic(err)
}
_ = int8(parsed) // OK
_ = uint8(parsed) // OK
_ = int16(parsed) // OK
_ = uint16(parsed) // OK
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 16)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // OK
_ = uint16(parsed) // OK
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 32)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // NOT OK
_ = uint32(parsed) // NOT OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // NOT OK
_ = uint(parsed) // NOT OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // NOT OK
_ = uint32(parsed) // NOT OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
}
func testAtoi() {
parsed, err := strconv.Atoi("3456")
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // NOT OK
_ = uint32(parsed) // NOT OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
type customInt int16
// these should be caught:
func typeAliases(input string) {
{
parsed, err := strconv.ParseInt(input, 10, 32)
if err != nil {
panic(err)
}
// NOTE: byte is uint8
_ = byte(parsed) // NOT OK
_ = customInt(parsed) // NOT OK
}
}
func testBoundsChecking(input string) {
{
parsed, err := strconv.Atoi(input)
if err != nil {
panic(err)
}
if parsed <= math.MaxInt8 && parsed >= math.MinInt8 {
_ = int8(parsed) // OK
}
if parsed < math.MaxInt8 {
_ = int8(parsed) // OK (because we only check for upper bounds)
if parsed >= 0 {
_ = int16(parsed) // OK
}
}
if parsed >= math.MinInt8 {
_ = int8(parsed) // NOT OK
if parsed <= 0 {
_ = int16(parsed) // OK
}
}
}
{
parsed, err := strconv.ParseUint(input, 10, 32)
if err != nil {
panic(err)
}
if parsed <= math.MaxInt8 {
_ = uint8(parsed) // OK
}
if parsed < 5 {
_ = uint16(parsed) // OK
}
if err == nil && 1 == 1 && parsed < math.MaxInt8 {
_ = int8(parsed) // OK
}
if parsed > 42 {
_ = uint16(parsed) // NOT OK
}
if parsed > 5 {
return
}
_ = uint8(parsed) // OK
}
}
func testRightShifted(input string) {
{
parsed, err := strconv.ParseInt(input, 10, 32)
if err != nil {
panic(err)
}
_ = byte(parsed) // OK
_ = byte(parsed >> 8)
_ = byte(parsed >> 16)
_ = byte(parsed >> 24)
}
{
parsed, err := strconv.ParseInt(input, 10, 16)
if err != nil {
panic(err)
}
_ = byte(parsed) // OK
_ = byte(parsed & 0xff00 >> 8)
}
{
parsed, err := strconv.ParseInt(input, 10, 32)
if err != nil {
panic(err)
}
_ = byte(parsed) // OK
_ = byte(parsed >> 8 & 0xff)
}
{
parsed, err := strconv.ParseInt(input, 10, 16)
if err != nil {
panic(err)
}
_ = byte(parsed) // NOT OK
_ = byte(parsed << 8)
}
}
func testPathWithMoreThanOneSink(input string) {
{
parsed, err := strconv.ParseInt(input, 10, 32)
if err != nil {
panic(err)
}
v1 := int16(parsed) // NOT OK
_ = int16(v1) // OK
}
{
parsed, err := strconv.ParseInt(input, 10, 32)
if err != nil {
panic(err)
}
v := int16(parsed) // NOT OK
_ = int8(v) // OK
}
{
parsed, err := strconv.ParseInt(input, 10, 32)
if err != nil {
panic(err)
}
v1 := int32(parsed) // OK
v2 := int16(v1) // NOT OK
_ = int8(v2) // OK
}
{
parsed, err := strconv.ParseInt(input, 10, 16)
if err != nil {
panic(err)
}
v1 := int64(parsed) // OK
v2 := int32(v1) // OK
v3 := int16(v2) // OK
_ = int8(v3) // NOT OK
}
}
func testUsingStrConvIntSize(input string) {
parsed, err := strconv.ParseInt(input, 10, strconv.IntSize)
if err != nil {
panic(err)
}
_ = int8(parsed) // NOT OK
_ = uint8(parsed) // NOT OK
_ = int16(parsed) // NOT OK
_ = uint16(parsed) // NOT OK
_ = int32(parsed) // NOT OK
_ = uint32(parsed) // NOT OK
_ = int64(parsed) // OK
_ = uint64(parsed) // OK
_ = int(parsed) // OK
_ = uint(parsed) // OK
}

View File

@@ -0,0 +1 @@
Security/CWE-681/IncorrectIntegerConversion.ql

View File

@@ -0,0 +1,34 @@
// Note that the filename acts as an implicit build constraint
package main
import (
"strconv"
)
func testIntSource386() {
{
parsed, err := strconv.ParseInt("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
}
{
parsed, err := strconv.Atoi("3456")
if err != nil {
panic(err)
}
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
}
}

View File

@@ -0,0 +1,36 @@
// +build 386 amd64p32 arm armbe mips mipsle mips64p32 mips64p32le ppc s390 sparc
// +build gc
// +build go1.4
package main
import (
"strconv"
)
func testIntSource32() {
{
parsed, err := strconv.ParseInt("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
}
{
parsed, err := strconv.Atoi("3456")
if err != nil {
panic(err)
}
_ = int32(parsed) // OK
_ = uint32(parsed) // OK
}
}

View File

@@ -0,0 +1,26 @@
// Note that the filename acts as an implicit build constraint
package main
import (
"strconv"
)
func testIntSinkAmd64() {
{
parsed, err := strconv.ParseInt("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
}

View File

@@ -0,0 +1,28 @@
// +build amd64 arm64 arm64be ppc64 ppc64le mips64 mips64le s390x sparc64
// +build gc
// +build go1.4
package main
import (
"strconv"
)
func testIntSink64() {
{
parsed, err := strconv.ParseInt("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
{
parsed, err := strconv.ParseUint("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int(parsed) // OK
_ = uint(parsed) // OK
}
}

View File

@@ -0,0 +1,27 @@
// +build gc
// +build go1.4
package main
import (
"strconv"
)
func testIntSizeIsArchicturallyDependent1() {
{
parsed, err := strconv.ParseInt("3456", 10, 0)
if err != nil {
panic(err)
}
_ = int32(parsed) // NOT OK
_ = uint32(parsed) // NOT OK
}
{
parsed, err := strconv.ParseInt("3456", 10, 64)
if err != nil {
panic(err)
}
_ = int(parsed) // NOT OK
_ = uint(parsed) // NOT OK
}
}