mirror of
https://github.com/github/codeql.git
synced 2026-05-03 12:45:27 +02:00
Merge branch 'master' into taintedallocfp
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
| file://:0:0:0:0 | abc | test.cpp:53:6:53:11 | chars1 |
|
||||
| file://:0:0:0:0 | {...} | test.cpp:38:22:38:22 | v |
|
||||
| test.cpp:4:9:4:11 | 10 | test.cpp:4:6:4:6 | v |
|
||||
| test.cpp:5:15:5:16 | & ... | test.cpp:5:7:5:11 | ptr_v |
|
||||
| test.cpp:6:15:6:15 | v | test.cpp:6:7:6:11 | ref_v |
|
||||
| test.cpp:8:6:8:7 | 11 | test.cpp:4:6:4:6 | v |
|
||||
| test.cpp:10:10:10:11 | 13 | test.cpp:6:7:6:11 | ref_v |
|
||||
| test.cpp:11:6:11:10 | ... + ... | test.cpp:4:6:4:6 | v |
|
||||
| test.cpp:19:32:19:35 | 0.0 | test.cpp:19:27:19:28 | _y |
|
||||
| test.cpp:19:42:19:43 | _x | test.cpp:24:8:24:8 | x |
|
||||
| test.cpp:19:49:19:50 | _y | test.cpp:24:11:24:11 | y |
|
||||
| test.cpp:19:54:19:60 | 0.0 | test.cpp:24:14:24:14 | z |
|
||||
| test.cpp:35:16:35:25 | {...} | test.cpp:35:11:35:12 | v1 |
|
||||
| test.cpp:35:17:35:17 | 1 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:35:20:35:24 | One | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:36:16:36:39 | {...} | test.cpp:36:11:36:12 | v2 |
|
||||
| test.cpp:36:24:36:24 | 2 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:36:34:36:38 | Two | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:38:27:38:27 | 3 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:38:30:38:36 | Three | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:48:16:48:28 | {...} | test.cpp:48:11:48:12 | v3 |
|
||||
| test.cpp:48:17:48:27 | {...} | test.cpp:45:12:45:14 | ms2 |
|
||||
| test.cpp:48:18:48:18 | 4 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:48:21:48:26 | Four | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:52:19:52:27 | {...} | test.cpp:52:5:52:11 | myArray |
|
||||
| test.cpp:54:17:54:31 | {...} | test.cpp:54:6:54:11 | chars2 |
|
||||
| test.cpp:55:16:55:20 | abc | test.cpp:55:7:55:12 | chars3 |
|
||||
@@ -0,0 +1,4 @@
|
||||
import cpp
|
||||
|
||||
from Variable v
|
||||
select v.getAnAssignedValue(), v
|
||||
@@ -0,0 +1,55 @@
|
||||
|
||||
void test1()
|
||||
{
|
||||
int v = 10; // assignment to `v`
|
||||
int *ptr_v = &v; // assignment to `ptr_v`
|
||||
int &ref_v = v; // assignment to `ref_v`
|
||||
|
||||
v = 11; // assignment to `v`
|
||||
*ptr_v = 12;
|
||||
ref_v = 13; // assignment to `ref_v`
|
||||
v = v + 1; // assignment to `v`
|
||||
v += 1;
|
||||
v++;
|
||||
}
|
||||
|
||||
class myClass1
|
||||
{
|
||||
public:
|
||||
myClass1(float _x, float _y = 0.0f) : x(_x), y(_y), z(0.0f) { // assignments to `_y`, `x`, `y`, `z`
|
||||
// ...
|
||||
}
|
||||
|
||||
private:
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
// ---
|
||||
|
||||
struct myStruct1
|
||||
{
|
||||
int num;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
myStruct1 v1 = {1, "One"}; // assigments to `v1`, `num`, `str`
|
||||
myStruct1 v2 = {.num = 2, .str = "Two"}; // assigments to `v2`, `num`, `str`
|
||||
|
||||
void test2(myStruct1 v = {3, "Three"}) // assignments to `v` (literal `{...}` has no location), `num`, `str`
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
struct myStruct2
|
||||
{
|
||||
myStruct1 ms2;
|
||||
};
|
||||
|
||||
myStruct2 v3 = {{4, "Four"}}; // assigments to `v3`, `ms2`, `num`, `str`
|
||||
|
||||
// ---
|
||||
|
||||
int myArray[10] = {1, 2, 3}; // assigment to `myArray`
|
||||
char chars1[] = "abc"; // assignment to `chars1` (literal "abc" has no location)
|
||||
char chars2[] = {'a', 'b', 'c'}; // assigment to `chars2`
|
||||
char *chars3 = "abc"; // assigment to `chars3`
|
||||
@@ -0,0 +1,40 @@
|
||||
class EraInfo
|
||||
{
|
||||
public:
|
||||
EraInfo() {
|
||||
|
||||
};
|
||||
|
||||
EraInfo(int year, int month, int day) {
|
||||
|
||||
};
|
||||
|
||||
EraInfo(int Era, int foo, int year, int month, int day, const wchar_t * eraName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static EraInfo * EraInfoFromDate(int Era, int foo, int year, int month, int day, wchar_t * eraName)
|
||||
{
|
||||
return new EraInfo(Era, foo, year, month, day, eraName);
|
||||
}
|
||||
};
|
||||
|
||||
int Main()
|
||||
{
|
||||
|
||||
// BAD: constructor creating a EraInfo with exact Heisei era start date
|
||||
EraInfo * pDateTimeUtil = new EraInfo(1989, 1, 8);
|
||||
|
||||
// BAD: constructor creating a EraInfo with exact Heisei era start date
|
||||
EraInfo * pDateTimeUtil1 = new EraInfo(1, 2, 1989, 1, 8, L"\u5e73\u6210");
|
||||
|
||||
// Good: constructor creating a EraInfo with another date
|
||||
EraInfo * pDateTimeUtil2 = new EraInfo(1, 2, 1900, 1, 1, L"foo");
|
||||
|
||||
// BAD: method call passing exact Haisei era start date as parameters
|
||||
EraInfo * pDateTimeUtil3 = EraInfo::EraInfoFromDate(1, 2, 1989, 1, 8, L"\u5e73\u6210");
|
||||
|
||||
// GOOD: method call with the same parameters in a different order (we only track year, month, day)
|
||||
EraInfo * pDateTimeUtil4 = EraInfo::EraInfoFromDate(1, 2, 8, 1, 1989, L"\u5e73\u6210");
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
| ConstructorOrMethodWithExactDate.cpp:27:31:27:53 | call to EraInfo | Call that appears to have hard-coded Japanese era start date as parameter. |
|
||||
| ConstructorOrMethodWithExactDate.cpp:30:32:30:77 | call to EraInfo | Call that appears to have hard-coded Japanese era start date as parameter. |
|
||||
| ConstructorOrMethodWithExactDate.cpp:36:32:36:55 | call to EraInfoFromDate | Call that appears to have hard-coded Japanese era start date as parameter. |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/JapaneseEra/ConstructorOrMethodWithExactEraDate.ql
|
||||
@@ -0,0 +1,57 @@
|
||||
typedef unsigned short WORD;
|
||||
|
||||
struct tm
|
||||
{
|
||||
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
||||
int tm_min; // minutes after the hour - [0, 59]
|
||||
int tm_hour; // hours since midnight - [0, 23]
|
||||
int tm_mday; // day of the month - [1, 31]
|
||||
int tm_mon; // months since January - [0, 11]
|
||||
int tm_year; // years since 1900
|
||||
int tm_wday; // days since Sunday - [0, 6]
|
||||
int tm_yday; // days since January 1 - [0, 365]
|
||||
int tm_isdst; // daylight savings time flag
|
||||
};
|
||||
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
int main()
|
||||
{
|
||||
// BAD: Creation of tm stuct corresponding to the beginning of Heisei era
|
||||
tm *timeTm = new tm();
|
||||
timeTm->tm_year = 1989;
|
||||
timeTm->tm_mon = 1;
|
||||
timeTm->tm_mday = 8;
|
||||
|
||||
|
||||
// GOOD: Creation of tm stuct with different date
|
||||
tm *timeTm1 = new tm();
|
||||
timeTm1->tm_year = 1988;
|
||||
timeTm1->tm_mon = 1;
|
||||
timeTm1->tm_mday = 1;
|
||||
|
||||
// BAD: Creation of SYSTEMTIME stuct corresponding to the beginning of Heisei era
|
||||
SYSTEMTIME st;
|
||||
st.wDay = 8;
|
||||
st.wMonth = 1;
|
||||
st.wYear = 1989;
|
||||
|
||||
|
||||
// GOOD: Creation of SYSTEMTIME stuct with a different date
|
||||
SYSTEMTIME st1;
|
||||
st1.wDay = 1;
|
||||
st1.wMonth = 1;
|
||||
st1.wYear = 1990;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| StructWithExactDate.cpp:31:13:31:19 | tm_year | A time struct that is initialized with exact Japanese calendar era start date. |
|
||||
| StructWithExactDate.cpp:46:8:46:12 | wYear | A time struct that is initialized with exact Japanese calendar era start date. |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/JapaneseEra/StructWithExactEraDate.ql
|
||||
@@ -0,0 +1,11 @@
|
||||
| test.cpp:314:5:314:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:309:13:309:14 | st | st |
|
||||
| test.cpp:327:5:327:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:322:13:322:14 | st | st |
|
||||
| test.cpp:338:6:338:10 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:333:62:333:63 | st | st |
|
||||
| test.cpp:484:5:484:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:480:13:480:14 | st | st |
|
||||
| test.cpp:497:5:497:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:492:13:492:14 | st | st |
|
||||
| test.cpp:509:5:509:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:505:13:505:14 | st | st |
|
||||
| test.cpp:606:11:606:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:602:12:602:19 | timeinfo | timeinfo |
|
||||
| test.cpp:634:11:634:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:628:12:628:19 | timeinfo | timeinfo |
|
||||
| test.cpp:636:11:636:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:628:12:628:19 | timeinfo | timeinfo |
|
||||
| test.cpp:640:5:640:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:629:13:629:14 | st | st |
|
||||
| test.cpp:642:5:642:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:629:13:629:14 | st | st |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.cpp:317:2:317:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:309:13:309:14 | st | st |
|
||||
| test.cpp:330:2:330:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:322:13:322:14 | st | st |
|
||||
| test.cpp:341:2:341:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:333:62:333:63 | st | st |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/Leap Year/UncheckedReturnValueForTimeFunctions.ql
|
||||
@@ -0,0 +1,658 @@
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD, HANDLE;
|
||||
typedef int BOOL, BOOLEAN, errno_t;
|
||||
typedef char CHAR;
|
||||
typedef short SHORT;
|
||||
typedef long LONG;
|
||||
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
|
||||
typedef long __time64_t, time_t;
|
||||
#define NULL 0
|
||||
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *PFILETIME, *LPFILETIME;
|
||||
|
||||
typedef struct _TIME_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
|
||||
|
||||
typedef struct _TIME_DYNAMIC_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
WCHAR TimeZoneKeyName[128];
|
||||
BOOLEAN DynamicDaylightTimeDisabled;
|
||||
} DYNAMIC_TIME_ZONE_INFORMATION, *PDYNAMIC_TIME_ZONE_INFORMATION;
|
||||
|
||||
struct tm
|
||||
{
|
||||
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
||||
int tm_min; // minutes after the hour - [0, 59]
|
||||
int tm_hour; // hours since midnight - [0, 23]
|
||||
int tm_mday; // day of the month - [1, 31]
|
||||
int tm_mon; // months since January - [0, 11]
|
||||
int tm_year; // years since 1900
|
||||
int tm_wday; // days since Sunday - [0, 6]
|
||||
int tm_yday; // days since January 1 - [0, 365]
|
||||
int tm_isdst; // daylight savings time flag
|
||||
};
|
||||
|
||||
BOOL
|
||||
SystemTimeToFileTime(
|
||||
const SYSTEMTIME* lpSystemTime,
|
||||
LPFILETIME lpFileTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
FileTimeToSystemTime(
|
||||
const FILETIME* lpFileTime,
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
void GetSystemTime(
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
void GetSystemTimeAsFileTime(
|
||||
LPFILETIME lpSystemTimeAsFileTime
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime64(
|
||||
struct tm* _Tm
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t mktime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t _time64(
|
||||
__time64_t* _Time
|
||||
);
|
||||
|
||||
__time64_t time(
|
||||
time_t* const _Time
|
||||
)
|
||||
{
|
||||
return _time64(_Time);
|
||||
}
|
||||
|
||||
int gmtime_s(
|
||||
struct tm* _Tm,
|
||||
__time64_t const* _Time
|
||||
);
|
||||
|
||||
BOOL
|
||||
GetFileTime(
|
||||
HANDLE hFile,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpLastAccessTime,
|
||||
LPFILETIME lpLastWriteTime
|
||||
);
|
||||
|
||||
void Correct_FileTimeToSystemTime(const FILETIME* lpFileTime)
|
||||
{
|
||||
SYSTEMTIME systemTime;
|
||||
|
||||
if (!FileTimeToSystemTime(lpFileTime, &systemTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_FileTimeToSystemTime(const FILETIME* lpFileTime)
|
||||
{
|
||||
SYSTEMTIME systemTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
FileTimeToSystemTime(lpFileTime, &systemTime);
|
||||
}
|
||||
|
||||
void Correct_SystemTimeToTzSpecificLocalTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
if (!SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation, lpUniversalTime, &localTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_SystemTimeToTzSpecificLocalTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation, lpUniversalTime, &localTime);
|
||||
}
|
||||
|
||||
void Correct_SystemTimeToTzSpecificLocalTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
if (!SystemTimeToTzSpecificLocalTimeEx(lpTimeZoneInformation, lpUniversalTime, &localTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_SystemTimeToTzSpecificLocalTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
SystemTimeToTzSpecificLocalTimeEx(lpTimeZoneInformation, lpUniversalTime, &localTime);
|
||||
}
|
||||
|
||||
void Correct_TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
if (!TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation, lpLocalTime, &universalTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation, lpLocalTime, &universalTime);
|
||||
}
|
||||
|
||||
void Correct_TzSpecificLocalTimeToSystemTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
if (!TzSpecificLocalTimeToSystemTimeEx(lpTimeZoneInformation, lpLocalTime, &universalTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_TzSpecificLocalTimeToSystemTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
TzSpecificLocalTimeToSystemTimeEx(lpTimeZoneInformation, lpLocalTime, &universalTime);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
SYSTEMTIME Cases
|
||||
*************************************************/
|
||||
|
||||
void Correct_filetime_conversion_check(SYSTEMTIME& st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
if (!SystemTimeToFileTime(&st, &ft))
|
||||
{
|
||||
/// Something failed, handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// SystemTimeToFileTime succeeded
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion(SYSTEMTIME& st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
// (out-of-scope) GeneralBug: Unchecked call to SystemTimeToFileTime. this may have failed, but we didn't check the return value!
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2(SYSTEMTIME* st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
if (st != NULL)
|
||||
{
|
||||
// (out-of-scope) GeneralBug: Unchecked call to SystemTimeToFileTime. this may have failed, but we didn't check the return value!
|
||||
SystemTimeToFileTime(st, &ft);
|
||||
}
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wDay++;
|
||||
|
||||
// (out-of-scope) GeneralBug: Not checking is OK, no struct manipulation
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2a()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear += 2;
|
||||
|
||||
// BUG - UncheckedReturnValueForTimeFunctions
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2b()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear++;
|
||||
|
||||
// BUG - UncheckedReturnValueForTimeFunctions
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2b(SYSTEMTIME* st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st->wYear++;
|
||||
|
||||
// BUG - UncheckedReturnValueForTimeFunctions
|
||||
SystemTimeToFileTime(st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion3()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
if (st.wMonth < 12)
|
||||
{
|
||||
st.wMonth++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for leap year, but...
|
||||
st.wMonth = 1;
|
||||
st.wYear++;
|
||||
}
|
||||
|
||||
// (out-of-scope) GeneralBug: Not checking if newly generated date is valid for conversion
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
void CorrectPattern_check1()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wYear++;
|
||||
|
||||
// Guard
|
||||
if (st.wMonth == 2 && st.wDay == 29)
|
||||
{
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
|
||||
if (!isLeapYear)
|
||||
{
|
||||
st.wDay = 28;
|
||||
}
|
||||
}
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
void CorrectPattern_check2(int yearsToAdd)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wYear += yearsToAdd;
|
||||
|
||||
// Guard
|
||||
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
|
||||
st.wDay = st.wMonth == 2 && st.wDay == 29 && !isLeapYear ? 28 : st.wDay;
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
bool isLeapYear(SYSTEMTIME& st)
|
||||
{
|
||||
return st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
|
||||
}
|
||||
|
||||
void CorrectPattern_check3()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wYear++;
|
||||
|
||||
// Guard
|
||||
if (st.wMonth == 2 && st.wDay == 29 && isLeapYear(st))
|
||||
{
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
st.wDay = 28;
|
||||
}
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
bool isLeapYear2(int year)
|
||||
{
|
||||
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
}
|
||||
|
||||
bool fixDate(int day, int month, int year)
|
||||
{
|
||||
return (month == 2 && day == 29 && isLeapYear2(year));
|
||||
}
|
||||
|
||||
void CorrectPattern_check4()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
///// FP
|
||||
st.wYear++;
|
||||
|
||||
// Guard
|
||||
if (fixDate(st.wDay, st.wMonth, st.wYear))
|
||||
{
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
st.wDay = 28;
|
||||
}
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CorrectPattern_NotManipulated_DateFromAPI_0()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
FILETIME ft;
|
||||
|
||||
// Not checking is OK, no struct manipulation
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void CorrectPattern_NotManipulated_DateFromAPI_1(HANDLE hWatchdog)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
|
||||
GetFileTime(hWatchdog, NULL, NULL, &ft);
|
||||
FileTimeToSystemTime(&ft, &st);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
void AntiPattern_1_year_addition()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear++;
|
||||
|
||||
// Usage of potentially invalid date
|
||||
Correct_filetime_conversion_check(st);
|
||||
}
|
||||
|
||||
void AntiPattern_simple_addition(int yearAddition)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear += yearAddition;
|
||||
|
||||
// Usage of potentially invalid date
|
||||
Correct_filetime_conversion_check(st);
|
||||
}
|
||||
|
||||
void AntiPattern_IncorrectGuard(int yearsToAdd)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear += yearsToAdd;
|
||||
|
||||
// Incorrect Guard
|
||||
if (st.wMonth == 2 && st.wDay == 29)
|
||||
{
|
||||
// Part of a different anti-pattern.
|
||||
// Make sure the guard includes the proper check
|
||||
bool isLeapYear = st.wYear % 4 == 0;
|
||||
if (!isLeapYear)
|
||||
{
|
||||
st.wDay = 28;
|
||||
}
|
||||
}
|
||||
|
||||
// Potentially Unsafe to use
|
||||
Correct_filetime_conversion_check(st);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
struct tm Cases
|
||||
*************************************************/
|
||||
|
||||
void CorrectUsageOf_mkgmtime(struct tm& timeinfo)
|
||||
{
|
||||
if (_mkgmtime(&timeinfo) == -1)
|
||||
{
|
||||
/// Something failed, handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// _mkgmtime succeeded
|
||||
}
|
||||
|
||||
void AntiPattern_uncheckedUsageOf_mkgmtime(struct tm& timeinfo)
|
||||
{
|
||||
// (out-of-scope) GeneralBug: Must check return value for _mkgmtime
|
||||
// QLNOTE: Include other related _mkgmtime* functions in the function name pattern
|
||||
_mkgmtime(&timeinfo);
|
||||
// _mktime64(&timeinfo);
|
||||
// _mktime32(&timeinfo);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
void Correct_year_addition_struct_tm()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm timeinfo;
|
||||
time(&rawtime);
|
||||
// NOTE: Should ideally check return value for this function (not in scope)
|
||||
errno_t err = gmtime_s(&timeinfo, &rawtime);
|
||||
if (err)
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
// this is the potentially dangerous part, when not followed up with leap year checks
|
||||
timeinfo.tm_year++;
|
||||
|
||||
// Guard
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
bool isLeapYear = timeinfo.tm_year % 4 == 0 && (timeinfo.tm_year % 100 != 0 || (timeinfo.tm_year + 1900) % 400 == 0);
|
||||
timeinfo.tm_mday = timeinfo.tm_mon == 1 && timeinfo.tm_mday == 29 && !isLeapYear ? 28 : timeinfo.tm_mday;
|
||||
|
||||
// safe to use
|
||||
AntiPattern_uncheckedUsageOf_mkgmtime(timeinfo);
|
||||
}
|
||||
|
||||
void Correct_LinuxPattern()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm timeinfo;
|
||||
time(&rawtime);
|
||||
// NOTE: Should ideally check return value for this function (not in scope)
|
||||
errno_t err = gmtime_s(&timeinfo, &rawtime);
|
||||
|
||||
/* from 1900 -> from 1980 */
|
||||
timeinfo.tm_year -= 80;
|
||||
/* 0~11 -> 1~12 */
|
||||
timeinfo.tm_mon++;
|
||||
/* 0~59 -> 0~29(2sec counts) */
|
||||
timeinfo.tm_sec >>= 1;
|
||||
|
||||
// safe to use
|
||||
AntiPattern_uncheckedUsageOf_mkgmtime(timeinfo);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
void AntiPattern_year_addition_struct_tm()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm timeinfo;
|
||||
time(&rawtime);
|
||||
gmtime_s(&timeinfo, &rawtime);
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
timeinfo.tm_year++;
|
||||
|
||||
// Usage of potentially invalid date
|
||||
CorrectUsageOf_mkgmtime(timeinfo);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
void FalsePositiveTests(int x)
|
||||
{
|
||||
struct tm timeinfo;
|
||||
SYSTEMTIME st;
|
||||
|
||||
timeinfo.tm_year = x;
|
||||
timeinfo.tm_year = 1970;
|
||||
|
||||
st.wYear = x;
|
||||
st.wYear = 1900 + x;
|
||||
}
|
||||
|
||||
void FalseNegativeTests(int x)
|
||||
{
|
||||
struct tm timeinfo;
|
||||
SYSTEMTIME st;
|
||||
|
||||
timeinfo.tm_year = x;
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
timeinfo.tm_year = x + timeinfo.tm_year;
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
timeinfo.tm_year = 1970 + timeinfo.tm_year;
|
||||
|
||||
st.wYear = x;
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear = x + st.wYear;
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear = (1986 + st.wYear) - 1;
|
||||
}
|
||||
|
||||
// False positive
|
||||
inline void
|
||||
IncrementMonth(LPSYSTEMTIME pst)
|
||||
{
|
||||
if (pst->wMonth < 12)
|
||||
{
|
||||
pst->wMonth++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pst->wMonth = 1;
|
||||
pst->wYear++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
| test.cpp:173:29:173:38 | qwLongTime | This arithmetic operation $@ uses a constant value of 365 ends up modifying the date/time located at $@, without considering leap year scenarios. | test.cpp:170:2:170:47 | ... += ... | ... += ... | test.cpp:173:29:173:38 | qwLongTime | qwLongTime |
|
||||
| test.cpp:174:30:174:39 | qwLongTime | This arithmetic operation $@ uses a constant value of 365 ends up modifying the date/time located at $@, without considering leap year scenarios. | test.cpp:170:2:170:47 | ... += ... | ... += ... | test.cpp:174:30:174:39 | qwLongTime | qwLongTime |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/Leap Year/Adding365daysPerYear.ql
|
||||
@@ -0,0 +1,178 @@
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD, HANDLE;
|
||||
typedef int BOOL, BOOLEAN, errno_t;
|
||||
typedef char CHAR;
|
||||
typedef short SHORT;
|
||||
typedef long LONG;
|
||||
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
|
||||
typedef long __time64_t, time_t;
|
||||
#define NULL 0
|
||||
|
||||
typedef long long LONGLONG;
|
||||
typedef unsigned long long ULONGLONG;
|
||||
|
||||
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *PFILETIME, *LPFILETIME;
|
||||
|
||||
typedef struct _TIME_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
|
||||
|
||||
typedef struct _TIME_DYNAMIC_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
WCHAR TimeZoneKeyName[128];
|
||||
BOOLEAN DynamicDaylightTimeDisabled;
|
||||
} DYNAMIC_TIME_ZONE_INFORMATION, *PDYNAMIC_TIME_ZONE_INFORMATION;
|
||||
|
||||
struct tm
|
||||
{
|
||||
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
||||
int tm_min; // minutes after the hour - [0, 59]
|
||||
int tm_hour; // hours since midnight - [0, 23]
|
||||
int tm_mday; // day of the month - [1, 31]
|
||||
int tm_mon; // months since January - [0, 11]
|
||||
int tm_year; // years since 1900
|
||||
int tm_wday; // days since Sunday - [0, 6]
|
||||
int tm_yday; // days since January 1 - [0, 365]
|
||||
int tm_isdst; // daylight savings time flag
|
||||
};
|
||||
|
||||
BOOL
|
||||
SystemTimeToFileTime(
|
||||
const SYSTEMTIME* lpSystemTime,
|
||||
LPFILETIME lpFileTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
FileTimeToSystemTime(
|
||||
const FILETIME* lpFileTime,
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
void GetSystemTime(
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
void GetSystemTimeAsFileTime(
|
||||
LPFILETIME lpSystemTimeAsFileTime
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime64(
|
||||
struct tm* _Tm
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t mktime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t _time64(
|
||||
__time64_t* _Time
|
||||
);
|
||||
|
||||
__time64_t time(
|
||||
time_t* const _Time
|
||||
)
|
||||
{
|
||||
return _time64(_Time);
|
||||
}
|
||||
|
||||
int gmtime_s(
|
||||
struct tm* _Tm,
|
||||
__time64_t const* _Time
|
||||
);
|
||||
|
||||
BOOL
|
||||
GetFileTime(
|
||||
HANDLE hFile,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpLastAccessTime,
|
||||
LPFILETIME lpLastWriteTime
|
||||
);
|
||||
|
||||
|
||||
void antipattern2()
|
||||
{
|
||||
// get the current time as a FILETIME
|
||||
SYSTEMTIME st; FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
|
||||
// convert to a quadword (64-bit integer) to do arithmetic
|
||||
ULONGLONG qwLongTime;
|
||||
qwLongTime = (((ULONGLONG)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
|
||||
|
||||
// add a year by calculating the ticks in 365 days
|
||||
// (which may be incorrect when crossing a leap day)
|
||||
qwLongTime += 365 * 24 * 60 * 60 * 10000000LLU;
|
||||
|
||||
// copy back to a FILETIME
|
||||
ft.dwLowDateTime = (DWORD)(qwLongTime & 0xFFFFFFFF);
|
||||
ft.dwHighDateTime = (DWORD)(qwLongTime >> 32);
|
||||
|
||||
// convert back to SYSTEMTIME for display or other usage
|
||||
FileTimeToSystemTime(&ft, &st);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.cpp:17:6:17:10 | items | There is an array or std::vector allocation with a hard-coded set of 365 elements, which may indicate the number of days in a year without considering leap year scenarios. |
|
||||
| test.cpp:25:15:25:26 | new[] | There is an array or std::vector allocation with a hard-coded set of 365 elements, which may indicate the number of days in a year without considering leap year scenarios. |
|
||||
| test.cpp:52:20:52:23 | call to vector | There is an array or std::vector allocation with a hard-coded set of 365 elements, which may indicate the number of days in a year without considering leap year scenarios. |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/Leap Year/UnsafeArrayForDaysOfYear.ql
|
||||
@@ -0,0 +1,70 @@
|
||||
template <class T>
|
||||
class vector {
|
||||
private:
|
||||
T _x;
|
||||
public:
|
||||
vector(int size)
|
||||
{
|
||||
}
|
||||
|
||||
T& operator[](int idx) { return _x; }
|
||||
const T& operator[](int idx) const { return _x; }
|
||||
};
|
||||
|
||||
void ArrayOfDays_Bug(int dayOfYear, int x)
|
||||
{
|
||||
// BUG
|
||||
int items[365];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void ArrayOfDays_Bug2(int dayOfYear, int x)
|
||||
{
|
||||
// BUG
|
||||
int *items = new int[365];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
delete items;
|
||||
}
|
||||
|
||||
|
||||
void ArrayOfDays_Correct(unsigned long year, int dayOfYear, int x)
|
||||
{
|
||||
bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
int *items = new int[isLeapYear ? 366 : 365];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
|
||||
delete[] items;
|
||||
}
|
||||
|
||||
void ArrayOfDays_FalsePositive(int dayOfYear, int x)
|
||||
{
|
||||
int items[366];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void VectorOfDays_Bug(int dayOfYear, int x)
|
||||
{
|
||||
// BUG
|
||||
vector<int> items(365);
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void VectorOfDays_Correct(unsigned long year, int dayOfYear, int x)
|
||||
{
|
||||
bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
vector<int> items(isLeapYear ? 366 : 365);
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void VectorOfDays_FalsePositive(int dayOfYear, int x)
|
||||
{
|
||||
vector<int> items(366);
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
| test.cpp:35:2:37:2 | for(...;...;...) ... | test.cpp:35:18:35:23 | ... < ... | 1 | i | { ... } | i | ExprStmt |
|
||||
| test.cpp:43:2:45:2 | for(...;...;...) ... | test.cpp:43:18:43:26 | ... < ... | | i | { ... } | i | ExprStmt |
|
||||
| test.cpp:74:2:77:2 | while (...) ... | test.cpp:74:9:74:17 | ... > ... | 1 | count | { ... } | count | ExprStmt |
|
||||
| test.cpp:84:2:88:2 | while (...) ... | test.cpp:84:9:84:17 | ... > ... | | count | { ... } | count | if (...) ... |
|
||||
| test.cpp:171:3:173:3 | while (...) ... | test.cpp:171:10:171:43 | ... != ... | 0 | | { ... } | 0 | return ... |
|
||||
| test.cpp:251:2:255:2 | while (...) ... | test.cpp:251:9:251:12 | loop | 1 | loop | { ... } | loop | return ... |
|
||||
| test.cpp:263:2:267:2 | while (...) ... | test.cpp:263:9:263:20 | ... && ... | 1 | 1 | { ... } | ... && ... | return ... |
|
||||
| test.cpp:275:2:279:2 | while (...) ... | test.cpp:275:9:275:13 | ! ... | 1 | stop | { ... } | stop | return ... |
|
||||
| test.cpp:287:2:291:2 | while (...) ... | test.cpp:287:9:287:20 | ... && ... | 1 | loop | { ... } | loop | return ... |
|
||||
| test.cpp:299:2:303:2 | while (...) ... | test.cpp:299:9:299:20 | ... && ... | 1 | loop | { ... } | ... && ..., loop | return ... |
|
||||
| test.cpp:311:2:315:2 | while (...) ... | test.cpp:311:9:311:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | return ... |
|
||||
| test.cpp:323:2:328:2 | while (...) ... | test.cpp:323:9:323:17 | ... ? ... : ... | | b, c | { ... } | c | return ... |
|
||||
| test.cpp:336:2:341:2 | while (...) ... | test.cpp:336:9:336:21 | ... \|\| ... | 1 | b, c | { ... } | c | return ... |
|
||||
| test.cpp:348:2:351:17 | do (...) ... | test.cpp:351:11:351:15 | 0 | | { ... } | { ... } | { ... } | return ... |
|
||||
| test.cpp:361:2:364:2 | while (...) ... | test.cpp:361:9:361:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | while (...) ... |
|
||||
| test.cpp:365:2:368:2 | while (...) ... | test.cpp:365:9:365:13 | ! ... | 1 | stop | { ... } | stop | while (...) ... |
|
||||
| test.cpp:369:2:373:2 | while (...) ... | test.cpp:369:9:369:21 | ... \|\| ... | 1 | b, c | { ... } | c | do (...) ... |
|
||||
| test.cpp:374:2:376:17 | do (...) ... | test.cpp:376:11:376:15 | 0 | | do (...) ... | { ... } | { ... } | return ... |
|
||||
| test.cpp:384:2:386:2 | while (...) ... | test.cpp:384:9:384:12 | 1 | 1 | 1 | { ... } | | return ... |
|
||||
| test.cpp:394:2:396:2 | while (...) ... | test.cpp:394:9:394:21 | ... , ... | | { ... } | { ... } | | |
|
||||
| test.cpp:404:3:408:3 | while (...) ... | test.cpp:404:10:404:13 | loop | 1 | loop | { ... } | | |
|
||||
| test.cpp:416:2:418:2 | for(...;...;...) ... | test.cpp:416:18:416:23 | ... < ... | 1 | i | { ... } | i | return ... |
|
||||
| test.cpp:424:2:425:2 | for(...;...;...) ... | test.cpp:424:18:424:23 | ... < ... | 1 | i | { ... } | i | return ... |
|
||||
| test.cpp:433:2:434:2 | for(...;...;...) ... | test.cpp:433:18:433:22 | 0 | 0 | | { ... } | 0 | return ... |
|
||||
@@ -0,0 +1,13 @@
|
||||
import cpp
|
||||
import LoopConditionsConst
|
||||
|
||||
from Loop l, Expr condition
|
||||
where
|
||||
l.getCondition() = condition
|
||||
select
|
||||
l, condition,
|
||||
concat(int val | loopEntryConst(condition, val) | val.toString(), ", "),
|
||||
concat(BasicBlock bb | bb.getASuccessor() = l.getStmt() | bb.toString(), ", "),
|
||||
concat(l.getStmt().toString(), ", "),
|
||||
concat(BasicBlock bb | bb.getASuccessor() = l.getFollowingStmt() | bb.toString(), ", "),
|
||||
concat(l.getFollowingStmt().toString(), ", ")
|
||||
@@ -0,0 +1,10 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.controlflow.internal.ConstantExprs
|
||||
|
||||
predicate loopEntryConst(Expr condition, int val)
|
||||
{
|
||||
exists(LoopEntryConditionEvaluator x, ControlFlowNode loop |
|
||||
x.isLoopEntry(condition, loop) and
|
||||
val = x.getValue(condition)
|
||||
)
|
||||
}
|
||||
@@ -8,3 +8,9 @@
|
||||
| test.cpp:132:9:132:9 | j | The variable $@ may not be initialized here. | test.cpp:126:6:126:6 | j | j |
|
||||
| test.cpp:219:3:219:3 | x | The variable $@ may not be initialized here. | test.cpp:218:7:218:7 | x | x |
|
||||
| test.cpp:243:13:243:13 | i | The variable $@ may not be initialized here. | test.cpp:241:6:241:6 | i | i |
|
||||
| test.cpp:329:9:329:11 | val | The variable $@ may not be initialized here. | test.cpp:321:6:321:8 | val | val |
|
||||
| test.cpp:336:10:336:10 | a | The variable $@ may not be initialized here. | test.cpp:333:7:333:7 | a | a |
|
||||
| test.cpp:369:10:369:10 | a | The variable $@ may not be initialized here. | test.cpp:358:7:358:7 | a | a |
|
||||
| test.cpp:378:9:378:11 | val | The variable $@ may not be initialized here. | test.cpp:359:6:359:8 | val | val |
|
||||
| test.cpp:417:10:417:10 | j | The variable $@ may not be initialized here. | test.cpp:414:9:414:9 | j | j |
|
||||
| test.cpp:436:9:436:9 | j | The variable $@ may not be initialized here. | test.cpp:431:9:431:9 | j | j |
|
||||
|
||||
@@ -242,4 +242,196 @@ void test21()
|
||||
|
||||
v3 = v1 >> i; // BAD: i is not initialized
|
||||
v3 = v2 >> 1; // BAD: v2 is not initialized [NOT DETECTED]
|
||||
}
|
||||
}
|
||||
|
||||
int test22() {
|
||||
bool loop = true;
|
||||
int val;
|
||||
|
||||
while (loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test23() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (loop && true)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test24() {
|
||||
bool stop = false;
|
||||
int val;
|
||||
|
||||
while (!stop)
|
||||
{
|
||||
val = 1;
|
||||
stop = true;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test25() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (true && loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test26() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (loop && loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test27() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (loop || false)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test28() {
|
||||
bool a = true, b = true, c = true;
|
||||
int val;
|
||||
|
||||
while (a ? b : c)
|
||||
{
|
||||
val = 1;
|
||||
a = false;
|
||||
c = false;
|
||||
}
|
||||
return val; // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
int test29() {
|
||||
bool a, b = true, c = true;
|
||||
int val;
|
||||
|
||||
while ((a && b) || c) // BAD (a is uninitialized)
|
||||
{
|
||||
val = 1;
|
||||
b = false;
|
||||
c = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test30() {
|
||||
int val;
|
||||
|
||||
do
|
||||
{
|
||||
val = 1;
|
||||
} while (false);
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test31() {
|
||||
bool loop = true;
|
||||
bool stop = false;
|
||||
bool a, b = true, c = true;
|
||||
int val;
|
||||
|
||||
while (loop || false)
|
||||
{
|
||||
loop = false;
|
||||
}
|
||||
while (!stop)
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
while ((a && b) || c) // BAD (a is uninitialized)
|
||||
{
|
||||
b = false;
|
||||
c = false;
|
||||
}
|
||||
do
|
||||
{
|
||||
} while (false);
|
||||
|
||||
return val; // BAD
|
||||
}
|
||||
|
||||
int test32() {
|
||||
int val;
|
||||
|
||||
while (true)
|
||||
{
|
||||
}
|
||||
|
||||
return val; // GOOD (never reached)
|
||||
}
|
||||
|
||||
int test33() {
|
||||
int val;
|
||||
|
||||
while (val = 1, true) {
|
||||
return val; // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
int test34() {
|
||||
bool loop = true;
|
||||
int val;
|
||||
|
||||
{
|
||||
while (loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test35() {
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; i < 10; i++, j = 1) {
|
||||
return j; // BAD
|
||||
}
|
||||
}
|
||||
|
||||
int test36() {
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; i < 10; i++, j = 1) {
|
||||
}
|
||||
|
||||
return j; // GOOD
|
||||
}
|
||||
|
||||
int test38() {
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; false; i++, j = 1) {
|
||||
}
|
||||
|
||||
return j; // BAD
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user