mirror of
https://github.com/github/codeql.git
synced 2026-04-27 01:35:13 +02:00
C++: Post-processing query for inline test expectations
This commit is contained in:
@@ -5,31 +5,5 @@
|
||||
|
||||
import cpp as C
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
private module Impl implements InlineExpectationsTestSig {
|
||||
private newtype TExpectationComment = MkExpectationComment(C::CppStyleComment c)
|
||||
|
||||
/**
|
||||
* A class representing a line comment in the CPP style.
|
||||
* Unlike the `CppStyleComment` class, however, the string returned by `getContents` does _not_
|
||||
* include the preceding comment marker (`//`).
|
||||
*/
|
||||
class ExpectationComment extends TExpectationComment {
|
||||
C::CppStyleComment comment;
|
||||
|
||||
ExpectationComment() { this = MkExpectationComment(comment) }
|
||||
|
||||
/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
|
||||
string getContents() { result = comment.getContents().suffix(2) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = comment.toString() }
|
||||
|
||||
/** Gets the location of this comment. */
|
||||
Location getLocation() { result = comment.getLocation() }
|
||||
}
|
||||
|
||||
class Location = C::Location;
|
||||
}
|
||||
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import Make<Impl>
|
||||
|
||||
21
cpp/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
21
cpp/ql/test/TestUtilities/InlineExpectationsTestQuery.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @kind test-postprocess
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import codeql.util.test.InlineExpectationsTest as T
|
||||
private import internal.InlineExpectationsTestImpl
|
||||
import T::TestPostProcessing
|
||||
import T::TestPostProcessing::Make<Impl, Input>
|
||||
|
||||
private module Input implements T::TestPostProcessing::InputSig<Impl> {
|
||||
string getRelativeUrl(Location location) {
|
||||
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
|
||||
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
|
||||
f = location.getFile()
|
||||
|
|
||||
result =
|
||||
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import cpp as C
|
||||
private import codeql.util.test.InlineExpectationsTest
|
||||
|
||||
module Impl implements InlineExpectationsTestSig {
|
||||
private newtype TExpectationComment = MkExpectationComment(C::CppStyleComment c)
|
||||
|
||||
/**
|
||||
* A class representing a line comment in the CPP style.
|
||||
* Unlike the `CppStyleComment` class, however, the string returned by `getContents` does _not_
|
||||
* include the preceding comment marker (`//`).
|
||||
*/
|
||||
class ExpectationComment extends TExpectationComment {
|
||||
C::CppStyleComment comment;
|
||||
|
||||
ExpectationComment() { this = MkExpectationComment(comment) }
|
||||
|
||||
/** Returns the contents of the given comment, _without_ the preceding comment marker (`//`). */
|
||||
string getContents() { result = comment.getContents().suffix(2) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = comment.toString() }
|
||||
|
||||
/** Gets the location of this comment. */
|
||||
Location getLocation() { result = comment.getLocation() }
|
||||
}
|
||||
|
||||
class Location = C::Location;
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
Critical/SizeCheck.ql
|
||||
query: Critical/SizeCheck.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -13,8 +13,8 @@ void free(void *ptr);
|
||||
|
||||
void bad0(void) {
|
||||
|
||||
float *fptr = malloc(3); // BAD -- Too small
|
||||
double *dptr = malloc(5); // BAD -- Too small
|
||||
float *fptr = malloc(3); // $ Alert -- Too small
|
||||
double *dptr = malloc(5); // $ Alert -- Too small
|
||||
free(fptr);
|
||||
free(dptr);
|
||||
}
|
||||
@@ -29,8 +29,8 @@ void good0(void) {
|
||||
|
||||
void bad1(void) {
|
||||
|
||||
float *fptr = malloc(sizeof(short)); // BAD -- Too small
|
||||
double *dptr = malloc(sizeof(float)); // BAD -- Too small
|
||||
float *fptr = malloc(sizeof(short)); // $ Alert -- Too small
|
||||
double *dptr = malloc(sizeof(float)); // $ Alert -- Too small
|
||||
free(fptr);
|
||||
free(dptr);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ typedef union _myUnion
|
||||
|
||||
void test_union() {
|
||||
MyUnion *a = malloc(sizeof(MyUnion)); // GOOD
|
||||
MyUnion *b = malloc(sizeof(MyStruct)); // BAD (too small)
|
||||
MyUnion *b = malloc(sizeof(MyStruct)); // $ Alert (too small)
|
||||
}
|
||||
|
||||
// --- custom allocators ---
|
||||
@@ -66,6 +66,6 @@ void *MyMalloc2(size_t size);
|
||||
|
||||
void customAllocatorTests()
|
||||
{
|
||||
float *fptr1 = MyMalloc1(3); // BAD (too small) [NOT DETECTED]
|
||||
float *fptr2 = MyMalloc2(3); // BAD (too small) [NOT DETECTED]
|
||||
float *fptr1 = MyMalloc1(3); // $ MISSING: BAD (too small)
|
||||
float *fptr2 = MyMalloc2(3); // $ MISSING: BAD (too small)
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
Security/CWE/CWE-022/TaintedPath.ql
|
||||
query: Security/CWE/CWE-022/TaintedPath.ql
|
||||
postprocess: TestUtilities/InlineExpectationsTestQuery.ql
|
||||
@@ -5,7 +5,7 @@
|
||||
#define PATH_MAX 4096
|
||||
///// Test code /////
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main(int argc, char** argv) { // $ Source=argv
|
||||
char *userAndFile = argv[2];
|
||||
|
||||
{
|
||||
@@ -14,7 +14,7 @@ int main(int argc, char** argv) {
|
||||
size_t len = strlen(fileName);
|
||||
strncat(fileName+len, userAndFile, FILENAME_MAX-len-1);
|
||||
// BAD: a string from the user is used in a filename
|
||||
fopen(fileName, "wb+");
|
||||
fopen(fileName, "wb+"); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
@@ -29,30 +29,30 @@ int main(int argc, char** argv) {
|
||||
|
||||
{
|
||||
char *fileName = argv[1];
|
||||
fopen(fileName, "wb+"); // BAD
|
||||
fopen(fileName, "wb+"); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
char fileName[20];
|
||||
scanf("%s", fileName);
|
||||
fopen(fileName, "wb+"); // BAD
|
||||
scanf("%s", fileName); // $ Source=scanf_output1
|
||||
fopen(fileName, "wb+"); // $ Alert=scanf_output1
|
||||
}
|
||||
|
||||
{
|
||||
char *fileName = (char*)malloc(20 * sizeof(char));
|
||||
scanf("%s", fileName);
|
||||
fopen(fileName, "wb+"); // BAD
|
||||
scanf("%s", fileName); // $ Source=scanf_output2
|
||||
fopen(fileName, "wb+"); // $ Alert=scanf_output2
|
||||
}
|
||||
|
||||
{
|
||||
char *tainted = getenv("A_STRING");
|
||||
fopen(tainted, "wb+"); // BAD
|
||||
char *tainted = getenv("A_STRING"); // $ Source=getenv1
|
||||
fopen(tainted, "wb+"); // $ Alert=getenv1
|
||||
}
|
||||
|
||||
{
|
||||
char buffer[1024];
|
||||
strncpy(buffer, getenv("A_STRING"), 1024);
|
||||
fopen(buffer, "wb+"); // BAD
|
||||
strncpy(buffer, getenv("A_STRING"), 1024); // $ Source=getenv2
|
||||
fopen(buffer, "wb+"); // $ Alert=getenv2
|
||||
fopen(buffer, "wb+"); // (we don't want a duplicate result here)
|
||||
}
|
||||
|
||||
@@ -66,14 +66,14 @@ int main(int argc, char** argv) {
|
||||
|
||||
{
|
||||
void readFile(const char *fileName);
|
||||
readFile(argv[1]); // BAD
|
||||
readFile(argv[1]); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
char buffer[1024];
|
||||
read(0, buffer, 1024);
|
||||
read(0, buffer, 1024);
|
||||
fopen(buffer, "wb+"); // BAD [duplicated with both sources]
|
||||
read(0, buffer, 1024); // $ Source=read_output1
|
||||
read(0, buffer, 1024); // $ Source=read_output2
|
||||
fopen(buffer, "wb+"); // $ Alert=read_output1 $ Alert=read_output2
|
||||
}
|
||||
|
||||
{
|
||||
@@ -81,7 +81,7 @@ int main(int argc, char** argv) {
|
||||
char fileBuffer[PATH_MAX];
|
||||
snprintf(fileBuffer, sizeof(fileBuffer), "/home/%s", userAndFile);
|
||||
// BAD: a string from the user is used in a filename
|
||||
fopen(fileBuffer, "wb+");
|
||||
fopen(fileBuffer, "wb+"); // $ Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
@@ -95,7 +95,7 @@ int main(int argc, char** argv) {
|
||||
char fileBuffer[PATH_MAX];
|
||||
snprintf(fileBuffer, sizeof(fileBuffer), "/home/user/files/%s", fileName);
|
||||
// GOOD: We know that the filename is safe and stays within the public folder. But we currently get an FP here.
|
||||
FILE *file = fopen(fileBuffer, "wb+");
|
||||
FILE *file = fopen(fileBuffer, "wb+"); // $ SPURIOUS: Alert=argv
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user