Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions buggy_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import time

# 1. 逻辑/语法错误:函数定义缺少冒号,且缩进不规范
def calculate_discount(price, discount)
final_price = price * (1 - discount)
return final_price # 缩进错误
Comment on lines +1 to +6

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Syntax errors prevent this function from parsing.

Multiple issues on this function definition:

  1. Line 4: Missing colon (:) after the function signature.
  2. Line 6: Inconsistent indentation (3 spaces instead of 4).
  3. Line 1: time is imported but never used.
🔎 Proposed fix
-import time
-
-# 1. 逻辑/语法错误:函数定义缺少冒号,且缩进不规范
-def calculate_discount(price, discount)
-    final_price = price * (1 - discount)
-   return final_price  # 缩进错误
+# 1. 逻辑/语法错误:函数定义缺少冒号,且缩进不规范
+def calculate_discount(price, discount):
+    final_price = price * (1 - discount)
+    return final_price
🧰 Tools
🪛 Ruff (0.14.10)

3-3: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)


3-3: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)


4-5: Expected :, found newline

(invalid-syntax)


6-6: unindent does not match any outer indentation level

(invalid-syntax)

🤖 Prompt for AI Agents
In buggy_script.py around lines 1 to 6, the calculate_discount function has
syntax and indentation errors and there's an unused import: add the missing
colon after the function signature, fix the return indentation to match the
function body (use consistent 4-space indentation), and remove the unused import
of time (or use it if intended); ensure the file parses cleanly after these
corrections.


# 2. 陷阱:使用可变对象(列表)作为默认参数
def add_item_to_cart(item, cart=[]):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

默认参数使用可变对象(列表)。每次调用函数时,如果未提供 cart 参数,则使用相同的列表对象,可能导致意外的行为。

cart.append(item)
return cart
Comment on lines +8 to +11

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Mutable default argument causes shared state across calls.

Using cart=[] means all calls without an explicit cart argument share the same list instance. Items accumulate unexpectedly across invocations.

🔎 Proposed fix using None sentinel pattern
-def add_item_to_cart(item, cart=[]):
+def add_item_to_cart(item, cart=None):
+    if cart is None:
+        cart = []
     cart.append(item)
     return cart
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 2. 陷阱:使用可变对象(列表)作为默认参数
def add_item_to_cart(item, cart=[]):
cart.append(item)
return cart
# 2. 陷阱:使用可变对象(列表)作为默认参数
def add_item_to_cart(item, cart=None):
if cart is None:
cart = []
cart.append(item)
return cart
🧰 Tools
🪛 Ruff (0.14.10)

8-8: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)


8-8: Comment contains ambiguous (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?

(RUF003)


8-8: Comment contains ambiguous (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?

(RUF003)

🤖 Prompt for AI Agents
In buggy_script.py around lines 8 to 11, the function add_item_to_cart uses a
mutable default argument (cart=[]), causing shared state across calls; change
the signature to use cart=None and inside the function set cart = [] if cart is
None, then append the item and return cart; ensure that if a caller passes an
existing list you append to that list (do not replace it), and avoid altering
any module-level state.


class User:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

类的初始化方法拼写错误,应该是 init 而不是 init

# 3. 拼写错误:初始化方法写成了 _init_ 而不是 __init__
def _init_(self, name, age):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

初始化方法拼写错误,应该是 init 而不是 init

self.name = name
self.age = age

def greet(self):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

尝试将字符串和整数直接连接,会导致 TypeError。

# 4. 类型错误:尝试将字符串和整数直接连接
print("Hello, I am " + self.name + " and I am " + self.age + " years old.")
Comment on lines +13 to +21

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Constructor typo and type error in greet method.

Two critical issues:

  1. Line 15: _init_ should be __init__ (double underscores). The current method won't be invoked as a constructor.
  2. Line 21: Concatenating self.age (int) with strings raises TypeError.
🔎 Proposed fix
 class User:
     # 3. 拼写错误:初始化方法写成了 _init_ 而不是 __init__
-    def _init_(self, name, age):
+    def __init__(self, name, age):
         self.name = name
         self.age = age
 
     def greet(self):
         # 4. 类型错误:尝试将字符串和整数直接连接
-        print("Hello, I am " + self.name + " and I am " + self.age + " years old.")
+        print(f"Hello, I am {self.name} and I am {self.age} years old.")
🧰 Tools
🪛 Ruff (0.14.10)

14-14: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)


20-20: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)

🤖 Prompt for AI Agents
In buggy_script.py around lines 13 to 21, the class constructor is misspelled as
_init_ instead of __init__, so instances won't be initialized; rename the method
to __init__ and ensure it accepts name and age and assigns them to self.name and
self.age. In the greet method avoid concatenating an int with strings—convert
self.age to a string or format the output (e.g., use f-strings or str(self.age))
so the print statement builds a valid string.


def main():

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用了错误的运算符 (^ 是异或,不是幂运算)。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在 if 条件中使用了赋值运算符 (=) 而不是比较运算符 (==)。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

运行时错误:IndexError (索引越界)。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

运行时错误:ZeroDivisionError (除以零)。

print("Welcome to the shop!")

# 5. 逻辑错误:运算符误用 (^ 在 Python 中是异或,不是幂运算)
square_area = 10 ^ 2
print(f"Area calculation check: {square_area}")

# 6. 语法错误:在 if 条件中使用了赋值运算符 (=) 而不是比较运算符 (==)
user_input = "yes"
if user_input = "yes":
print("User agreed.")
Comment on lines +26 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Operator errors: XOR vs exponentiation, and assignment in condition.

  1. Line 27: ^ is bitwise XOR in Python, not exponentiation. 10 ^ 2 equals 8, not 100. Use ** for power.
  2. Line 32: Assignment (=) in if condition is a syntax error. Use == for comparison.
🔎 Proposed fix
     # 5. 逻辑错误:运算符误用 (^ 在 Python 中是异或,不是幂运算)
-    square_area = 10 ^ 2 
+    square_area = 10 ** 2
     print(f"Area calculation check: {square_area}") 

     # 6. 语法错误:在 if 条件中使用了赋值运算符 (=) 而不是比较运算符 (==)
     user_input = "yes"
-    if user_input = "yes":
+    if user_input == "yes":
         print("User agreed.")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 5. 逻辑错误:运算符误用 (^ 在 Python 中是异或,不是幂运算)
square_area = 10 ^ 2
print(f"Area calculation check: {square_area}")
# 6. 语法错误:在 if 条件中使用了赋值运算符 (=) 而不是比较运算符 (==)
user_input = "yes"
if user_input = "yes":
print("User agreed.")
# 5. 逻辑错误:运算符误用 (^ 在 Python 中是异或,不是幂运算)
square_area = 10 ** 2
print(f"Area calculation check: {square_area}")
# 6. 语法错误:在 if 条件中使用了赋值运算符 (=) 而不是比较运算符 (==)
user_input = "yes"
if user_input == "yes":
print("User agreed.")
🧰 Tools
🪛 Ruff (0.14.10)

26-26: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)


26-26: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)


30-30: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)


32-32: Expected :, found =

(invalid-syntax)


32-32: Invalid annotated assignment target

(invalid-syntax)


32-33: Expected an expression

(invalid-syntax)


33-33: Unexpected indentation

(invalid-syntax)

🤖 Prompt for AI Agents
In buggy_script.py around lines 26 to 33, two operator mistakes must be fixed:
replace the bitwise XOR used for exponentiation (change the `10 ^ 2` usage to
use the power operator) so the square_area computes 100, and correct the invalid
assignment inside the if condition (change `if user_input = "yes":` to a
comparison) so the conditional is valid and checks equality; update the print
logic accordingly if needed.


# 7. 运行时错误:IndexError (索引越界)
items = ["Apple", "Banana", "Orange"]
for i in range(len(items) + 1):
print(f"Item {i}: {items[i]}")

# 8. 运行时错误:ZeroDivisionError (除以零)
count = 0
total = 100
average = total / count
print("Average: " + average)
Comment on lines +35 to +44

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Runtime errors: IndexError and ZeroDivisionError.

Multiple issues:

  1. Line 37: range(len(items) + 1) iterates indices 0-3, but items[3] is out of bounds.
  2. Line 43: Division by zero when count = 0.
  3. Line 44: String concatenation with float average raises TypeError.
🔎 Proposed fix
     # 7. 运行时错误:IndexError (索引越界)
     items = ["Apple", "Banana", "Orange"]
-    for i in range(len(items) + 1):
-        print(f"Item {i}: {items[i]}")
+    for i in range(len(items)):
+        print(f"Item {i}: {items[i]}")

     # 8. 运行时错误:ZeroDivisionError (除以零)
-    count = 0
+    count = 10  # or add a guard: if count != 0
     total = 100
     average = total / count
-    print("Average: " + average)
+    print(f"Average: {average}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 7. 运行时错误:IndexError (索引越界)
items = ["Apple", "Banana", "Orange"]
for i in range(len(items) + 1):
print(f"Item {i}: {items[i]}")
# 8. 运行时错误:ZeroDivisionError (除以零)
count = 0
total = 100
average = total / count
print("Average: " + average)
# 7. 运行时错误:IndexError (索引越界)
items = ["Apple", "Banana", "Orange"]
for i in range(len(items)):
print(f"Item {i}: {items[i]}")
# 8. 运行时错误:ZeroDivisionError (除以零)
count = 10 # or add a guard: if count != 0
total = 100
average = total / count
print(f"Average: {average}")
🧰 Tools
🪛 Ruff (0.14.10)

35-35: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)


40-40: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)

🤖 Prompt for AI Agents
In buggy_script.py around lines 35 to 44, the code causes an IndexError by
iterating range(len(items) + 1) (accessing items[3]) and a ZeroDivisionError
plus TypeError by dividing by zero and concatenating a float to a string; fix by
iterating only existing indices (use range(len(items)) or iterate items
directly), guard the division with a check (if count == 0 set average to 0 or
skip calculation) or raise/handle the error, and format the output using string
conversion or an f-string (e.g., f"Average: {average}") so no TypeError occurs.


# 9. 拼写错误:name 变量拼写错误
if __name__ == "__main__":
mian()
Comment on lines +46 to +48

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Typo: mian() should be main().

Line 48 calls mian() which is undefined, raising NameError at runtime.

🔎 Proposed fix
 # 9. 拼写错误:name 变量拼写错误
 if __name__ == "__main__":
-    mian()
+    main()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 9. 拼写错误:name 变量拼写错误
if __name__ == "__main__":
mian()
# 9. 拼写错误:name 变量拼写错误
if __name__ == "__main__":
main()
🧰 Tools
🪛 Ruff (0.14.10)

46-46: Comment contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF003)

🤖 Prompt for AI Agents
In buggy_script.py around lines 46 to 48, there's a typo where the script calls
the undefined function `mian()`; change the call to `main()` so the correct
entry-point function is invoked and the NameError on execution is resolved.

54 changes: 54 additions & 0 deletions cpp_security_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>

#define BUFFER_SIZE 10

void bufferOverflowVuln(const char* input) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用 strcpy 导致缓冲区溢出。

char buffer[BUFFER_SIZE];
strcpy(buffer, input);
std::cout << "Vulnerable Buffer: " << buffer << std::endl;
}
Comment on lines +8 to +12

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Buffer overflow vulnerability (CWE-120).

This function uses strcpy without bounds checking, allowing buffer overflow when input exceeds 9 characters (10 bytes including null terminator). If this is intentional for CWE demonstration purposes, add clear documentation and consider:

  • Adding a prominent comment block explaining the vulnerability
  • Renaming to make the danger explicit (e.g., UNSAFE_bufferOverflowDemo)
  • Placing in a dedicated test/demo directory with a README
  • Adding compile-time guards or build flags to prevent accidental use
🔎 Recommended safeguards if keeping this for educational purposes
+// INTENTIONAL VULNERABILITY - CWE-120: Buffer Overflow
+// DO NOT USE IN PRODUCTION CODE
+// Demonstrates unsafe strcpy() usage for security testing
 void bufferOverflowVuln(const char* input) {
     char buffer[BUFFER_SIZE];
-    strcpy(buffer, input); 
+    strcpy(buffer, input);  // UNSAFE: No bounds checking
     std::cout << "Vulnerable Buffer: " << buffer << std::endl;
 }
🤖 Prompt for AI Agents
In cpp_security_test.cpp around lines 8 to 12, the function bufferOverflowVuln
uses strcpy without bounds checking causing a CWE-120 buffer overflow; either
make the unsafe intent explicit or fix it: if intent is demonstration, rename to
UNSAFE_bufferOverflowDemo, add a prominent comment block explaining the
vulnerability and mitigation, move to a dedicated demo/test directory with
README, and add compile-time guards or build flags to prevent accidental
inclusion; otherwise make it safe by replacing strcpy with a bounded alternative
(use std::string or strncpy/strnlen with BUFFER_SIZE-1 and explicit
null-termination) and validate input length before copy.


void memoryLeakVuln() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

动态分配的内存未释放,导致内存泄漏。

int* data = new int[100];
if (data == nullptr) return;

data[0] = 1;
std::cout << "Memory allocated and leaked." << std::endl;
}
Comment on lines +14 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Memory leak vulnerability (CWE-401).

Memory allocated with new int[100] is never freed with delete[], causing a leak of approximately 400 bytes per call. Static analysis correctly flagged this issue. If this is intentional for CWE demonstration, add clear documentation.

🔎 Production fix vs. demo documentation

Production fix:

 void memoryLeakVuln() {
     int* data = new int[100];
     if (data == nullptr) return;
 
     data[0] = 1;
     std::cout << "Memory allocated and leaked." << std::endl;
+    delete[] data;  // Free the allocated memory
 }

If keeping for demo purposes:

+// INTENTIONAL VULNERABILITY - CWE-401: Memory Leak
+// DO NOT USE IN PRODUCTION CODE
+// Demonstrates memory leak for security testing
 void memoryLeakVuln() {
     int* data = new int[100];
     if (data == nullptr) return;
 
     data[0] = 1;
-    std::cout << "Memory allocated and leaked." << std::endl;
+    std::cout << "Memory allocated and leaked." << std::endl;  // UNSAFE: Missing delete[]
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void memoryLeakVuln() {
int* data = new int[100];
if (data == nullptr) return;
data[0] = 1;
std::cout << "Memory allocated and leaked." << std::endl;
}
void memoryLeakVuln() {
int* data = new int[100];
if (data == nullptr) return;
data[0] = 1;
std::cout << "Memory allocated and leaked." << std::endl;
delete[] data; // Free the allocated memory
}
🧰 Tools
🪛 Cppcheck (2.19.0)

[error] 20-20: Memory leak

(memleak)

🤖 Prompt for AI Agents
In cpp_security_test.cpp around lines 14 to 20, the function memoryLeakVuln
allocates with new int[100] and never frees it, causing a CWE-401 memory leak;
fix by either (preferred) replacing the raw allocation with a RAII container
(e.g., std::vector<int> or std::unique_ptr<int[]>) so deallocation is automatic,
or (if keeping raw new for demonstration) add a matching delete[] data before
every return and add a clear comment explaining the intentional leak for CWE
demonstration and documenting expected behavior and lifetime.


int integerOverflowVuln(int a, int b) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

整数溢出漏洞。

return a + b;
}
Comment on lines +22 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Integer overflow vulnerability (CWE-190).

This function performs addition without overflow checking, causing undefined behavior when the result exceeds INT_MAX. Line 48 demonstrates this by calling with (2147483647, 1) (INT_MAX + 1), which triggers signed integer overflow.

🔎 Production fix vs. demo documentation

Production fix with overflow check:

+#include <limits>
+
 int integerOverflowVuln(int a, int b) {
-    return a + b; 
+    // Check for overflow before addition
+    if (a > 0 && b > 0 && a > std::numeric_limits<int>::max() - b) {
+        throw std::overflow_error("Integer overflow detected");
+    }
+    if (a < 0 && b < 0 && a < std::numeric_limits<int>::min() - b) {
+        throw std::underflow_error("Integer underflow detected");
+    }
+    return a + b;
 }

If keeping for demo purposes:

+// INTENTIONAL VULNERABILITY - CWE-190: Integer Overflow
+// DO NOT USE IN PRODUCTION CODE
+// Demonstrates unchecked integer addition
 int integerOverflowVuln(int a, int b) {
-    return a + b; 
+    return a + b;  // UNSAFE: No overflow checking
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In cpp_security_test.cpp around lines 22 to 24, the function integerOverflowVuln
performs an unchecked int addition which can overflow (e.g., INT_MAX + 1); fix
it by adding an explicit overflow check before returning: either cast operands
to a wider type (e.g., int64_t) to compute the sum and verify it fits into int,
or check bounds using INT_MAX/INT_MIN (if b > 0 ensure a <= INT_MAX - b; if b <
0 ensure a >= INT_MIN - b) and handle the overflow case deterministically
(return an error code, clamp, or throw an exception) rather than allowing
undefined behavior.


void formatStringVuln(const char* logMessage) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

格式化字符串漏洞。

printf(logMessage);
printf("\n");
}
Comment on lines +26 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Format string vulnerability (CWE-134).

User input is passed directly as a format string to printf, allowing attackers to:

  • Read arbitrary memory using %s or %x specifiers
  • Write arbitrary memory using %n specifier (potentially achieving code execution)
  • Crash the program with invalid format strings

This is exploitable when called from main_cwe_test with user-controlled argv[1].

🔎 Production fix vs. demo documentation

Production fix:

 void formatStringVuln(const char* logMessage) {
-    printf(logMessage); 
+    printf("%s", logMessage);  // Safe: Treat logMessage as data, not format string
     printf("\n");
 }

If keeping for demo purposes:

+// INTENTIONAL VULNERABILITY - CWE-134: Format String Vulnerability
+// DO NOT USE IN PRODUCTION CODE
+// Demonstrates unsafe printf usage with user input
 void formatStringVuln(const char* logMessage) {
-    printf(logMessage); 
+    printf(logMessage);  // UNSAFE: User input as format string
     printf("\n");
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void formatStringVuln(const char* logMessage) {
printf(logMessage);
printf("\n");
}
// INTENTIONAL VULNERABILITY - CWE-134: Format String Vulnerability
// DO NOT USE IN PRODUCTION CODE
// Demonstrates unsafe printf usage with user input
void formatStringVuln(const char* logMessage) {
printf(logMessage); // UNSAFE: User input as format string
printf("\n");
}
Suggested change
void formatStringVuln(const char* logMessage) {
printf(logMessage);
printf("\n");
}
void formatStringVuln(const char* logMessage) {
printf("%s", logMessage); // Safe: Treat logMessage as data, not format string
printf("\n");
}
🤖 Prompt for AI Agents
In cpp_security_test.cpp around lines 26 to 29, formatStringVuln passes
user-controlled data directly as the printf format string, creating a CWE-134
format-string vulnerability; fix it by treating logMessage as data not a format:
call printf with a constant format specifier (e.g. printf("%s\n", logMessage))
or use puts/snprintf to a bounded buffer, validate or sanitize input (escape
percent signs) if needed, and ensure no use of %n or other risky specifiers so
user input cannot control formatting or memory access.


void bufferOverflowSafe(const char* input) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用 strncpy 和手动设置 null 终止符来防止缓冲区溢出。

char buffer[BUFFER_SIZE];
strncpy(buffer, input, BUFFER_SIZE - 1);
buffer[BUFFER_SIZE - 1] = '\0';
std::cout << "Safe Buffer: " << buffer << std::endl;
}

int main_cwe_test(int argc, char** argv) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

缺少对输入参数的有效性检查。

if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <input_string>" << std::endl;
return 1;
}

const char* user_input = argv[1];

bufferOverflowVuln(user_input);
memoryLeakVuln();
int result = integerOverflowVuln(2147483647, 1);
formatStringVuln(user_input);

Comment on lines +46 to +50

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: User input passed to multiple vulnerable functions.

Lines 46, 48, and 49 pass untrusted user input to functions with critical security vulnerabilities:

  • bufferOverflowVuln(user_input) - triggers buffer overflow (CWE-120)
  • integerOverflowVuln(2147483647, 1) - triggers integer overflow (CWE-190)
  • formatStringVuln(user_input) - triggers format string vulnerability (CWE-134)

Additionally, line 48 assigns the overflow result to result but never uses it, causing a compiler warning.

🔎 Recommended changes

Remove unused variable:

     bufferOverflowVuln(user_input);
     memoryLeakVuln();
-    int result = integerOverflowVuln(2147483647, 1); 
+    integerOverflowVuln(2147483647, 1);  // Demonstrates overflow
     formatStringVuln(user_input);

If this is a test/demo file, add protective measures:

+#ifdef ENABLE_VULNERABLE_DEMOS
+    // WARNING: The following calls demonstrate security vulnerabilities
+    // Only enabled when ENABLE_VULNERABLE_DEMOS is defined
     bufferOverflowVuln(user_input);
     memoryLeakVuln();
-    int result = integerOverflowVuln(2147483647, 1); 
+    integerOverflowVuln(2147483647, 1);
     formatStringVuln(user_input);
+#else
+    std::cout << "Vulnerable demos are disabled. Define ENABLE_VULNERABLE_DEMOS to enable." << std::endl;
+#endif
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bufferOverflowVuln(user_input);
memoryLeakVuln();
int result = integerOverflowVuln(2147483647, 1);
formatStringVuln(user_input);
#ifdef ENABLE_VULNERABLE_DEMOS
// WARNING: The following calls demonstrate security vulnerabilities
// Only enabled when ENABLE_VULNERABLE_DEMOS is defined
bufferOverflowVuln(user_input);
memoryLeakVuln();
integerOverflowVuln(2147483647, 1); // Demonstrates overflow
formatStringVuln(user_input);
#else
std::cout << "Vulnerable demos are disabled. Define ENABLE_VULNERABLE_DEMOS to enable." << std::endl;
#endif
🤖 Prompt for AI Agents
In cpp_security_test.cpp around lines 46 to 50, multiple unsafe calls use
untrusted user_input and an unused overflow result: replace
bufferOverflowVuln(user_input) with a safe, bounds-checked call or pass a
sanitized/validated copy (e.g., length-checked buffer or std::string with
explicit copy and bounds), remove or handle the unused int result from
integerOverflowVuln(2147483647, 1) by either checking for overflow before
calling (use wider integer type like int64_t or perform pre-addition overflow
check) or removing the call if unused, and fix formatStringVuln(user_input) by
using a safe formatting API that treats user_input as data (e.g.,
snprintf/format with a fixed format string or using std::format with
placeholders) rather than a format string; if this is a test/demo file, wrap
these calls in clearly marked guarded tests or mock inputs and add comments
explaining the protective measures.

bufferOverflowSafe(user_input);

return 0;
}
172 changes: 172 additions & 0 deletions test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package main

import (
"fmt"
"io/ioutil" // 已弃用的包
"log"
"os"
"strings"
"time"
"unsafe" // 不安全的操作
)

var globalVar int // 未使用的全局变量

// 过长的函数(圈复杂度高)
func processData(data string) error {
if data == "" {
return fmt.Errorf("empty data")
} else if len(data) > 100 {
return fmt.Errorf("data too long")
} else {
parts := strings.Split(data, ",")
for i, part := range parts {
if i%2 == 0 {
if len(part) > 10 {
part = part[:10]
} else {
if part == "test" {
fmt.Println("found test")
}
}
} else {
switch part {
case "a":
fmt.Println("a")
case "b":
fmt.Println("b")
case "c":
fmt.Println("c")
case "d":
fmt.Println("d")
default:
fmt.Println("default")
}
}
}
}
return nil
}

// 未处理的错误
func readFile(filename string) string {
data, _ := ioutil.ReadFile(filename) // 错误未处理
return string(data)
}
Comment on lines +52 to +55

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

严重问题:忽略了文件读取错误。

使用 _ 忽略 ReadFile 的错误会导致静默失败。当文件不存在或无法读取时,函数返回空字符串,调用方无法区分空文件和读取失败。

🔎 建议修复
-func readFile(filename string) string {
-        data, _ := ioutil.ReadFile(filename) // 错误未处理
-        return string(data)
+func readFile(filename string) (string, error) {
+        data, err := os.ReadFile(filename)
+        if err != nil {
+                return "", err
+        }
+        return string(data), nil
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func readFile(filename string) string {
data, _ := ioutil.ReadFile(filename) // 错误未处理
return string(data)
}
func readFile(filename string) (string, error) {
data, err := os.ReadFile(filename)
if err != nil {
return "", err
}
return string(data), nil
}
🤖 Prompt for AI Agents
In test.go around lines 52 to 55, the readFile function ignores
ioutil.ReadFile's error causing silent failures; change the signature to
readFile(filename string) (string, error), capture the error from
ioutil.ReadFile, if err != nil return "", err, otherwise return string(data),
nil, and update all callers to handle the returned error (or propagate it) so
file-not-found or read errors are not swallowed.


// 拼写错误的参数名
func printMessage(mesage string) { // 参数名拼写错误
fmt.Println(mesage)
}

// 返回未导出的类型
type myError struct { // 未导出的类型
msg string
}

func (e *myError) Error() string {
return e.msg
}

func createError() error {
return &myError{msg: "error"} // 返回未导出的类型
}

// 冗余的代码
func redundantCode() {
var s string = "hello" // 冗余的类型声明
fmt.Println(s)

var i int
i = 10 // 可以合并声明和赋值
fmt.Println(i)

if true { // 总是为true的条件
fmt.Println("always true")
}
}

// 使用不安全操作
func unsafeOperation() {
var x int = 42
ptr := unsafe.Pointer(&x)
fmt.Printf("Pointer: %v\n", ptr)
}

// 未使用的参数
func unusedParameter(unused string) int { // 未使用的参数
return 42
}

// 魔法数字
func calculate() int {
return 100 * 24 * 60 * 60 // 魔法数字
}

// 冗长的函数调用链
func longChain() {
fmt.Println(strings.ToUpper(strings.TrimSpace(strings.Replace("hello world", "world", "golang", -1))))
}

// 空的错误检查
func emptyErrorCheck() {
err := processData("test")
if err != nil { // 空的错误检查
// 什么也不做
}
}
Comment on lines +111 to +117

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

空的错误处理块。

检查了错误但未做任何处理,这会导致问题难以调试。应记录错误或向上传播。

🔎 建议修复
 func emptyErrorCheck() {
         err := processData("test")
-        if err != nil { // 空的错误检查
-                // 什么也不做
+        if err != nil {
+                log.Printf("processData failed: %v", err)
         }
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In test.go around lines 111 to 117, the function emptyErrorCheck detects an
error from processData but the if block is empty; either handle the error (log
it with context and any details) or change the function signature to return an
error and propagate it (e.g., return fmt.Errorf("processData failed: %w", err));
ensure you choose one approach consistently, add necessary imports (log or fmt),
and remove the silent empty branch so errors are not swallowed.


// defer 在循环中
func deferInLoop() {
for i := 0; i < 10; i++ {
file, _ := os.Create(fmt.Sprintf("test%d.txt", i))
defer file.Close() // defer在循环中
file.WriteString("test")
}
}
Comment on lines +119 to +126

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

严重问题:循环中使用 defer 导致资源泄漏。

defer 语句在函数返回时才执行,而非循环迭代结束时。这会导致所有文件句柄在函数退出前一直保持打开状态,可能耗尽文件描述符。此外,os.Create 的错误被忽略,可能导致空指针解引用。

🔎 建议修复
 func deferInLoop() {
         for i := 0; i < 10; i++ {
-                file, _ := os.Create(fmt.Sprintf("test%d.txt", i))
-                defer file.Close() // defer在循环中
-                file.WriteString("test")
+                func() {
+                        file, err := os.Create(fmt.Sprintf("test%d.txt", i))
+                        if err != nil {
+                                log.Printf("failed to create file: %v", err)
+                                return
+                        }
+                        defer file.Close()
+                        file.WriteString("test")
+                }()
         }
 }
🤖 Prompt for AI Agents
In test.go around lines 119 to 126, the loop uses defer file.Close() which
defers closes until the outer function returns (causing file descriptor leaks)
and os.Create's error is ignored (risking nil deref); fix by checking the error
returned by os.Create and handling it (log/continue/return), perform
file.WriteString and check its error, then call file.Close() immediately after
the write and handle its error instead of deferring; alternatively, if you
prefer defer semantics per iteration, wrap the iteration body in a short
anonymous function and defer inside it so the file is closed at the end of each
iteration.


// 可能的竞态条件
var counter int

func incrementCounter() {
counter++ // 非原子操作
}
Comment on lines +128 to +133

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

严重问题:存在数据竞争。

counter++ 不是原子操作,当 incrementCounter 在 goroutine 中被调用时(第 165 行),会与主 goroutine 产生数据竞争。

🔎 建议修复(使用 sync/atomic)
+import "sync/atomic"
+
-var counter int
+var counter int64

 func incrementCounter() {
-        counter++ // 非原子操作
+        atomic.AddInt64(&counter, 1)
 }

或者使用 sync.Mutex 进行保护。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 可能的竞态条件
var counter int
func incrementCounter() {
counter++ // 非原子操作
}
import "sync/atomic"
// 可能的竞态条件
var counter int64
func incrementCounter() {
atomic.AddInt64(&counter, 1)
}
🤖 Prompt for AI Agents
In test.go around lines 128 to 133, the global counter++ is a non-atomic
operation causing a data race when incrementCounter is called from goroutines
(see use at line 165); fix by making counter an int64 and replacing non-atomic
increments with sync/atomic operations (use atomic.AddInt64(&counter, 1) and
atomic.LoadInt64 for reads) and add the sync/atomic import, or alternatively
protect counter with a sync.Mutex: declare a mutex, lock/unlock around
increments and reads; update all call sites accordingly to eliminate the race.


// 使用 time.Sleep 而不是 context
func waitForCondition() {
time.Sleep(5 * time.Second) // 应该使用context
fmt.Println("done waiting")
}

// 过长的行
func veryLongFunctionNameWithManyParameters(param1 string, param2 int, param3 bool, param4 float64, param5 []string) (result string, err error) {
// 这是一个非常长的行,超过了通常的代码风格指南建议的80或120字符限制,应该被分解成多行以提高可读性。
return "result", nil
}

// 主函数
func main() {
fmt.Println("Starting application...")

// 调用各种有问题的函数
processData("test,data,example,hello,world,foo,bar,baz")
readFile("nonexistent.txt")
printMessage("Hello")
redundantCode()
unsafeOperation()
unusedParameter("test")
result := calculate()
fmt.Printf("Result: %d\n", result)
longChain()
emptyErrorCheck()
deferInLoop()

// 启动goroutine但没有同步
go incrementCounter()

waitForCondition()
Comment on lines +164 to +167

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

启动的 goroutine 缺少同步机制。

启动 goroutine 后没有等待其完成,程序可能在 goroutine 执行前就退出。time.Sleep 不能保证 goroutine 完成。

🔎 建议修复
+var wg sync.WaitGroup
+
 func main() {
         // ...
-        go incrementCounter()
+        wg.Add(1)
+        go func() {
+                defer wg.Done()
+                incrementCounter()
+        }()
 
-        waitForCondition()
+        wg.Wait()
         // ...
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 启动goroutine但没有同步
go incrementCounter()
waitForCondition()
// 启动goroutine但没有同步
wg.Add(1)
go func() {
defer wg.Done()
incrementCounter()
}()
wg.Wait()
🤖 Prompt for AI Agents
In test.go around lines 164 to 167, the goroutine started with go
incrementCounter() is not synchronized so the program may exit before it runs;
replace the sleeping/waitForCondition approach with explicit synchronization
(e.g., add a sync.WaitGroup or a done channel), increment the WaitGroup counter
before launching the goroutine (or pass the channel into incrementCounter), have
the goroutine signal completion (wg.Done() or close/send on the channel), and
then block the main flow on wg.Wait() or receiving from the channel to ensure
the goroutine has completed before continuing.


veryLongFunctionNameWithManyParameters("param1", 123, true, 3.14, []string{"a", "b", "c"})

log.Println("Application finished")
}
Loading