Merge branch 'main' into aliasperf2

This commit is contained in:
Geoffrey White
2024-10-10 17:25:45 +01:00
155 changed files with 24915 additions and 8611 deletions

View File

@@ -6,7 +6,7 @@ int wprintf (const wchar_t* format, ...);
int strlen( const char * string );
int checkErrors();
void goodTest0()
static void goodTest0()
{
char * ptr = "123456789";
int ret;
@@ -17,7 +17,7 @@ void goodTest0()
ptr += ret;
}
}
void goodTest1(const char* ptr)
static void goodTest1(const char* ptr)
{
int ret;
int len;
@@ -27,7 +27,7 @@ void goodTest1(const char* ptr)
ptr += ret;
}
}
void goodTest2(char* ptr)
static void goodTest2(char* ptr)
{
int ret;
ptr[10]=0;
@@ -38,7 +38,7 @@ void goodTest2(char* ptr)
}
}
void goodTest3(const char* ptr)
static void goodTest3(const char* ptr)
{
int ret;
int len;
@@ -48,7 +48,7 @@ void goodTest3(const char* ptr)
ptr += ret;
}
}
void goodTest4(const char* ptr)
static void goodTest4(const char* ptr)
{
int ret;
int len;
@@ -58,7 +58,7 @@ void goodTest4(const char* ptr)
ptr += ret;
}
}
void badTest1(const char* ptr)
static void badTest1(const char* ptr)
{
int ret;
int len;
@@ -68,7 +68,7 @@ void badTest1(const char* ptr)
ptr += ret;
}
}
void badTest2(const char* ptr)
static void badTest2(const char* ptr)
{
int ret;
int len;
@@ -79,7 +79,7 @@ void badTest2(const char* ptr)
}
}
void goodTest5(const char* ptr,wchar_t *wc,int wc_len)
static void goodTest5(const char* ptr,wchar_t *wc,int wc_len)
{
int ret;
int len;
@@ -96,7 +96,7 @@ void goodTest5(const char* ptr,wchar_t *wc,int wc_len)
}
}
void badTest3(const char* ptr,int wc_len)
static void badTest3(const char* ptr,int wc_len)
{
int ret;
int len;
@@ -113,7 +113,7 @@ void badTest3(const char* ptr,int wc_len)
wc++;
}
}
void badTest4(const char* ptr,int wc_len)
static void badTest4(const char* ptr,int wc_len)
{
int ret;
int len;
@@ -130,7 +130,7 @@ void badTest4(const char* ptr,int wc_len)
wc++;
}
}
void badTest5(const char* ptr,int wc_len)
static void badTest5(const char* ptr,int wc_len)
{
int ret;
int len;
@@ -148,7 +148,7 @@ void badTest5(const char* ptr,int wc_len)
}
}
void badTest6(const char* ptr,int wc_len)
static void badTest6(const char* ptr,int wc_len)
{
int ret;
int len;
@@ -171,7 +171,7 @@ void badTest6(const char* ptr,int wc_len)
ptr+=ret;
}
}
void badTest7(const char* ptr,int wc_len)
static void badTest7(const char* ptr,int wc_len)
{
int ret;
int len;
@@ -188,7 +188,7 @@ void badTest7(const char* ptr,int wc_len)
ptr+=ret;
}
}
void badTest8(const char* ptr,wchar_t *wc)
static void badTest8(const char* ptr,wchar_t *wc)
{
int ret;
int len;

View File

@@ -24,7 +24,7 @@ typedef unsigned int size_t;
void* calloc (size_t num, size_t size);
void* malloc (size_t size);
void badTest1(void *src, int size) {
static void badTest1(void *src, int size) {
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, (LPSTR)src, size, 0, 0); // BAD
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, (LPCWSTR)src, 30); // BAD
}
@@ -39,43 +39,43 @@ void goodTest2(){
}
printf("%s\n", dst);
}
void badTest2(){
static void badTest2(){
wchar_t src[] = L"0123456789ABCDEF";
char dst[16];
WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, 16, NULL, NULL); // BAD
printf("%s\n", dst);
}
void goodTest3(){
static void goodTest3(){
char src[] = "0123456789ABCDEF";
int size = MultiByteToWideChar(CP_UTF8, 0, src,sizeof(src),NULL,0);
wchar_t * dst = (wchar_t*)calloc(size + 1, sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // GOOD
}
void badTest3(){
static void badTest3(){
char src[] = "0123456789ABCDEF";
int size = MultiByteToWideChar(CP_UTF8, 0, src,sizeof(src),NULL,0);
wchar_t * dst = (wchar_t*)calloc(size + 1, 1);
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // BAD
}
void goodTest4(){
static void goodTest4(){
char src[] = "0123456789ABCDEF";
int size = MultiByteToWideChar(CP_UTF8, 0, src,sizeof(src),NULL,0);
wchar_t * dst = (wchar_t*)malloc((size + 1)*sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // GOOD
}
void badTest4(){
static void badTest4(){
char src[] = "0123456789ABCDEF";
int size = MultiByteToWideChar(CP_UTF8, 0, src,sizeof(src),NULL,0);
wchar_t * dst = (wchar_t*)malloc(size + 1);
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // BAD
}
int goodTest5(void *src){
static int goodTest5(void *src){
return WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, 0, 0, 0, 0); // GOOD
}
int badTest5 (void *src) {
static int badTest5 (void *src) {
return WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, 0, 3, 0, 0); // BAD
}
void goodTest6(WCHAR *src)
static void goodTest6(WCHAR *src)
{
int size;
char dst[5] ="";
@@ -87,7 +87,7 @@ void goodTest6(WCHAR *src)
WideCharToMultiByte(CP_ACP, 0, src, -1, dst, sizeof(dst), 0, 0); // GOOD
printf("%s\n", dst);
}
void badTest6(WCHAR *src)
static void badTest6(WCHAR *src)
{
char dst[5] ="";
WideCharToMultiByte(CP_ACP, 0, src, -1, dst, 260, 0, 0); // BAD

View File

@@ -11,14 +11,14 @@ size_t _mbstowcs_l(wchar_t *wcstr,const char *mbstr,size_t count, _locale_t loca
size_t mbsrtowcs(wchar_t *wcstr,const char *mbstr,size_t count, mbstate_t *mbstate);
void badTest1(void *src, int size) {
static void badTest1(void *src, int size) {
mbstowcs((wchar_t*)src,(char*)src,size); // BAD
_locale_t locale;
_mbstowcs_l((wchar_t*)src,(char*)src,size,locale); // BAD
mbstate_t *mbstate;
mbsrtowcs((wchar_t*)src,(char*)src,size,mbstate); // BAD
}
void goodTest2(){
static void goodTest2(){
char src[] = "0123456789ABCDEF";
wchar_t dst[16];
int res = mbstowcs(dst, src,16); // GOOD
@@ -29,43 +29,43 @@ void goodTest2(){
}
printf("%s\n", dst);
}
void badTest2(){
static void badTest2(){
char src[] = "0123456789ABCDEF";
wchar_t dst[16];
mbstowcs(dst, src,16); // BAD
printf("%s\n", dst);
}
void goodTest3(){
static void goodTest3(){
char src[] = "0123456789ABCDEF";
int size = mbstowcs(NULL, src,NULL);
wchar_t * dst = (wchar_t*)calloc(size + 1, sizeof(wchar_t));
mbstowcs(dst, src,size+1); // GOOD
}
void badTest3(){
static void badTest3(){
char src[] = "0123456789ABCDEF";
int size = mbstowcs(NULL, src,NULL);
wchar_t * dst = (wchar_t*)calloc(size + 1, 1);
mbstowcs(dst, src,size+1); // BAD
}
void goodTest4(){
static void goodTest4(){
char src[] = "0123456789ABCDEF";
int size = mbstowcs(NULL, src,NULL);
wchar_t * dst = (wchar_t*)malloc((size + 1)*sizeof(wchar_t));
mbstowcs(dst, src,size+1); // GOOD
}
void badTest4(){
static void badTest4(){
char src[] = "0123456789ABCDEF";
int size = mbstowcs(NULL, src,NULL);
wchar_t * dst = (wchar_t*)malloc(size + 1);
mbstowcs(dst, src,size+1); // BAD
}
int goodTest5(void *src){
static int goodTest5(void *src){
return mbstowcs(NULL, (char*)src,NULL); // GOOD
}
int badTest5 (void *src) {
static int badTest5 (void *src) {
return mbstowcs(NULL, (char*)src,3); // BAD
}
void goodTest6(void *src){
static void goodTest6(void *src){
wchar_t dst[5];
int size = mbstowcs(NULL, (char*)src,NULL);
if(size>=sizeof(dst)){
@@ -75,7 +75,7 @@ void goodTest6(void *src){
mbstowcs(dst, (char*)src,sizeof(dst)); // GOOD
printf("%s\n", dst);
}
void badTest6(void *src){
static void badTest6(void *src){
wchar_t dst[5];
mbstowcs(dst, (char*)src,260); // BAD
printf("%s\n", dst);

View File

@@ -9,14 +9,14 @@ void goodTest1(unsigned char *src){
unsigned char dst[50];
_mbsnbcpy(dst,src,sizeof(dst)); // GOOD
}
size_t badTest1(unsigned char *src){
static size_t badTest1(unsigned char *src){
int cb = 0;
unsigned char dst[50];
while( cb < sizeof(dst) )
dst[cb++]=*src++; // BAD
return _mbclen(dst);
}
void goodTest2(unsigned char *src){
static void goodTest2(unsigned char *src){
int cb = 0;
unsigned char dst[50];
@@ -27,7 +27,7 @@ void goodTest2(unsigned char *src){
src=_mbsinc(src);
}
}
void badTest2(unsigned char *src){
static void badTest2(unsigned char *src){
int cb = 0;
unsigned char dst[50];
@@ -38,11 +38,11 @@ void badTest2(unsigned char *src){
src=_mbsinc(src);
}
}
void goodTest3(){
static void goodTest3(){
wchar_t name[50];
name[sizeof(name) / sizeof(*name) - 1] = L'\0'; // GOOD
}
void badTest3(){
static void badTest3(){
wchar_t name[50];
name[sizeof(name) - 1] = L'\0'; // BAD
}

View File

@@ -78,7 +78,7 @@ int* deref(int** p) { // $ ast-def=p ir-def=*p ir-def=**p
return q;
}
void test1() {
void flowout_test1() {
int x = 0;
int* p = &x;
deref(&p)[0] = source();
@@ -95,7 +95,7 @@ void addtaint2(int** p) { // $ ast-def=p ir-def=*p ir-def=**p
addtaint1(q);
}
void test2() {
void flowout_test2() {
int x = 0;
int* p = &x;
addtaint2(&p);

View File

@@ -15,7 +15,7 @@ template<> struct std::iterator_traits<unsigned long>
};
int test() {
int iterator_test() {
unsigned long x = source();
sink(x); // $ ast ir
}

View File

@@ -5,7 +5,7 @@ int source();
void sink(...);
bool random();
void test1() {
void on_entry_test1() {
int x = source();
for (int i = 0; i < 10; i++) {
x = 0;
@@ -13,7 +13,7 @@ void test1() {
sink(x); // $ SPURIOUS: ir
}
void test2(int iterations) {
void on_entry_test2(int iterations) {
int x = source();
for (int i = 0; i < iterations; i++) {
x = 0;
@@ -21,7 +21,7 @@ void test2(int iterations) {
sink(x); // $ ast,ir
}
void test3() {
void on_entry_test3() {
int x = 0;
for (int i = 0; i < 10; i++) {
x = source();
@@ -29,7 +29,7 @@ void test3() {
sink(x); // $ ast,ir
}
void test4() {
void on_entry_test4() {
int x = source();
for (int i = 0; i < 10; i++) {
if (random())
@@ -39,7 +39,7 @@ void test4() {
sink(x); // $ ast,ir
}
void test5() {
void on_entry_test5() {
int x = source();
for (int i = 0; i < 10; i++) {
if (random())
@@ -49,7 +49,7 @@ void test5() {
sink(x); // $ ast,ir
}
void test6() {
void on_entry_test6() {
int y;
int x = source();
for (int i = 0; i < 10 && (y = 1); i++) {
@@ -57,7 +57,7 @@ void test6() {
sink(x); // $ ast,ir
}
void test7() {
void on_entry_test7() {
int y;
int x = source();
for (int i = 0; i < 10 && (y = 1); i++) {
@@ -66,7 +66,7 @@ void test7() {
sink(x); // $ SPURIOUS: ir
}
void test8() {
void on_entry_test8() {
int x = source();
// It appears to the analysis that the condition can exit after `i < 10`
// without having assigned to `x`. That is an effect of how the
@@ -78,7 +78,7 @@ void test8() {
sink(x); // $ SPURIOUS: ast,ir
}
void test9() {
void on_entry_test9() {
int y;
int x = source();
for (int i = 0; (y = 1) && i < 10; i++) {
@@ -86,14 +86,14 @@ void test9() {
sink(x); // $ ast,ir
}
void test10() {
void on_entry_test10() {
int x = source();
for (int i = 0; (x = 1) && i < 10; i++) {
}
sink(x); // no flow
}
void test10(int b, int d) {
void on_entry_test10(int b, int d) {
int i = 0;
int x = source();
if (b)

View File

@@ -23564,6 +23564,26 @@ ir.cpp:
# 2686| Value = [CStyleCast] 0
# 2686| ValueCategory = prvalue
# 2687| getStmt(1): [ReturnStmt] return ...
# 2691| [TopLevelFunction] int concepts::requires_use()
# 2691| <params>:
# 2691| getEntryPoint(): [BlockStmt] { ... }
# 2692| getStmt(0): [DeclStmt] declaration
# 2692| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
# 2692| Type = [IntType] int
# 2692| getVariable().getInitializer(): [Initializer] initializer for y
#-----| getExpr(): [RequiresExpr] requires ...
#-----| Type = [BoolType] bool
#-----| Value = [RequiresExpr] 1
#-----| ValueCategory = prvalue
#-----| getExpr().getFullyConverted(): [CStyleCast] (int)...
#-----| Conversion = [IntegralConversion] integral conversion
#-----| Type = [IntType] int
#-----| Value = [CStyleCast] 1
#-----| ValueCategory = prvalue
# 2693| getStmt(1): [ReturnStmt] return ...
# 2693| getExpr(): [VariableAccess] y
# 2693| Type = [IntType] int
# 2693| ValueCategory = prvalue(load)
many-defs-per-use.cpp:
# 34| [TopLevelFunction] void many_defs_per_use()
# 34| <params>:

View File

@@ -19099,6 +19099,24 @@ ir.cpp:
# 2684| Block 8
# 2684| v2684_14(void) = Unreached :
# 2691| int concepts::requires_use()
# 2691| Block 0
# 2691| v2691_1(void) = EnterFunction :
# 2691| m2691_2(unknown) = AliasedDefinition :
# 2691| m2691_3(unknown) = InitializeNonLocal :
# 2691| m2691_4(unknown) = Chi : total:m2691_2, partial:m2691_3
# 2692| r2692_1(glval<int>) = VariableAddress[y] :
#-----| r0_1(int) = Constant[1] :
#-----| m0_2(int) = Store[y] : &:r2692_1, r0_1
# 2693| r2693_1(glval<int>) = VariableAddress[#return] :
# 2693| r2693_2(glval<int>) = VariableAddress[y] :
# 2693| r2693_3(int) = Load[y] : &:r2693_2, m0_2
# 2693| m2693_4(int) = Store[#return] : &:r2693_1, r2693_3
# 2691| r2691_5(glval<int>) = VariableAddress[#return] :
# 2691| v2691_6(void) = ReturnValue : &:r2691_5, m2693_4
# 2691| v2691_7(void) = AliasedUse : m2691_3
# 2691| v2691_8(void) = ExitFunction :
many-defs-per-use.cpp:
# 34| void many_defs_per_use()
# 34| Block 0

View File

@@ -2686,4 +2686,13 @@ void test(bool b)
twice_call_use(b ? "" : "");
}
namespace concepts {
int requires_use() {
int y = requires { sizeof(int) > 0; };
return y;
}
}
// semmle-extractor-options: -std=c++20 --clang

View File

@@ -17422,6 +17422,23 @@ ir.cpp:
# 2684| v2684_7(void) = AliasedUse : ~m?
# 2684| v2684_8(void) = ExitFunction :
# 2691| int concepts::requires_use()
# 2691| Block 0
# 2691| v2691_1(void) = EnterFunction :
# 2691| mu2691_2(unknown) = AliasedDefinition :
# 2691| mu2691_3(unknown) = InitializeNonLocal :
# 2692| r2692_1(glval<int>) = VariableAddress[y] :
#-----| r0_1(int) = Constant[1] :
#-----| mu0_2(int) = Store[y] : &:r2692_1, r0_1
# 2693| r2693_1(glval<int>) = VariableAddress[#return] :
# 2693| r2693_2(glval<int>) = VariableAddress[y] :
# 2693| r2693_3(int) = Load[y] : &:r2693_2, ~m?
# 2693| mu2693_4(int) = Store[#return] : &:r2693_1, r2693_3
# 2691| r2691_4(glval<int>) = VariableAddress[#return] :
# 2691| v2691_5(void) = ReturnValue : &:r2691_4, ~m?
# 2691| v2691_6(void) = AliasedUse : ~m?
# 2691| v2691_7(void) = ExitFunction :
many-defs-per-use.cpp:
# 34| void many_defs_per_use()
# 34| Block 0

View File

@@ -2,29 +2,36 @@ edges
| test1.c:7:26:7:29 | **argv | test1.c:8:11:8:14 | call to atoi | provenance | TaintFunction |
| test1.c:8:11:8:14 | call to atoi | test1.c:9:9:9:9 | i | provenance | |
| test1.c:8:11:8:14 | call to atoi | test1.c:11:9:11:9 | i | provenance | |
| test1.c:8:11:8:14 | call to atoi | test1.c:12:9:12:9 | i | provenance | |
| test1.c:8:11:8:14 | call to atoi | test1.c:13:9:13:9 | i | provenance | |
| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i | provenance | |
| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i | provenance | |
| test1.c:13:9:13:9 | i | test1.c:48:16:48:16 | i | provenance | |
| test1.c:16:16:16:16 | i | test1.c:18:16:18:16 | i | provenance | |
| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i | provenance | |
| test1.c:48:16:48:16 | i | test1.c:51:3:51:7 | ... = ... | provenance | |
| test1.c:51:3:51:7 | ... = ... | test1.c:53:15:53:15 | j | provenance | |
| test1.c:9:9:9:9 | i | test1.c:18:16:18:16 | i | provenance | |
| test1.c:11:9:11:9 | i | test1.c:34:16:34:16 | i | provenance | |
| test1.c:12:9:12:9 | i | test1.c:42:16:42:16 | i | provenance | |
| test1.c:13:9:13:9 | i | test1.c:50:16:50:16 | i | provenance | |
| test1.c:18:16:18:16 | i | test1.c:20:16:20:16 | i | provenance | |
| test1.c:34:16:34:16 | i | test1.c:35:11:35:11 | i | provenance | |
| test1.c:42:16:42:16 | i | test1.c:43:11:43:11 | i | provenance | |
| test1.c:50:16:50:16 | i | test1.c:53:3:53:7 | ... = ... | provenance | |
| test1.c:53:3:53:7 | ... = ... | test1.c:55:15:55:15 | j | provenance | |
nodes
| test1.c:7:26:7:29 | **argv | semmle.label | **argv |
| test1.c:8:11:8:14 | call to atoi | semmle.label | call to atoi |
| test1.c:9:9:9:9 | i | semmle.label | i |
| test1.c:11:9:11:9 | i | semmle.label | i |
| test1.c:12:9:12:9 | i | semmle.label | i |
| test1.c:13:9:13:9 | i | semmle.label | i |
| test1.c:16:16:16:16 | i | semmle.label | i |
| test1.c:18:16:18:16 | i | semmle.label | i |
| test1.c:32:16:32:16 | i | semmle.label | i |
| test1.c:33:11:33:11 | i | semmle.label | i |
| test1.c:48:16:48:16 | i | semmle.label | i |
| test1.c:51:3:51:7 | ... = ... | semmle.label | ... = ... |
| test1.c:53:15:53:15 | j | semmle.label | j |
| test1.c:20:16:20:16 | i | semmle.label | i |
| test1.c:34:16:34:16 | i | semmle.label | i |
| test1.c:35:11:35:11 | i | semmle.label | i |
| test1.c:42:16:42:16 | i | semmle.label | i |
| test1.c:43:11:43:11 | i | semmle.label | i |
| test1.c:50:16:50:16 | i | semmle.label | i |
| test1.c:53:3:53:7 | ... = ... | semmle.label | ... = ... |
| test1.c:55:15:55:15 | j | semmle.label | j |
subpaths
#select
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | **argv | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | **argv | a command-line argument |
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | **argv | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | **argv | a command-line argument |
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | **argv | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | **argv | a command-line argument |
| test1.c:20:16:20:16 | i | test1.c:7:26:7:29 | **argv | test1.c:20:16:20:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | **argv | a command-line argument |
| test1.c:35:11:35:11 | i | test1.c:7:26:7:29 | **argv | test1.c:35:11:35:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | **argv | a command-line argument |
| test1.c:43:11:43:11 | i | test1.c:7:26:7:29 | **argv | test1.c:43:11:43:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | **argv | a command-line argument |
| test1.c:55:15:55:15 | j | test1.c:7:26:7:29 | **argv | test1.c:55:15:55:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | **argv | a command-line argument |

View File

@@ -11,6 +11,8 @@ int main(int argc, char *argv[]) {
test3(i);
test4(i);
test5(i);
test6(i);
test7(argv[1]);
}
void test1(int i) {
@@ -38,7 +40,7 @@ void test3(int i) {
}
void test4(int i) {
myArray[i] = 0; // BAD: i has not been validated [NOT REPORTED]
myArray[i] = 0; // BAD: i has not been validated
if ((i < 0) || (i >= 10)) return;
@@ -52,3 +54,26 @@ void test5(int i) {
j = myArray[j]; // BAD: j has not been validated
}
extern int myTable[256];
void test6(int i) {
unsigned char s = i;
myTable[s] = 0; // GOOD: Input is small [FALSE POSITIVE]
}
typedef void FILE;
#define EOF (-1)
int getc(FILE*);
extern int myMaxCharTable[256];
void test7(FILE* fp) {
int ch;
while ((ch = getc(fp)) != EOF) {
myMaxCharTable[ch] = 0; // GOOD
}
}

View File

@@ -11,14 +11,14 @@ char *strcpy(char *s1, const char *s2);
//// Test code /////
void bad0(char *str) {
static void bad0(char *str) {
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(strlen(str));
strcpy(buffer, str);
free(buffer);
}
void good0(char *str) {
static void good0(char *str) {
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc(strlen(str)+1);
strcpy(buffer, str);
@@ -26,7 +26,7 @@ void good0(char *str) {
}
void bad1(char *str) {
static void bad1(char *str) {
int len = strlen(str);
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(len);
@@ -34,7 +34,7 @@ void bad1(char *str) {
free(buffer);
}
void good1(char *str) {
static void good1(char *str) {
int len = strlen(str);
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc(len+1);
@@ -43,7 +43,7 @@ void good1(char *str) {
}
void bad2(char *str) {
static void bad2(char *str) {
int len = strlen(str);
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(len);
@@ -51,7 +51,7 @@ void bad2(char *str) {
free(buffer);
}
void good2(char *str) {
static void good2(char *str) {
int len = strlen(str)+1;
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc(len);
@@ -59,14 +59,14 @@ void good2(char *str) {
free(buffer);
}
void bad3(char *str) {
static void bad3(char *str) {
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(strlen(str) * sizeof(char));
strcpy(buffer, str);
free(buffer);
}
void good3(char *str) {
static void good3(char *str) {
// GOOD -- Allocating extra byte for terminator
char *buffer = malloc((strlen(str) + 1) * sizeof(char));
strcpy(buffer, str);
@@ -75,7 +75,7 @@ void good3(char *str) {
void *memcpy(void *s1, const void *s2, size_t n);
void good4(char *str) {
static void good4(char *str) {
// GOOD -- allocating a non zero-terminated string
int len = strlen(str);
char *buffer = malloc(len);

View File

@@ -19,28 +19,28 @@ int strcmp(const char *s1, const char *s2);
//// Test code /////
void bad1(wchar_t *wstr) {
static void bad1(wchar_t *wstr) {
// BAD -- Not allocating space for '\0' terminator
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(wstr));
wcscpy(wbuffer, wstr);
free(wbuffer);
}
void bad2(wchar_t *wstr) {
static void bad2(wchar_t *wstr) {
// BAD -- Not allocating space for '\0' terminator
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(wstr) * sizeof(wchar_t));
wcscpy(wbuffer, wstr);
free(wbuffer);
}
void good1(wchar_t *wstr) {
static void good1(wchar_t *wstr) {
// GOOD -- Allocating extra character for terminator
wchar_t *wbuffer = (wchar_t *)malloc((wcslen(wstr) + 1) * sizeof(wchar_t));
wcscpy(wbuffer, wstr);
free(wbuffer);
}
void bad3(char *str) {
static void bad3(char *str) {
// BAD -- zero-termination proved by sprintf (as destination)
char *buffer = (char *)malloc(strlen(str));
sprintf(buffer, "%s", str);
@@ -50,7 +50,7 @@ void bad3(char *str) {
void decode(char *dest, char *src);
void wdecode(wchar_t *dest, wchar_t *src);
void bad4(char *str) {
static void bad4(char *str) {
// BAD -- zero-termination proved by wprintf (as parameter)
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
@@ -58,7 +58,7 @@ void bad4(char *str) {
free(buffer);
}
void bad5(char *str) {
static void bad5(char *str) {
// BAD -- zero-termination proved by strcat (as destination)
char *buffer = (char *)malloc(strlen(str));
buffer[0] = 0;
@@ -66,7 +66,7 @@ void bad5(char *str) {
free(buffer);
}
void bad6(char *str, char *dest) {
static void bad6(char *str, char *dest) {
// BAD -- zero-termination proved by strcat (as source)
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
@@ -74,7 +74,7 @@ void bad6(char *str, char *dest) {
free(buffer);
}
void bad7(char *str, char *str2) {
static void bad7(char *str, char *str2) {
// BAD -- zero-termination proved by strcmp
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
@@ -84,7 +84,7 @@ void bad7(char *str, char *str2) {
free(buffer);
}
void bad8(wchar_t *str) {
static void bad8(wchar_t *str) {
// BAD -- zero-termination proved by wcslen
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(str));
wdecode(wbuffer, str);
@@ -94,21 +94,21 @@ void bad8(wchar_t *str) {
free(wbuffer);
}
void good2(char *str, char *dest) {
static void good2(char *str, char *dest) {
// GOOD -- zero-termination not proven
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
free(buffer);
}
void bad9(wchar_t *wstr) {
static void bad9(wchar_t *wstr) {
// BAD -- using new
wchar_t *wbuffer = new wchar_t[wcslen(wstr)];
wcscpy(wbuffer, wstr);
delete wbuffer;
}
void good3(char *str) {
static void good3(char *str) {
// GOOD -- zero-termination not required for this printf
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);
@@ -116,7 +116,7 @@ void good3(char *str) {
free(buffer);
}
void good4(char *str) {
static void good4(char *str) {
// GOOD -- zero-termination not required for this printf
char *buffer = (char *)malloc(strlen(str));
decode(buffer, str);

View File

@@ -38,35 +38,35 @@ namespace std
//// Test code /////
void bad1(char *str) {
static void bad1(char *str) {
// BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
char *buffer = (char *)malloc(strlen(str));
std::string str2(buffer);
free(buffer);
}
void good1(char *str) {
static void good1(char *str) {
// GOOD --- copy does not overrun due to size limit
char *buffer = (char *)malloc(strlen(str));
std::string str2(buffer, strlen(str));
free(buffer);
}
void bad2(wchar_t *str) {
static void bad2(wchar_t *str) {
// BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
wchar_t *buffer = (wchar_t *)calloc(wcslen(str), sizeof(wchar_t));
wcscpy(buffer, str);
free(buffer);
}
void bad3(wchar_t *str) {
static void bad3(wchar_t *str) {
// BAD -- Not allocating space for '\0' terminator
wchar_t *buffer = (wchar_t *)calloc(sizeof(wchar_t), wcslen(str));
wcscpy(buffer, str);
free(buffer);
}
void bad4(char *str) {
static void bad4(char *str) {
// BAD -- Not allocating space for '\0' terminator
char *buffer = (char *)realloc(0, strlen(str));
strcpy(buffer, str);

View File

@@ -1,4 +1,6 @@
edges
| main.cpp:7:27:7:30 | **argv | main.cpp:8:17:8:20 | **argv | provenance | |
| main.cpp:8:17:8:20 | **argv | test.c:10:28:10:31 | **argv | provenance | |
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v | provenance | |
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:13:27:13 | v | provenance | |
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v | provenance | |
@@ -6,18 +8,15 @@ edges
| test2.cpp:38:13:38:16 | call to atoi | test2.cpp:39:3:39:18 | ... = ... | provenance | |
| test2.cpp:38:13:38:16 | call to atoi | test2.cpp:39:9:39:11 | num | provenance | |
| test2.cpp:39:3:39:18 | ... = ... | test2.cpp:40:3:40:5 | num | provenance | |
| test3.c:10:27:10:30 | **argv | test.c:11:24:11:27 | call to atoi | provenance | TaintFunction |
| test3.c:10:27:10:30 | **argv | test.c:41:5:41:24 | ... = ... | provenance | TaintFunction |
| test3.c:10:27:10:30 | **argv | test.c:51:5:51:24 | ... = ... | provenance | TaintFunction |
| test5.cpp:5:5:5:17 | *getTaintedInt | test5.cpp:17:6:17:18 | call to getTaintedInt | provenance | |
| test5.cpp:5:5:5:17 | *getTaintedInt | test5.cpp:18:6:18:18 | call to getTaintedInt | provenance | |
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:10:9:10:27 | call to strtoul | provenance | TaintFunction |
| test5.cpp:10:9:10:27 | call to strtoul | test5.cpp:5:5:5:17 | *getTaintedInt | provenance | |
| test5.cpp:18:2:18:20 | ... = ... | test5.cpp:19:6:19:6 | y | provenance | |
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:18:2:18:20 | ... = ... | provenance | |
| test.c:10:27:10:30 | **argv | test.c:11:24:11:27 | call to atoi | provenance | TaintFunction |
| test.c:10:27:10:30 | **argv | test.c:41:5:41:24 | ... = ... | provenance | TaintFunction |
| test.c:10:27:10:30 | **argv | test.c:51:5:51:24 | ... = ... | provenance | TaintFunction |
| test.c:10:28:10:31 | **argv | test.c:11:24:11:27 | call to atoi | provenance | TaintFunction |
| test.c:10:28:10:31 | **argv | test.c:41:5:41:24 | ... = ... | provenance | TaintFunction |
| test.c:10:28:10:31 | **argv | test.c:51:5:51:24 | ... = ... | provenance | TaintFunction |
| test.c:11:24:11:27 | call to atoi | test.c:14:15:14:28 | maxConnections | provenance | |
| test.c:41:5:41:24 | ... = ... | test.c:44:7:44:10 | len2 | provenance | |
| test.c:41:5:41:24 | ... = ... | test.c:44:7:44:12 | ... -- | provenance | |
@@ -26,6 +25,8 @@ edges
| test.c:51:5:51:24 | ... = ... | test.c:54:7:54:12 | ... -- | provenance | |
| test.c:54:7:54:12 | ... -- | test.c:54:7:54:10 | len3 | provenance | |
nodes
| main.cpp:7:27:7:30 | **argv | semmle.label | **argv |
| main.cpp:8:17:8:20 | **argv | semmle.label | **argv |
| test2.cpp:12:21:12:21 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
@@ -35,7 +36,6 @@ nodes
| test2.cpp:39:3:39:18 | ... = ... | semmle.label | ... = ... |
| test2.cpp:39:9:39:11 | num | semmle.label | num |
| test2.cpp:40:3:40:5 | num | semmle.label | num |
| test3.c:10:27:10:30 | **argv | semmle.label | **argv |
| test5.cpp:5:5:5:17 | *getTaintedInt | semmle.label | *getTaintedInt |
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
| test5.cpp:10:9:10:27 | call to strtoul | semmle.label | call to strtoul |
@@ -43,7 +43,7 @@ nodes
| test5.cpp:18:2:18:20 | ... = ... | semmle.label | ... = ... |
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test.c:10:27:10:30 | **argv | semmle.label | **argv |
| test.c:10:28:10:31 | **argv | semmle.label | **argv |
| test.c:11:24:11:27 | call to atoi | semmle.label | call to atoi |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:41:5:41:24 | ... = ... | semmle.label | ... = ... |
@@ -61,19 +61,7 @@ subpaths
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | **argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | **argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | **argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | **argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | **argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | **argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | **argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | **argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | main.cpp:7:27:7:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test.c:14:15:14:28 | maxConnections | main.cpp:7:27:7:30 | **argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test.c:44:7:44:10 | len2 | main.cpp:7:27:7:30 | **argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test.c:54:7:54:10 | len3 | main.cpp:7:27:7:30 | **argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | main.cpp:7:27:7:30 | **argv | a command-line argument |

View File

@@ -4,20 +4,15 @@
| test2.cpp:17:11:17:22 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
| test2.cpp:39:9:39:18 | ... + ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
| test2.cpp:40:3:40:13 | ... += ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
| test3.c:12:11:12:34 | * ... | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test3.c:12:11:12:34 | * ... | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | **argv | a command-line argument |
| test3.c:13:11:13:20 | * ... | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test3.c:13:11:13:20 | * ... | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | **argv | a command-line argument |
| test4.cpp:13:7:13:20 | access to array | $@ flows an expression which might overflow negatively. | test4.cpp:8:27:8:30 | **argv | a command-line argument |
| test3.c:12:11:12:34 | * ... | $@ flows an expression which might overflow negatively. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test3.c:13:11:13:20 | * ... | $@ flows an expression which might overflow negatively. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test4.cpp:13:7:13:20 | access to array | $@ flows an expression which might overflow negatively. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test5.cpp:10:9:10:27 | call to strtoul | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:17:6:17:27 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:19:6:19:13 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test6.cpp:11:10:11:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
| test6.cpp:16:10:16:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
| test6.cpp:30:11:30:16 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | **argv | a command-line argument |
| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | **argv | a command-line argument |
| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | main.cpp:7:27:7:30 | **argv | a command-line argument |
| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | main.cpp:7:27:7:30 | **argv | a command-line argument |

View File

@@ -0,0 +1,12 @@
extern "C" {
int main1(int argc, char** argv);
int main3(int argc, char** argv);
}
int main4(int argc, char** argv);
int main(int argc, char** argv) {
main1(argc, argv);
main3(argc, argv);
main4(argc, argv);
return 0;
}

View File

@@ -7,7 +7,7 @@ void startServer(int heapSize);
typedef unsigned long size_t;
size_t strlen(const char *s);
int main(int argc, char** argv) {
int main1(int argc, char** argv) {
int maxConnections = atoi(argv[1]);
// BAD: arithmetic on a user input without any validation

View File

@@ -7,7 +7,7 @@
// Regression test for ODASA-6054: IntegerOverflowTainted should
// not report a result if the overflow happens in a macro expansion
// from a macro that is defined in a system header.
int main(int argc, char **argv) {
int main3(int argc, char **argv) {
char *cmd = argv[0];
int x = (int)(unsigned char)*cmd; // BAD: overflow
int y = CAST(*cmd); // BAD: overflow in macro expansion (macro is not from a system header)

View File

@@ -5,7 +5,7 @@
// by comparing the value to 0. This means that the cast cannot overflow,
// regardless of what the input type is.
int main(int argc, char **argv) {
int main4(int argc, char **argv) {
char *p = argv[0];
if (!p[0]) { // GOOD: cast to bool.
return 1;

View File

@@ -50,7 +50,7 @@ int val();
const char *global1 = mysql_get_client_info();
const char *global2 = "abc";
void test1()
void test7()
{
int sock = socket(val(), val(), val());