diff --git a/rules/c/security/null-library-function-c.yml b/rules/c/security/null-library-function-c.yml new file mode 100644 index 00000000..5ed6c572 --- /dev/null +++ b/rules/c/security/null-library-function-c.yml @@ -0,0 +1,262 @@ +id: null-library-function-c +language: C +severity: warning +message: >- + The `$SOURCE` function returns NULL on error and this line dereferences + the return value without checking for NULL. +note: >- + [CWE-476] NULL Pointer Dereference. + [REFERENCES] + - https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers +ast-grep-essentials: true + +rule: + all: + - not: + has: + stopBy: end + kind: ERROR + - any: + - kind: subscript_expression + # any: + # - pattern: $SOURCE($$$)[$$$] + # - pattern: ($SOURCE($$$))[$$$] + all: + - has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + - has: + stopBy: end + any: + - kind: number_literal + - kind: identifier + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^atof|::atof|std::atof|atoi|::atoi|std::atoi|atol_l|::atol_l|std::atol_l|atol|::atol|std::atol|atoll_l|::atoll_l|std::atoll_l|atoll|::atoll|std::atoll|getc|::getc|std::getc|fprintf|::fprintf|std::fprintf|fgetpos|::fgetpos|std::fgetpos|fseek|::fseek|std::fseek|fseeko|::fseeko|std::fseeko|fsetpos|::fsetpos|std::fsetpos|ftell|::ftell|std::ftell|ftello|::ftello|std::ftello|rewind|::rewind|std::rewind|strlen|::strlen|std::strlen|strtoimax|::strtoimax|std::strtoimax|strtod|::strtod|std::strtod|strtol|::strtol|std::strtol|strtoul|::strtoul|std::strtoul|strtoll|::strtoll|std::strtoll|strtoq|::strtoq|std::strtoq$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: call_expression + nthChild: 1 + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^atof|::atof|std::atof|atoi|::atoi|std::atoi|atol_l|::atol_l|std::atol_l|atol|::atol|std::atol|atoll_l|::atoll_l|std::atoll_l|atoll|::atoll|std::atoll|getc|::getc|std::getc|fprintf|::fprintf|std::fprintf|fgetpos|::fgetpos|std::fgetpos|fseek|::fseek|std::fseek|fseeko|::fseeko|std::fseeko|fsetpos|::fsetpos|std::fsetpos|ftell|::ftell|std::ftell|ftello|::ftello|std::ftello|rewind|::rewind|std::rewind|strlen|::strlen|std::strlen|strtoimax|::strtoimax|std::strtoimax|strtod|::strtod|std::strtod|strtol|::strtol|std::strtol|strtoul|::strtoul|std::strtoul|strtoll|::strtoll|std::strtoll|strtoq|::strtoq|std::strtoq$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: assignment_expression + nthChild: 1 + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $VAR + - has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: call_expression + nthChild: 2 + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + - not: + inside: + stopBy: end + kind: call_expression + has: + stopBy: neighbor + kind: identifier + pattern: $SINK + - not: + has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: call_expression + has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^bcopy|::bcopy|std::bcopy|memccpy|::memccpy|std::memccpy|memcpy|::memcpy|std::memcpy|memmove|::memmove|std::memmove|stpncpy|::stpncpy|std::stpncpy|strcat|::strcat|std::strcat|strcpy|::strcpy|std::strcpy|strcpy|::strcpy|std::strcpy|strlcat|::strlcat|std::strlcat|strlcpy|::strlcpy|std::strlcpy|strncat|::strncat|std::strncat|strpcpy|::strpcpy|std::strpcpy|wcpcpy|::wcpcpy|std::wcpcpy|wcpncpy|::wcpncpy|std::wcpncpy$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: assignment_expression + pattern: $VAR = $SOURCE($$$) + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $VAR + - has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + + - kind: call_expression + # any: + # - pattern: $SINK($$$, $SOURCE($$$)) + # - pattern: $SINK($SOURCE($$$)) + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^fwrite|::fwrite|std::fwrite$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + + - kind: call_expression + any: + - pattern: $SINK($$$, $VAR = $SOURCE($$$)) + - pattern: $SINK($VAR = $SOURCE($$$)) + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^fwrite|::fwrite|std::fwrite$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: assignment_expression + pattern: $VAR = $SOURCE($$$) + all: + - has: + stopBy: neighbor + kind: identifier + - has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + + - kind: pointer_expression + has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + - not: + inside: + stopBy: end + any: + - kind: subscript_expression + # - kind: call_expression + - not: + has: + stopBy: end + any: + - kind: assignment_expression + - inside: + stopBy: end + kind: return_statement + \ No newline at end of file diff --git a/rules/cpp/null-library-function-cpp.yml b/rules/cpp/null-library-function-cpp.yml new file mode 100644 index 00000000..8f6ba936 --- /dev/null +++ b/rules/cpp/null-library-function-cpp.yml @@ -0,0 +1,262 @@ +id: null-library-function-cpp +language: cpp +severity: warning +message: >- + The `$SOURCE` function returns NULL on error and this line dereferences + the return value without checking for NULL. +note: >- + [CWE-476] NULL Pointer Dereference. + [REFERENCES] + - https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers +ast-grep-essentials: true + +rule: + all: + - not: + has: + stopBy: end + kind: ERROR + - any: + - kind: subscript_expression + # any: + # - pattern: $SOURCE($$$)[$$$] + # - pattern: ($SOURCE($$$))[$$$] + all: + - has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + - has: + stopBy: end + any: + - kind: number_literal + - kind: identifier + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^atof|::atof|std::atof|atoi|::atoi|std::atoi|atol_l|::atol_l|std::atol_l|atol|::atol|std::atol|atoll_l|::atoll_l|std::atoll_l|atoll|::atoll|std::atoll|getc|::getc|std::getc|fprintf|::fprintf|std::fprintf|fgetpos|::fgetpos|std::fgetpos|fseek|::fseek|std::fseek|fseeko|::fseeko|std::fseeko|fsetpos|::fsetpos|std::fsetpos|ftell|::ftell|std::ftell|ftello|::ftello|std::ftello|rewind|::rewind|std::rewind|strlen|::strlen|std::strlen|strtoimax|::strtoimax|std::strtoimax|strtod|::strtod|std::strtod|strtol|::strtol|std::strtol|strtoul|::strtoul|std::strtoul|strtoll|::strtoll|std::strtoll|strtoq|::strtoq|std::strtoq$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: call_expression + nthChild: 1 + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^atof|::atof|std::atof|atoi|::atoi|std::atoi|atol_l|::atol_l|std::atol_l|atol|::atol|std::atol|atoll_l|::atoll_l|std::atoll_l|atoll|::atoll|std::atoll|getc|::getc|std::getc|fprintf|::fprintf|std::fprintf|fgetpos|::fgetpos|std::fgetpos|fseek|::fseek|std::fseek|fseeko|::fseeko|std::fseeko|fsetpos|::fsetpos|std::fsetpos|ftell|::ftell|std::ftell|ftello|::ftello|std::ftello|rewind|::rewind|std::rewind|strlen|::strlen|std::strlen|strtoimax|::strtoimax|std::strtoimax|strtod|::strtod|std::strtod|strtol|::strtol|std::strtol|strtoul|::strtoul|std::strtoul|strtoll|::strtoll|std::strtoll|strtoq|::strtoq|std::strtoq$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: assignment_expression + nthChild: 1 + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $VAR + - has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: call_expression + nthChild: 2 + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + - not: + inside: + stopBy: end + kind: call_expression + has: + stopBy: neighbor + kind: identifier + pattern: $SINK + - not: + has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: call_expression + has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + + - kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^bcopy|::bcopy|std::bcopy|memccpy|::memccpy|std::memccpy|memcpy|::memcpy|std::memcpy|memmove|::memmove|std::memmove|stpncpy|::stpncpy|std::stpncpy|strcat|::strcat|std::strcat|strcpy|::strcpy|std::strcpy|strcpy|::strcpy|std::strcpy|strlcat|::strlcat|std::strlcat|strlcpy|::strlcpy|std::strlcpy|strncat|::strncat|std::strncat|strpcpy|::strpcpy|std::strpcpy|wcpcpy|::wcpcpy|std::wcpcpy|wcpncpy|::wcpncpy|std::wcpncpy$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: neighbor + kind: assignment_expression + pattern: $VAR = $SOURCE($$$) + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $VAR + - has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + + - kind: call_expression + # any: + # - pattern: $SINK($$$, $SOURCE($$$)) + # - pattern: $SINK($SOURCE($$$)) + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^fwrite|::fwrite|std::fwrite$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: call_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + + - kind: call_expression + any: + - pattern: $SINK($$$, $VAR = $SOURCE($$$)) + - pattern: $SINK($VAR = $SOURCE($$$)) + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SINK + regex: ^fwrite|::fwrite|std::fwrite$ + - has: + stopBy: neighbor + kind: argument_list + has: + stopBy: end + kind: assignment_expression + pattern: $VAR = $SOURCE($$$) + all: + - has: + stopBy: neighbor + kind: identifier + - has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: neighbor + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + + - kind: pointer_expression + has: + stopBy: neighbor + kind: call_expression + all: + - has: + stopBy: end + kind: identifier + pattern: $SOURCE + regex: ^fgets|::fgets|std::fgets|fopen|::fopen|std::fopen|getenv|::getenv|std::getenv|getgrent|::getgrent|std::getgrent|getgrgid|::getgrgid|std::getgrgid|getgrnam|::getgrnam|std::getgrnam|getlogin|::getlogin|std::getlogin|getpwent|::getpwent|std::getpwent|getpwnam|::getpwnam|std::getpwnam|getpwuid|::getpwuid|std::getpwuid|getpwuuid|::getpwuuid|std::getpwuuid|gets|::gets|std::gets|inet_ntop|::inet_ntop|std::inet_ntop|realpath|::realpath|std::realpath|tempnam|::tempnam|std::tempnam|tmpfile|::tmpfile|std::tmpfile|tmpnam|::tmpnam|std::tmpnam|memchr|::memchr|std::memchr|strcasestr_l|::strcasestr_l|std::strcasestr_l|strcasestr|::strcasestr|std::strcasestr|strchr|::strchr|std::strchr|strnstr|::strnstr|std::strnstr|strpbrk|::strpbrk|std::strpbrk|strrchr|::strrchr|std::strrchr|strstr|::strstr|std::strstr|strtok_r|::strtok_r|std::strtok_r|strtok|::strtok|std::strtok$ + - has: + stopBy: neighbor + kind: argument_list + - not: + inside: + stopBy: end + any: + - kind: subscript_expression + # - kind: call_expression + - not: + has: + stopBy: end + any: + - kind: assignment_expression + - inside: + stopBy: end + kind: return_statement + \ No newline at end of file diff --git a/tests/__snapshots__/null-library-function-c-snapshot.yml b/tests/__snapshots__/null-library-function-c-snapshot.yml new file mode 100644 index 00000000..e31ea4e7 --- /dev/null +++ b/tests/__snapshots__/null-library-function-c-snapshot.yml @@ -0,0 +1,94 @@ +id: null-library-function-c +snapshots: + ? |- + void test_getc() { + int c = getc(fptr = fopen(file_name, "r")); + } + : labels: + - source: getc(fptr = fopen(file_name, "r")) + style: primary + start: 28 + end: 62 + - source: getc + style: secondary + start: 28 + end: 32 + - source: fptr + style: secondary + start: 33 + end: 37 + - source: fopen + style: secondary + start: 40 + end: 45 + - source: fopen(file_name, "r") + style: secondary + start: 40 + end: 61 + - source: fptr = fopen(file_name, "r") + style: secondary + start: 33 + end: 61 + - source: (fptr = fopen(file_name, "r")) + style: secondary + start: 32 + end: 62 + ? | + { + FILE *fptr; + fwrite("foo", 3, 1, fptr = fopen("foo.txt", "w")); + } + : labels: + - source: fwrite("foo", 3, 1, fptr = fopen("foo.txt", "w")) + style: primary + start: 16 + end: 65 + - source: fwrite + style: secondary + start: 16 + end: 22 + - source: fopen + style: secondary + start: 43 + end: 48 + - source: ("foo.txt", "w") + style: secondary + start: 48 + end: 64 + - source: fopen("foo.txt", "w") + style: secondary + start: 43 + end: 64 + - source: ("foo", 3, 1, fptr = fopen("foo.txt", "w")) + style: secondary + start: 22 + end: 65 + ? | + { + fwrite("foo", 3, 1, fopen("foo.txt", "w")); + } + : labels: + - source: fwrite("foo", 3, 1, fopen("foo.txt", "w")) + style: primary + start: 3 + end: 45 + - source: fwrite + style: secondary + start: 3 + end: 9 + - source: fopen + style: secondary + start: 23 + end: 28 + - source: ("foo.txt", "w") + style: secondary + start: 28 + end: 44 + - source: fopen("foo.txt", "w") + style: secondary + start: 23 + end: 44 + - source: ("foo", 3, 1, fopen("foo.txt", "w")) + style: secondary + start: 9 + end: 45 diff --git a/tests/__snapshots__/null-library-function-cpp-snapshot.yml b/tests/__snapshots__/null-library-function-cpp-snapshot.yml new file mode 100644 index 00000000..e8d68475 --- /dev/null +++ b/tests/__snapshots__/null-library-function-cpp-snapshot.yml @@ -0,0 +1,124 @@ +id: null-library-function-cpp +snapshots: + ? | + void f() { + char buf[128]; + strcpy(buf, getenv("FOO")); + } + : labels: + - source: strcpy(buf, getenv("FOO")) + style: primary + start: 32 + end: 58 + - source: strcpy + style: secondary + start: 32 + end: 38 + - source: getenv + style: secondary + start: 44 + end: 50 + - source: ("FOO") + style: secondary + start: 50 + end: 57 + - source: getenv("FOO") + style: secondary + start: 44 + end: 57 + - source: (buf, getenv("FOO")) + style: secondary + start: 38 + end: 58 + ? |- + void test_getc() { + int c = getc(fptr = fopen(file_name, "r")); + } + : labels: + - source: getc(fptr = fopen(file_name, "r")) + style: primary + start: 28 + end: 62 + - source: getc + style: secondary + start: 28 + end: 32 + - source: fptr + style: secondary + start: 33 + end: 37 + - source: fopen + style: secondary + start: 40 + end: 45 + - source: fopen(file_name, "r") + style: secondary + start: 40 + end: 61 + - source: fptr = fopen(file_name, "r") + style: secondary + start: 33 + end: 61 + - source: (fptr = fopen(file_name, "r")) + style: secondary + start: 32 + end: 62 + ? | + { + FILE *fptr; + fwrite("foo", 3, 1, fptr = fopen("foo.txt", "w")); + } + : labels: + - source: fwrite("foo", 3, 1, fptr = fopen("foo.txt", "w")) + style: primary + start: 16 + end: 65 + - source: fwrite + style: secondary + start: 16 + end: 22 + - source: fopen + style: secondary + start: 43 + end: 48 + - source: ("foo.txt", "w") + style: secondary + start: 48 + end: 64 + - source: fopen("foo.txt", "w") + style: secondary + start: 43 + end: 64 + - source: ("foo", 3, 1, fptr = fopen("foo.txt", "w")) + style: secondary + start: 22 + end: 65 + ? | + { + fwrite("foo", 3, 1, fopen("foo.txt", "w")); + } + : labels: + - source: fwrite("foo", 3, 1, fopen("foo.txt", "w")) + style: primary + start: 3 + end: 45 + - source: fwrite + style: secondary + start: 3 + end: 9 + - source: fopen + style: secondary + start: 23 + end: 28 + - source: ("foo.txt", "w") + style: secondary + start: 28 + end: 44 + - source: fopen("foo.txt", "w") + style: secondary + start: 23 + end: 44 + - source: ("foo", 3, 1, fopen("foo.txt", "w")) + style: secondary + start: 9 + end: 45 diff --git a/tests/__snapshots__/return-c-str-cpp-snapshot.yml b/tests/__snapshots__/return-c-str-cpp-snapshot.yml index 56d09ba6..e577adf6 100644 --- a/tests/__snapshots__/return-c-str-cpp-snapshot.yml +++ b/tests/__snapshots__/return-c-str-cpp-snapshot.yml @@ -27,3 +27,12 @@ snapshots: style: primary start: 28 end: 57 + ? | + char *return_namespace_directly() { + return std::string("foo").c_str(); + } + : labels: + - source: return std::string("foo").c_str(); + style: primary + start: 38 + end: 72 diff --git a/tests/__snapshots__/sizeof-this-c-snapshot.yml b/tests/__snapshots__/sizeof-this-c-snapshot.yml index 9e4a6df6..148c2f8c 100644 --- a/tests/__snapshots__/sizeof-this-c-snapshot.yml +++ b/tests/__snapshots__/sizeof-this-c-snapshot.yml @@ -1,2 +1,26 @@ id: sizeof-this-c -snapshots: {} +snapshots: + ? | + struct Foo { + uint64_t a; + uint8_t b; + size_t get_size() const { + return sizeof(this); + } + : labels: + - source: sizeof(this) + style: primary + start: 77 + end: 89 + - source: sizeof + style: secondary + start: 77 + end: 83 + - source: this + style: secondary + start: 84 + end: 88 + - source: (this) + style: secondary + start: 83 + end: 89 diff --git a/tests/c/null-library-function-c-test.yml b/tests/c/null-library-function-c-test.yml new file mode 100644 index 00000000..d5fbbf3a --- /dev/null +++ b/tests/c/null-library-function-c-test.yml @@ -0,0 +1,29 @@ +id: null-library-function-c +valid: + - | + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + +invalid: + - | + void f() { + char buf[128]; + strcpy(buf, getenv("FOO")); + } + - | + { + fwrite("foo", 3, 1, fopen("foo.txt", "w")); + } + - | + { + FILE *fptr; + fwrite("foo", 3, 1, fptr = fopen("foo.txt", "w")); + } + - | + void test_getc() { + int c = getc(fptr = fopen(file_name, "r")); + } \ No newline at end of file diff --git a/tests/cpp/null-library-function-cpp-test.yml b/tests/cpp/null-library-function-cpp-test.yml new file mode 100644 index 00000000..ac8f268e --- /dev/null +++ b/tests/cpp/null-library-function-cpp-test.yml @@ -0,0 +1,29 @@ +id: null-library-function-cpp +valid: + - | + errno = 0; + fwrite(data, len, 1, f); + if (errno) { + ERRS("unable to write output file"); + goto out_flush; + } + +invalid: + - | + void f() { + char buf[128]; + strcpy(buf, getenv("FOO")); + } + - | + { + fwrite("foo", 3, 1, fopen("foo.txt", "w")); + } + - | + { + FILE *fptr; + fwrite("foo", 3, 1, fptr = fopen("foo.txt", "w")); + } + - | + void test_getc() { + int c = getc(fptr = fopen(file_name, "r")); + } \ No newline at end of file