Skip to content

Commit 6988241

Browse files
author
Dave Bartolomeo
committed
Merge from master
2 parents 708e835 + 0180672 commit 6988241

File tree

176 files changed

+2037
-1406
lines changed

Some content is hidden

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

176 files changed

+2037
-1406
lines changed

change-notes/1.24/analysis-cpp.md

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

99
| **Query** | **Tags** | **Purpose** |
1010
|-----------------------------|-----------|--------------------------------------------------------------------|
11+
| Implicit function declarations (`cpp/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql`) | correctness, maintainability | This query finds calls to undeclared functions that are compiled by a C compiler. Results are shown on LGTM by default. |
1112

1213
## Changes to existing queries
1314

change-notes/1.24/analysis-csharp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The following changes in version 1.24 affect C# analysis in all applications.
1414
| **Query** | **Expected impact** | **Change** |
1515
|------------------------------|------------------------|-----------------------------------|
1616
| Useless assignment to local variable (`cs/useless-assignment-to-local`) | Fewer false positive results | Results have been removed when the variable is named `_` in a `foreach` statement. |
17+
| Dereferenced variable may be null (`cs/dereferenced-value-may-be-null`) | More results | Results are reported from parameters with a default value of `null`. |
1718

1819
## Removal of old queries
1920

change-notes/1.24/analysis-java.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,10 @@ The following changes in version 1.24 affect Java analysis in all applications.
2222

2323
## Changes to libraries
2424

25+
* Identification of test classes has been improved. Previously, one of the
26+
match conditions would classify any class with a name containing the string
27+
"Test" as a test class, but now this matching has been replaced with one that
28+
looks for the occurrence of actual unit-test annotations. This affects the
29+
general file classification mechanism and thus suppression of alerts, and
30+
also any security queries using taint tracking, as test classes act as
31+
default barriers stopping taint flow.

change-notes/1.24/analysis-javascript.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
- [react](https://www.npmjs.com/package/react)
1414
- [typeahead.js](https://www.npmjs.com/package/typeahead.js)
1515
- [Handlebars](https://www.npmjs.com/package/handlebars)
16+
- [Electron](https://electronjs.org/)
17+
- [Node.js](https://nodejs.org/)
18+
- [Socket.IO](https://socket.io/)
1619

1720
## New queries
1821

@@ -37,3 +40,4 @@
3740
## Changes to libraries
3841

3942
* The predicates `RegExpTerm.getSuccessor` and `RegExpTerm.getPredecessor` have been changed to reflect textual, not operational, matching order. This only makes a difference in lookbehind assertions, which are operationally matched backwards. Previously, `getSuccessor` would mimick this, so in an assertion `(?<=ab)` the term `b` would be considered the predecessor, not the successor, of `a`. Textually, however, `a` is still matched before `b`, and this is the order we now follow.
43+
* An extensible model of the `EventEmitter` pattern has been implemented.

cpp/config/suites/c/correctness

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ExprHasNoEffect.ql: /Correctness/Common Errors
1919
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooFewArguments.ql: /Correctness/Common Errors
2020
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooManyArguments.ql: /Correctness/Common Errors
21+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql: /Correctness/Common Errors
2122
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql: /Correctness/Common Errors
2223
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.ql: /Correctness/Common Errors
2324
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/FloatComparison.ql: /Correctness/Common Errors

cpp/config/suites/cpp/correctness

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ExprHasNoEffect.ql: /Correctness/Common Errors
2020
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooFewArguments.ql: /Correctness/Common Errors
2121
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooManyArguments.ql: /Correctness/Common Errors
22+
+ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/ImplicitFunctionDeclaration.ql: /Correctness/Common Errors
2223
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql: /Correctness/Common Errors
2324
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.ql: /Correctness/Common Errors
2425
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/FloatComparison.ql: /Correctness/Common Errors
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* '#include <stdlib.h>' was forgotton */
2+
3+
int main(void) {
4+
/* 'int malloc()' assumed */
5+
unsigned char *p = malloc(100);
6+
*p = 'a';
7+
return 0;
8+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
7+
<overview>
8+
<p>A function is called without a prior function declaration or definition.
9+
When this happens, the compiler generates an implicit declaration of the function,
10+
specifying an integer return type and no parameters.
11+
If the implicit declaration does not match the true signature of the function, the
12+
function may behave unpredictably.</p>
13+
14+
<p>This may indicate a misspelled function name, or that the required header containing
15+
the function declaration has not been included.</p>
16+
17+
</overview>
18+
<recommendation>
19+
<p>Provide an explicit declaration of the function before invoking it.</p>
20+
21+
</recommendation>
22+
<example><sample src="ImplicitFunctionDeclaration.c" />
23+
24+
</example>
25+
26+
<references>
27+
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL31-C.+Declare+identifiers+before+using+them">DCL31-C. Declare identifiers before using them</a></li>
28+
</references>
29+
</qhelp>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @name Implicit function declaration
3+
* @description An implicitly declared function is assumed to take no
4+
* arguments and return an integer. If this assumption does not hold, it
5+
* may lead to unpredictable behavior.
6+
* @kind problem
7+
* @problem.severity warning
8+
* @precision high
9+
* @id cpp/implicit-function-declaration
10+
* @tags correctness
11+
* maintainability
12+
*/
13+
14+
import cpp
15+
import MistypedFunctionArguments
16+
import TooFewArguments
17+
import TooManyArguments
18+
import semmle.code.cpp.commons.Exclusions
19+
20+
predicate locInfo(Locatable e, File file, int line, int col) {
21+
e.getFile() = file and
22+
e.getLocation().getStartLine() = line and
23+
e.getLocation().getStartColumn() = col
24+
}
25+
26+
predicate sameLocation(FunctionDeclarationEntry fde, FunctionCall fc) {
27+
exists(File file, int line, int col |
28+
locInfo(fde, file, line, col) and
29+
locInfo(fc, file, line, col)
30+
)
31+
}
32+
33+
predicate isCompiledAsC(File f) {
34+
f.compiledAsC()
35+
or
36+
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
37+
}
38+
39+
from FunctionDeclarationEntry fdeIm, FunctionCall fc
40+
where
41+
isCompiledAsC(fdeIm.getFile()) and
42+
not isFromMacroDefinition(fc) and
43+
fdeIm.isImplicit() and
44+
sameLocation(fdeIm, fc) and
45+
not mistypedFunctionArguments(fc, _, _) and
46+
not tooFewArguments(fc, _) and
47+
not tooManyArguments(fc, _)
48+
select fc, "Function call implicitly declares '" + fdeIm.getName() + "'."

cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql

Lines changed: 2 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -12,95 +12,10 @@
1212
*/
1313

1414
import cpp
15-
16-
predicate arithTypesMatch(Type arg, Type parm) {
17-
arg = parm
18-
or
19-
arg.getSize() = parm.getSize() and
20-
(
21-
arg instanceof IntegralOrEnumType and
22-
parm instanceof IntegralOrEnumType
23-
or
24-
arg instanceof FloatingPointType and
25-
parm instanceof FloatingPointType
26-
)
27-
}
28-
29-
pragma[inline]
30-
predicate nestedPointerArgTypeMayBeUsed(Type arg, Type parm) {
31-
// arithmetic types
32-
arithTypesMatch(arg, parm)
33-
or
34-
// conversion to/from pointers to void is allowed
35-
arg instanceof VoidType
36-
or
37-
parm instanceof VoidType
38-
}
39-
40-
pragma[inline]
41-
predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
42-
nestedPointerArgTypeMayBeUsed(arg, parm)
43-
or
44-
// nested pointers
45-
nestedPointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
46-
parm.(PointerType).getBaseType().getUnspecifiedType())
47-
or
48-
nestedPointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
49-
parm.(PointerType).getBaseType().getUnspecifiedType())
50-
}
51-
52-
pragma[inline]
53-
predicate argTypeMayBeUsed(Type arg, Type parm) {
54-
// arithmetic types
55-
arithTypesMatch(arg, parm)
56-
or
57-
// pointers to compatible types
58-
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
59-
parm.(PointerType).getBaseType().getUnspecifiedType())
60-
or
61-
pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
62-
parm.(PointerType).getBaseType().getUnspecifiedType())
63-
or
64-
// C11 arrays
65-
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
66-
parm.(ArrayType).getBaseType().getUnspecifiedType())
67-
or
68-
pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
69-
parm.(ArrayType).getBaseType().getUnspecifiedType())
70-
}
71-
72-
// This predicate holds whenever expression `arg` may be used to initialize
73-
// function parameter `parm` without need for run-time conversion.
74-
pragma[inline]
75-
predicate argMayBeUsed(Expr arg, Parameter parm) {
76-
argTypeMayBeUsed(arg.getFullyConverted().getUnspecifiedType(), parm.getUnspecifiedType())
77-
}
78-
79-
// True if function was ()-declared, but not (void)-declared or K&R-defined
80-
predicate hasZeroParamDecl(Function f) {
81-
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
82-
not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition()
83-
)
84-
}
85-
86-
// True if this file (or header) was compiled as a C file
87-
predicate isCompiledAsC(File f) {
88-
f.compiledAsC()
89-
or
90-
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
91-
}
15+
import MistypedFunctionArguments
9216

9317
from FunctionCall fc, Function f, Parameter p
94-
where
95-
f = fc.getTarget() and
96-
p = f.getAParameter() and
97-
hasZeroParamDecl(f) and
98-
isCompiledAsC(f.getFile()) and
99-
not f.isVarargs() and
100-
not f instanceof BuiltInFunction and
101-
p.getIndex() < fc.getNumberOfArguments() and
102-
// Parameter p and its corresponding call argument must have mismatched types
103-
not argMayBeUsed(fc.getArgument(p.getIndex()), p)
18+
where mistypedFunctionArguments(fc, f, p)
10419
select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
10520
fc.getArgument(p.getIndex()) as arg, arg.toString(),
10621
arg.getExplicitlyConverted().getUnspecifiedType() as atype, atype.toString(), p, p.getTypedName()

0 commit comments

Comments
 (0)