QL code and tests for C#/C++/JavaScript.

This commit is contained in:
Pavel Avgustinov
2018-08-02 17:53:23 +01:00
commit b55526aa58
10684 changed files with 581163 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
void v(int i) {
int *j = &i;
}

View File

@@ -0,0 +1,10 @@
struct S {
char* name;
};
void v()
{
char c[] = "hello";
struct S s;
s.name = c;
}

View File

@@ -0,0 +1,3 @@
void v(char *c, void *v) {
c = (char *)v;
}

View File

@@ -0,0 +1,5 @@
void v() {
int j = 0;
while(int k = j < 5) {
}
}

View File

@@ -0,0 +1,21 @@
class C {
public:
C(int i) {
}
};
class D {
public:
D() {
}
};
class E {
public:
};
void v(C *c, D *d, E *e) {
c = new C(5);
d = new D();
e = new E();
}

View File

@@ -0,0 +1,4 @@
void v() {
int i = (int)1;
}

View File

@@ -0,0 +1,3 @@
void v(int x) {
x = (int)5 + (int)7;
}

View File

@@ -0,0 +1,3 @@
void v(int x) {
x = (bool)(int)5 + ((int)7);
}

View File

@@ -0,0 +1,3 @@
void v(int x) {
x = ((int)7);
}

View File

@@ -0,0 +1,14 @@
class C {
public:
~C() {
}
};
class D {
public:
};
void v(C *c, D *d) {
delete c;
delete d;
}

View File

@@ -0,0 +1,14 @@
class Base {
virtual void f() { }
};
class Derived : public Base {
void f() { }
};
void v(Base *bp, Derived *d) {
d = dynamic_cast<Derived *>(bp);
}
void v_ref(Base &bp, Derived &d) {
d = dynamic_cast<Derived &>(bp);
}

View File

@@ -0,0 +1,3 @@
void v(int i) {
i = (i + 1) * 2;
}

View File

@@ -0,0 +1,3 @@
void v(int *i, int j) {
j = *i;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
semmle/code/cpp/PrintAST.ql

View File

@@ -0,0 +1,6 @@
/*
there is an implicit compiler-generated dereference node before the access to the variable 'i'
*/
void v(int &i, int j) {
j = i;
}

View File

@@ -0,0 +1,3 @@
int& v(int *i) {
return *i;
}

View File

@@ -0,0 +1,4 @@
void v(int array[]) {
int i = sizeof(int);
int j = sizeof(array);
}

View File

@@ -0,0 +1,3 @@
void v() {
int j = ({ int i = 5; i; });
}

View File

@@ -0,0 +1,9 @@
struct X {
static int i;
};
void v(int i, X &xref) {
// i = X::i;
i = xref.i;
}

View File

@@ -0,0 +1,3 @@
void v(int i[], int j) {
j = i[5];
}

View File

@@ -0,0 +1,16 @@
class E { };
class F {
public:
F() { }
};
void f(int i) {
try {
if(i)
throw E();
else
throw F();
} catch(E *e) {
throw;
}
}

View File

@@ -0,0 +1,20 @@
namespace std
{
class type_info
{
public:
const char *name() const;
};
}
class Base {
public:
virtual void v() { }
};
class Derived : public Base {
};
void v(Base *bp) {
const char *name = typeid(bp).name();
}

View File

@@ -0,0 +1,11 @@
template<class T>
void v(T x, T *y) {
x.T::~T();
y->T::~T();
}
void f(int i) {
// An int doesn't have a destructor, but we get to call it anyway through a
// template.
v(i, &i);
}

View File

@@ -0,0 +1,12 @@
typedef __builtin_va_list __gnuc_va_list;
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#define va_copy(d,s) __builtin_va_copy(d,s)
typedef __gnuc_va_list va_list;
void output(const char *text, ...) {
va_list args;
va_start(args, text);
va_end (args);
}

View File

@@ -0,0 +1,3 @@
This directory contains the C++ demo queries used on LGTM that are not also
standard queries. Maintaining this copy should ensure that they continue to
work.

View File

@@ -0,0 +1 @@
| test.cpp:10:5:10:17 | ... = ... | Assignment of '0' to parameter '$@' has no effect. | test.cpp:3:42:3:44 | buf | buf |

View File

@@ -0,0 +1,17 @@
/**
* @name Assignment to parameter has no effect
* @description An assignment to a parameter that is not subsequently read may
* indicate a logic error.
* @kind problem
* @problem.severity warning
*/
import cpp
from Parameter p, Assignment assign
where assign = p.getAnAssignment()
and not assign.getASuccessor+() = p.getAnAccess()
and not p.getType() instanceof ReferenceType
select assign, "Assignment of '"+ assign.getRValue() +
"' to parameter '$@' has no effect.",
p, p.getName()

View File

@@ -0,0 +1 @@
| test.cpp:4:9:4:17 | ... == ... | Expression tested for equality with 'true' |

View File

@@ -0,0 +1,15 @@
/**
* @name Equality test on Boolean
* @description Testing equality with `true` is redundant
* and can make the code harder to read.
* @kind problem
* @problem.severity warning
*/
import cpp
from EqualityOperation eq, Expr trueExpr
where
trueExpr = eq.getAnOperand() and
trueExpr.getType() instanceof BoolType and
trueExpr.getValue().toInt() = 1
select eq, "Expression tested for equality with 'true'"

View File

@@ -0,0 +1 @@
| test.cpp:5:9:5:15 | call to sprintf | sprintf called with variable format string. |

View File

@@ -0,0 +1,16 @@
/**
* @name Call to sprintf with non-literal format string
* @description Passing a non-constant 'format' string to a printf-like
* function can lead to a mismatch between the number of arguments
* defined by the 'format' and the number of arguments actually
* passed to the function. If the format string ultimately stems
* from an untrusted source, this can be used for exploits.
* @kind problem
* @problem.severity warning
*/
import cpp
from FunctionCall fc
where fc.getTarget().getQualifiedName() = "sprintf"
and not fc.getArgument(1) instanceof StringLiteral
select fc, "sprintf called with variable format string."

View File

@@ -0,0 +1,11 @@
long sprintf(char *buf, const char *format, ...);
void f(bool b, const char *format, char *buf) {
if (b == true) { // BAD
sprintf(buf, format, 5); // BAD
} else if (!b) { // GOOD
buf = buf + 1; // GOOD
sprintf(buf, "%d", 5); // GOOD
}
buf = nullptr; // BAD
}