Merge remote-tracking branch 'upstream/master' into merge-master-next-20180913

This commit is contained in:
Jonas Jensen
2018-09-13 20:28:17 +02:00
20 changed files with 105 additions and 20 deletions

View File

@@ -29,11 +29,20 @@ predicate isEffectivelyConstAccess(VariableAccess a)
) )
} }
from FunctionCall fc, VariableAccess src class StrcatSource extends VariableAccess {
where fc.getTarget().hasName("strcat") and FunctionCall strcat;
src = fc.getArgument(1) and
not src.getType() instanceof ArrayType and StrcatSource() {
strcat.getTarget().hasName("strcat") and
this = strcat.getArgument(1)
}
FunctionCall getStrcatCall() { result = strcat }
}
from StrcatSource src
where not src.getType() instanceof ArrayType and
not exists(BufferSizeExpr bse | not exists(BufferSizeExpr bse |
bse.getArg().(VariableAccess).getTarget() = src.getTarget()) and bse.getArg().(VariableAccess).getTarget() = src.getTarget()) and
not isEffectivelyConstAccess(src) not isEffectivelyConstAccess(src)
select fc, "Always check the size of the source buffer when using strcat." select src.getStrcatCall(), "Always check the size of the source buffer when using strcat."

View File

@@ -56,6 +56,7 @@ abstract class Declaration extends Locatable, @declaration {
// MemberFunction, MemberVariable, MemberType // MemberFunction, MemberVariable, MemberType
exists (Declaration m exists (Declaration m
| m = this and | m = this and
not m instanceof EnumConstant and
result = m.getDeclaringType().getQualifiedName() + "::" + m.getName()) result = m.getDeclaringType().getQualifiedName() + "::" + m.getName())
or or
exists (EnumConstant c exists (EnumConstant c

View File

@@ -904,15 +904,25 @@ class ArrayType extends DerivedType {
ArrayType() { derivedtypes(underlyingElement(this),_,4,_) } ArrayType() { derivedtypes(underlyingElement(this),_,4,_) }
predicate hasArraySize() { arraysizes(underlyingElement(this),_,_,_) } predicate hasArraySize() { arraysizes(underlyingElement(this),_,_,_) }
/**
* Gets the number of elements in this array. Only has a result for arrays declared to be of a
* constant size. See `getByteSize` for getting the number of bytes.
*/
int getArraySize() { arraysizes(underlyingElement(this),result,_,_) } int getArraySize() { arraysizes(underlyingElement(this),result,_,_) }
/**
* Gets the byte size of this array. Only has a result for arrays declared to be of a constant
* size. See `getArraySize` for getting the number of elements.
*/
int getByteSize() { arraysizes(underlyingElement(this),_,result,_) } int getByteSize() { arraysizes(underlyingElement(this),_,result,_) }
override int getAlignment() { arraysizes(underlyingElement(this), _, _, result) } override int getAlignment() { arraysizes(underlyingElement(this), _, _, result) }
/** /**
* Gets the size of this array (only valid for arrays declared to be of a constant * Gets the byte size of this array. Only has a result for arrays declared to be of a constant
* size, will fail for all others). * size. This predicate is a synonym for `getByteSize`. See `getArraySize` for getting the number
* of elements.
*/ */
override int getSize() { override int getSize() {
result = this.getByteSize() result = this.getByteSize()

View File

@@ -63,7 +63,7 @@ module InstructionSanity {
* Holds if instruction `instr` has multiple operands with tag `tag`. * Holds if instruction `instr` has multiple operands with tag `tag`.
*/ */
query predicate duplicateOperand(Instruction instr, OperandTag tag) { query predicate duplicateOperand(Instruction instr, OperandTag tag) {
count(instr.getOperand(tag)) > 1 and strictcount(instr.getOperand(tag)) > 1 and
not tag instanceof UnmodeledUseOperand not tag instanceof UnmodeledUseOperand
} }

View File

@@ -63,7 +63,7 @@ module InstructionSanity {
* Holds if instruction `instr` has multiple operands with tag `tag`. * Holds if instruction `instr` has multiple operands with tag `tag`.
*/ */
query predicate duplicateOperand(Instruction instr, OperandTag tag) { query predicate duplicateOperand(Instruction instr, OperandTag tag) {
count(instr.getOperand(tag)) > 1 and strictcount(instr.getOperand(tag)) > 1 and
not tag instanceof UnmodeledUseOperand not tag instanceof UnmodeledUseOperand
} }

View File

@@ -63,7 +63,7 @@ module InstructionSanity {
* Holds if instruction `instr` has multiple operands with tag `tag`. * Holds if instruction `instr` has multiple operands with tag `tag`.
*/ */
query predicate duplicateOperand(Instruction instr, OperandTag tag) { query predicate duplicateOperand(Instruction instr, OperandTag tag) {
count(instr.getOperand(tag)) > 1 and strictcount(instr.getOperand(tag)) > 1 and
not tag instanceof UnmodeledUseOperand not tag instanceof UnmodeledUseOperand
} }

View File

@@ -0,0 +1,21 @@
| file://:0:0:0:0 | __va_list_tag | __va_list_tag |
| file://:0:0:0:0 | fp_offset | __va_list_tag::fp_offset |
| file://:0:0:0:0 | gp_offset | __va_list_tag::gp_offset |
| file://:0:0:0:0 | operator= | __va_list_tag::operator= |
| file://:0:0:0:0 | operator= | __va_list_tag::operator= |
| file://:0:0:0:0 | overflow_arg_area | __va_list_tag::overflow_arg_area |
| file://:0:0:0:0 | reg_save_area | __va_list_tag::reg_save_area |
| test.cpp:2:7:2:7 | operator= | MyEnumClass::operator= |
| test.cpp:2:7:2:7 | operator= | MyEnumClass::operator= |
| test.cpp:2:7:2:17 | MyEnumClass | MyEnumClass |
| test.cpp:4:10:4:15 | MyEnum | MyEnumClass::MyEnum |
| test.cpp:5:9:5:9 | A | MyEnumClass::MyEnum::A |
| test.cpp:6:9:6:9 | B | MyEnumClass::MyEnum::B |
| test.cpp:10:34:10:34 | v | v |
| test.cpp:12:7:12:7 | MyClass2 | MyClass2::MyClass2 |
| test.cpp:12:7:12:7 | MyClass2 | MyClass2::MyClass2 |
| test.cpp:12:7:12:7 | operator= | MyClass2::operator= |
| test.cpp:12:7:12:7 | operator= | MyClass2::operator= |
| test.cpp:12:7:12:14 | MyClass2 | MyClass2 |
| test.cpp:14:12:14:19 | MyClass2 | MyClass2::MyClass2 |
| test.cpp:17:6:17:6 | f | f |

View File

@@ -0,0 +1,5 @@
import cpp
from Declaration d
select d, d.getQualifiedName()

View File

@@ -106,3 +106,16 @@ class ObjectInitializerType
new Point() { Name = "Bob" }; new Point() { Name = "Bob" };
} }
} }
class LiteralConversions
{
struct Point
{
public int? x, y;
}
void F()
{
new Point { x=1, y=2 };
}
}

View File

@@ -46,3 +46,9 @@
| Program.cs:101:16:101:21 | Object | | Program.cs:101:16:101:21 | Object |
| Program.cs:104:5:104:8 | Void | | Program.cs:104:5:104:8 | Void |
| Program.cs:106:13:106:17 | Point | | Program.cs:106:13:106:17 | Point |
| Program.cs:114:16:114:18 | Int32 |
| Program.cs:114:16:114:18 | Int32 |
| Program.cs:114:16:114:19 | Nullable<Int32> |
| Program.cs:114:16:114:19 | Nullable<Int32> |
| Program.cs:117:5:117:8 | Void |
| Program.cs:119:13:119:17 | Point |

View File

@@ -15,6 +15,7 @@
* external/cwe/cwe-197 * external/cwe/cwe-197
* external/cwe/cwe-681 * external/cwe/cwe-681
*/ */
import java import java
import semmle.code.java.dataflow.RangeUtils import semmle.code.java.dataflow.RangeUtils
import semmle.code.java.Conversions import semmle.code.java.Conversions
@@ -25,7 +26,8 @@ predicate small(MulExpr e) {
lhs = e.getLeftOperand().getProperExpr().(ConstantIntegerExpr).getIntValue() and lhs = e.getLeftOperand().getProperExpr().(ConstantIntegerExpr).getIntValue() and
rhs = e.getRightOperand().getProperExpr().(ConstantIntegerExpr).getIntValue() and rhs = e.getRightOperand().getProperExpr().(ConstantIntegerExpr).getIntValue() and
lhs * rhs = res and lhs * rhs = res and
t.getOrdPrimitiveType().getMinValue() <= res and res <= t.getOrdPrimitiveType().getMaxValue() t.getOrdPrimitiveType().getMinValue() <= res and
res <= t.getOrdPrimitiveType().getMaxValue()
) )
} }
@@ -52,4 +54,7 @@ where
// not obviously small and ok // not obviously small and ok
not small(e) and not small(e) and
e.getEnclosingCallable().fromSource() e.getEnclosingCallable().fromSource()
select c, "$@ converted to "+ destType.getName() +" by use in " + ("a " + c.kind()).regexpReplaceAll("^a ([aeiou])", "an $1") + ".", e, sourceType.getName() + " multiplication" select c,
"Potential overflow in $@ before it is converted to " + destType.getName() + " by use in " +
("a " + c.kind()).regexpReplaceAll("^a ([aeiou])", "an $1") + ".", e,
sourceType.getName() + " multiplication"

View File

@@ -1,4 +1,4 @@
| Test.java:20:23:20:48 | ... * ... | $@ converted to long by use in an assignment context. | Test.java:20:23:20:48 | ... * ... | int multiplication | | Test.java:20:23:20:48 | ... * ... | Potential overflow in $@ before it is converted to long by use in an assignment context. | Test.java:20:23:20:48 | ... * ... | int multiplication |
| Test.java:27:23:27:52 | ... + ... | $@ converted to long by use in an assignment context. | Test.java:27:23:27:48 | ... * ... | int multiplication | | Test.java:27:23:27:52 | ... + ... | Potential overflow in $@ before it is converted to long by use in an assignment context. | Test.java:27:23:27:48 | ... * ... | int multiplication |
| Test.java:34:23:34:63 | ...?...:... | $@ converted to long by use in an assignment context. | Test.java:34:30:34:55 | ... * ... | int multiplication | | Test.java:34:23:34:63 | ...?...:... | Potential overflow in $@ before it is converted to long by use in an assignment context. | Test.java:34:30:34:55 | ... * ... | int multiplication |
| Test.java:41:25:41:49 | ... * ... | $@ converted to double by use in an assignment context. | Test.java:41:25:41:49 | ... * ... | long multiplication | | Test.java:41:25:41:49 | ... * ... | Potential overflow in $@ before it is converted to double by use in an assignment context. | Test.java:41:25:41:49 | ... * ... | long multiplication |

View File

@@ -213,6 +213,7 @@ Comment getExclamationPointCommentInRun(ExclamationPointComment head) {
* Holds if this is a bundle containing multiple licenses. * Holds if this is a bundle containing multiple licenses.
*/ */
predicate isMultiLicenseBundle(TopLevel tl) { predicate isMultiLicenseBundle(TopLevel tl) {
// case: comments preserved by minifiers
count(ExclamationPointComment head | count(ExclamationPointComment head |
head.getTopLevel() = tl and head.getTopLevel() = tl and
exists(ExclamationPointComment licenseIndicator | exists(ExclamationPointComment licenseIndicator |
@@ -220,6 +221,12 @@ predicate isMultiLicenseBundle(TopLevel tl) {
licenseIndicator.getLine(_).regexpMatch("(?i).*\\b(copyright|license|\\d+\\.\\d+)\\b.*") licenseIndicator.getLine(_).regexpMatch("(?i).*\\b(copyright|license|\\d+\\.\\d+)\\b.*")
) )
) > 1 ) > 1
or
// case: ordinary block comments with "@license" lines
count(BlockComment head |
head.getTopLevel() = tl and
head.getLine(_).regexpMatch("(?i) *\\* @license .*")
) > 1
} }
/** /**

View File

@@ -1,6 +1,6 @@
var express = require('express'); var express = require('express');
var app = express(); var app = express();
var URI = reuires("urijs"); var URI = require("urijs");
app.get('/findKey', function(req, res) { app.get('/findKey', function(req, res) {
var key = req.param("key"), input = req.param("input"); var key = req.param("key"), input = req.param("input");

View File

@@ -11,6 +11,7 @@
| jsx.js:0:0:0:0 | jsx.js | generated | | jsx.js:0:0:0:0 | jsx.js | generated |
| multi-part-bundle.html:0:0:0:0 | multi-part-bundle.html | generated | | multi-part-bundle.html:0:0:0:0 | multi-part-bundle.html | generated |
| multi-part-bundle.js:0:0:0:0 | multi-part-bundle.js | generated | | multi-part-bundle.js:0:0:0:0 | multi-part-bundle.js | generated |
| multiple-licenses-2.js:0:0:0:0 | multiple-licenses-2.js | generated |
| multiple-licenses.js:0:0:0:0 | multiple-licenses.js | generated | | multiple-licenses.js:0:0:0:0 | multiple-licenses.js | generated |
| opal-test.js:0:0:0:0 | opal-test.js | generated | | opal-test.js:0:0:0:0 | opal-test.js | generated |
| peg-js.js:0:0:0:0 | peg-js.js | generated | | peg-js.js:0:0:0:0 | peg-js.js | generated |

View File

@@ -0,0 +1,10 @@
/*
* @copyright (c) ...
* @copyright (c) ...
* @license ...
*/
/**
* @copyright ...
* @license ...
*/