Files
codeql/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.c
2018-09-24 14:37:09 +02:00

95 lines
3.3 KiB
C

long long f(short x, int y, long long z) {
y == x * x; // safe
y == x * (int)x; // safe
z == y * x; // unsafe
z == (long long)(y * x); // we assume the user knows what they are doing
if(x == 56)
return y * y; // unsafe
if(x == 56)
return (long long)(y * y); // we assume the user knows what they are doing
return 42 * 23; // safe
}
void int_float(int i, int j, long long ll, float f, float g, double h, char c) {
// note: where cases are marked as 'dubious' that means there could be an overflow,
// but the target type does not imply that the developer anticipates one as with
// an int -> long long conversion. We should therefore not flag these cases.
double v1_1 = f * g; // unsafe (float -> double)
double v1_2 = f * (double)g; // safe
double v2_1 = (i + j) * f; // unsafe (float -> double)
double v2_2 = (i + j) * (double)f; // safe
double v3_1 = i * j; // dubious (int -> double)
double v3_2 = (double)i * j; // safe
double v3_3 = (long long)i * j; // safe
float v4_1 = i * j; // dubious (int -> float)
float v4_2 = i * (float)j; // safe
long long v5_1 = f * g; // safe (float -> long long)
long long v5_2 = f * (long long)g; // safe
long long v5_3 = (long long)f * (long long)g; // safe
int v6_1 = f * g; // safe (float -> int)
int v6_2 = (int)f * g; // safe
double v7_1 = f * f; // unsafe (float -> double)
double v7_2 = h * h; // safe
double v7_3 = (f * f); // unsafe (float -> double) [NOT DETECTED]
float v8_1 = f * f * 2.0; // dubious (float -> double -> float)
// ^ though 2.0 is strictly speaking a double, it's unlikely the author anticipates requiring a double here
float v8_2 = f * f * 2.0f; // safe (float -> float)
float v9_1 = f * 2.0 * f; // dubious (float -> double -> float)
float v9_2 = f * 2.0f * f; // safe (float -> float)
float v10_1 = 2.0 * f * f; // dubious (float -> double -> float)
float v10_2 = 2.0f * f * f; // safe (float -> float)
float v11_1 = (2.0 * 2.0) * f; // safe (one argument is const)
float v11_2 = (2.0f * 2.0f) * f; // safe
float v12_1 = 1.0 + f * f + f * f; // dubious (float -> double -> float)
float v12_2 = 1.0f + f * f + f * f; // safe
double v13_1 = f * f * 2.0; // unsafe (float -> double) [NOT DETECTED]
double v13_2 = f * f * 2.0f; // unsafe (float -> double)
long long v14_1 = i * (i + 2) + ll; // unsafe (int -> long long)
long long v14_2 = i * (i + 2ll) * ll; // safe
long long v14_3 = i * (i + (int)2ll) + ll; // unsafe (int -> long long)
}
typedef unsigned long long size_t;
void *malloc(size_t size);
void use_size_t(int W, int H)
{
int x = 10;
int y = 20;
const int vs[] = {10, 20};
malloc(W * H); // unsafe (int -> size_t)
malloc((size_t)W * (size_t)H); // safe
malloc(10 * 20); // safe (small values)
malloc(x * y); // safe (small values)
malloc(vs[0] * vs[1]); // safe (small values)
}
int printf(const char *format, ...);
void use_printf(float f, double d)
{
printf("%f", f * f); // safe (float -> double)
// ^ there's a float -> double varargs promotion here, but it's unlikely that the author anticipates requiring a double
printf("%f", d * d); // safe
}
size_t three_chars(unsigned char a, unsigned char b, unsigned char c) {
return a * b * c; // at most 16581375
}