From b97bb8fc795e49b208d319490c90f0d7e6e85b38 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 07:44:54 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20`2025122?= =?UTF-8?q?31408`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @SoftSec-Tech. * https://github.com/SoftSec-Tech/big_num_cal/pull/8#issuecomment-3685268786 The following files were modified: * `buggy_script.py` * `test.go` * `test.php` * `vulnerable.cpp` * `xxtest.c` --- buggy_script.py | 27 +++++++++++++++++++++ test.go | 49 +++++++++++++++++++++++++++----------- test.php | 54 ++++++++++++++++++++++++++++++++++++++---- vulnerable.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++--- xxtest.c | 35 +++++++++++++++++++++++---- 5 files changed, 203 insertions(+), 25 deletions(-) diff --git a/buggy_script.py b/buggy_script.py index 42a4e92..f7fa1d3 100644 --- a/buggy_script.py +++ b/buggy_script.py @@ -7,20 +7,47 @@ def calculate_discount(price, discount) # 2. 陷阱:使用可变对象(列表)作为默认参数 def add_item_to_cart(item, cart=[]): + """ + Append an item to a shopping cart list. + + Parameters: + item: The item to add to the cart. + cart (list): List to which the item will be appended. If omitted, a module-level default list is reused, so successive calls without an explicit cart share the same list. + + Returns: + list: The cart after the item has been appended. + """ cart.append(item) return cart class User: # 3. 拼写错误:初始化方法写成了 _init_ 而不是 __init__ def _init_(self, name, age): + """ + Initialize the user's name and age. + + Parameters: + name (str): The user's name. + age (int): The user's age in years. + """ self.name = name self.age = age def greet(self): # 4. 类型错误:尝试将字符串和整数直接连接 + """ + Prints a greeting that includes the user's name and age. + + Expects self.name and self.age to be strings; concatenation with non-string types will raise a TypeError. + """ print("Hello, I am " + self.name + " and I am " + self.age + " years old.") def main(): + """ + Run a short shop demo that prints messages and performs several example computations and loops. + + This function prints a welcome message, computes a numeric expression, evaluates a conditional branch, iterates over a list of items, and computes an average. When executed as written it performs console output and may raise runtime errors such as IndexError (accessing an out-of-range list index) and ZeroDivisionError (division by zero). + """ print("Welcome to the shop!") # 5. 逻辑错误:运算符误用 (^ 在 Python 中是异或,不是幂运算) diff --git a/test.go b/test.go index bdbc29a..97c4b78 100644 --- a/test.go +++ b/test.go @@ -12,7 +12,16 @@ import ( var globalVar int // 未使用的全局变量 -// 过长的函数(圈复杂度高) +// processData validates the input string and processes its comma-separated parts. +// +// For an empty input it returns an error with message "empty data"; for input +// longer than 100 bytes it returns an error with message "data too long". +// The input `data` is treated as a comma-separated list of parts. For each +// even-indexed part (0-based) it truncates the part to 10 characters if longer +// than 10, and prints "found test" if the part equals "test". For each +// odd-indexed part it prints "a", "b", "c", or "d" when the part is "a", "b", +// "c", or "d" respectively, and prints "default" for any other value. On +// successful processing it returns nil. func processData(data string) error { if data == "" { return fmt.Errorf("empty data") @@ -48,13 +57,14 @@ func processData(data string) error { return nil } -// 未处理的错误 +// readFile reads the contents of the named file and returns them as a string. +// If the file cannot be read, it returns the empty string. func readFile(filename string) string { data, _ := ioutil.ReadFile(filename) // 错误未处理 return string(data) } -// 拼写错误的参数名 +// printMessage prints the provided message to standard output. func printMessage(mesage string) { // 参数名拼写错误 fmt.Println(mesage) } @@ -68,11 +78,14 @@ func (e *myError) Error() string { return e.msg } +// createError returns an error whose message is "error". func createError() error { return &myError{msg: "error"} // 返回未导出的类型 } -// 冗余的代码 +// redundantCode demonstrates several redundant or suboptimal code patterns: +// redundant type declaration for a local string, separate declaration and assignment +// for an integer, and an always-true conditional block. func redundantCode() { var s string = "hello" // 冗余的类型声明 fmt.Println(s) @@ -86,29 +99,31 @@ func redundantCode() { } } -// 使用不安全操作 +// unsafeOperation demonstrates obtaining an unsafe.Pointer to a local integer and printing that pointer. func unsafeOperation() { var x int = 42 ptr := unsafe.Pointer(&x) fmt.Printf("Pointer: %v\n", ptr) } -// 未使用的参数 +// unusedParameter ignores the provided string parameter and always returns 42. func unusedParameter(unused string) int { // 未使用的参数 return 42 } -// 魔法数字 +// calculate returns the number of seconds in 100 days. +// The value is 100 * 24 * 60 * 60. func calculate() int { return 100 * 24 * 60 * 60 // 魔法数字 } -// 冗长的函数调用链 +// longChain prints "HELLO GOLANG" after replacing "world" with "golang", trimming spaces, and converting the result to upper case. func longChain() { fmt.Println(strings.ToUpper(strings.TrimSpace(strings.Replace("hello world", "world", "golang", -1)))) } -// 空的错误检查 +// emptyErrorCheck calls processData with the literal "test" and intentionally discards any returned error. +// It performs no action when processData returns a non-nil error. func emptyErrorCheck() { err := processData("test") if err != nil { // 空的错误检查 @@ -116,7 +131,8 @@ func emptyErrorCheck() { } } -// defer 在循环中 +// deferInLoop creates ten files named test0.txt through test9.txt and writes "test" to each. +// Each file's Close is deferred, so all files remain open until deferInLoop returns. func deferInLoop() { for i := 0; i < 10; i++ { file, _ := os.Create(fmt.Sprintf("test%d.txt", i)) @@ -128,23 +144,28 @@ func deferInLoop() { // 可能的竞态条件 var counter int +// incrementCounter increments the package-level counter variable. +// It adds one to the global counter and is not safe for concurrent use. func incrementCounter() { counter++ // 非原子操作 } -// 使用 time.Sleep 而不是 context +// waitForCondition pauses execution for five seconds and then prints "done waiting". +// It performs a fixed-duration wait and does not observe contexts or support cancellation. func waitForCondition() { time.Sleep(5 * time.Second) // 应该使用context fmt.Println("done waiting") } -// 过长的行 +// veryLongFunctionNameWithManyParameters performs a placeholder operation using multiple parameters. +// It always returns the string "result" and a nil error. func veryLongFunctionNameWithManyParameters(param1 string, param2 int, param3 bool, param4 float64, param5 []string) (result string, err error) { // 这是一个非常长的行,超过了通常的代码风格指南建议的80或120字符限制,应该被分解成多行以提高可读性。 return "result", nil } -// 主函数 +// main is the program entry point that runs a series of example routines demonstrating various behaviors and anti-patterns. +// It logs startup, invokes multiple helper functions (file I/O, unsafe operations, deferred calls in a loop, etc.), launches a goroutine that increments a counter without synchronization, waits for a condition, and logs completion. func main() { fmt.Println("Starting application...") @@ -169,4 +190,4 @@ func main() { veryLongFunctionNameWithManyParameters("param1", 123, true, 3.14, []string{"a", "b", "c"}) log.Println("Application finished") -} +} \ No newline at end of file diff --git a/test.php b/test.php index dfbfbf7..2758bec 100644 --- a/test.php +++ b/test.php @@ -17,12 +17,30 @@ class UserManager // 未使用的属性 (Unused Code Rules) private $unusedProperty; + /** + * Initialize a new UserManager instance. + * + * Intentionally empty constructor. + */ public function __construct() { // 空构造函数 (Unused Code Rules) } - // 过长的函数 (Code Size Rules) - 超过100行 + /** + * Filter and return users who meet age, country, and subscription criteria. + * + * Processes the provided user records and returns those accepted by the selection + * rules (age > 18; country is 'US' with 'premium' or 'basic' subscription, or + * country is 'CA'). When $verbose is true, processing messages may be emitted. + * + * @param array $users Array of user records. Each record is expected to contain the keys + * `id`, `name`, `email`, `age`, `country`, `subscription`, and `active`. + * @param bool $verbose When true, emit processing messages for diagnostic purposes. + * @return array The list of user records that satisfy the selection criteria. + * + * Side effects: increments the global $globalCounter. + */ public function processUserData(array $users, bool $verbose = false): array { // 未使用的参数 (Unused Code Rules) @@ -114,7 +132,22 @@ public function processUserData(array $users, bool $verbose = false): array return $result; } - // 函数参数过多 (Excessive Parameter List) + /** + * Create a new user record from the provided attributes. + * + * @param string $firstName The user's first name. + * @param string $lastName The user's last name. + * @param string $email The user's email address. + * @param string $phone The user's phone number. + * @param string $address The user's street address. + * @param string $city The user's city. + * @param string $state The user's state or region. + * @param string $zipCode The user's postal or ZIP code. + * @param string $country The user's country. + * @param bool $isActive Whether the user is active. + * @param bool $isAdmin Whether the user has administrative privileges. + * @return array The created user represented as an associative array of the provided attributes. + */ public function createUser( string $firstName, string $lastName, @@ -131,7 +164,12 @@ public function createUser( // 函数体为空 (Empty Function Body) } - // 过深的嵌套 (Depth of Inheritance Tree) + /** + * Classifies an integer into a descriptive category based on its sign, magnitude, and parity. + * + * @param int $value The integer to classify. + * @return string "Special case" if $value is a positive even number not equal to 4; "Even number" if $value is 4; "Odd number" if $value is positive and odd; "Large number" if $value is 10 or greater; "Non-positive" if $value is zero or negative. + */ public function nestedIfExample(int $value): string { if ($value > 0) { @@ -157,6 +195,11 @@ public function nestedIfExample(int $value): string // 未使用的类 (Unused Code Rules) class UnusedClass { + /** + * Echoes the literal string "I'm never called!" to the output. + * + * This method performs a direct output side effect and does not return a value. + */ public function doSomething() { echo "I'm never called!"; @@ -165,6 +208,9 @@ public function doSomething() // 匿名类 (Anonymous Class) $anonymous = new class { + /** + * Outputs a greeting message from the anonymous class. + */ public function greet() { echo "Hello from anonymous class!"; @@ -195,4 +241,4 @@ function unusedFunction(): void echo "Debug mode is " . ($debugMode ? 'ON' : 'OFF'); // 结束 -?> +?> \ No newline at end of file diff --git a/vulnerable.cpp b/vulnerable.cpp index 8636ba3..19b2c22 100644 --- a/vulnerable.cpp +++ b/vulnerable.cpp @@ -17,20 +17,41 @@ class UserManager { string db_password = "root"; // 3. SQL 注入 (CWE-89) - // 直接拼接字符串构建 SQL 查询是 C++ Web 后端常见的严重漏洞 + /** + * @brief Builds an SQL query for a user ID and prints it. + * + * Constructs an SQL SELECT statement using the provided userId and outputs + * the resulting query string to standard output. + * + * @param userId The user identifier used to populate the WHERE clause. + */ void queryUser(string userId) { string query = "SELECT * FROM users WHERE id = '" + userId + "'"; cout << "Executing query: " << query << endl; } // 4. 命令注入 (CWE-78) - // 允许外部输入直接进入 system() 函数 + /** + * @brief Executes the system ping command targeting the given IP address or hostname. + * + * @param ipAddress IP address or hostname to ping; passed directly to the system shell. + */ void pingHost(string ipAddress) { string cmd = "ping -c 4 " + ipAddress; system(cmd.c_str()); } }; +/** + * @brief Copies a null-terminated C string into a fixed-size stack buffer. + * + * Copies the contents of `input` into a local 10-byte buffer using `strcpy`. + * If `input` has length greater than or equal to 10 bytes (including the null + * terminator), this will overwrite adjacent stack memory and cause undefined + * behavior. + * + * @param input Null-terminated C string to copy into the local buffer. + */ void legacyBufferOverflow(char* input) { char buffer[10]; @@ -39,6 +60,12 @@ void legacyBufferOverflow(char* input) { strcpy(buffer, input); } +/** + * @brief Demonstrates allocation of a dynamic array without guaranteed deallocation. + * + * Allocates a heap array of 100 integers and may return before releasing it, + * causing a memory leak in that early-return path. + */ void memoryLeakAndRawPointers() { // 6. 内存泄漏 (CWE-401) // 使用了 new 但没有 delete @@ -54,6 +81,16 @@ void memoryLeakAndRawPointers() { delete[] data; } +/** + * @brief Demonstrates iterator invalidation by modifying a vector while iterating over it. + * + * Iterates a small vector of integers and calls push_back during traversal when a specific + * element is encountered. Mutating the container while iterating may reallocate the + * underlying storage and invalidate iterators, resulting in undefined behavior or a crash. + * + * @note This function intentionally contains unsafe behavior to illustrate iterator + * invalidation (logic error). + */ void iteratorInvalidation() { vector numbers = {1, 2, 3, 4, 5}; @@ -67,6 +104,14 @@ void iteratorInvalidation() { } } +/** + * @brief Generates and prints a non-cryptographic security token. + * + * Prints a time-seeded C-library `rand()` value to stdout in the form + * "Security Token: ". + * + * This token is not suitable for cryptographic or security-sensitive purposes. + */ void weakRandomness() { // 8. 弱伪随机数生成器 (CWE-338) // srand/rand 不适合用于安全相关的随机数生成 @@ -75,6 +120,18 @@ void weakRandomness() { cout << "Security Token: " << token << endl; } +/** + * @brief Program entry point that invokes a set of functions demonstrating common insecure coding patterns. + * + * The function constructs a UserManager instance and, when provided a command-line argument, + * passes that argument to several helper functions which exercise vulnerabilities such as + * SQL/command injection, buffer overflow, memory-management issues, iterator invalidation, + * and weak randomness. It returns early when required input is missing. + * + * @param argc Number of command-line arguments. + * @param argv Array of command-line argument strings. + * @return int 0 on normal completion; 1 if a required command-line argument is missing. + */ int main(int argc, char* argv[]) { UserManager um; @@ -98,4 +155,4 @@ int main(int argc, char* argv[]) { int y = 100 / x; return 0; -} +} \ No newline at end of file diff --git a/xxtest.c b/xxtest.c index 0c6ccb1..adbda96 100644 --- a/xxtest.c +++ b/xxtest.c @@ -3,14 +3,25 @@ #include // 1. 硬编码凭证 (Hardcoded Credentials) -// SAST工具会扫描特定的变量名(如 password, key)和字符串比较 +/** + * Check whether the provided password matches the hardcoded admin password and announce access on success. + * + * Compares the given password against the built-in admin credential and prints "Access Granted!" if they match. + * + * @param input_pass The password to verify; compared against the hardcoded admin password "SuperSecretAdminPassword123". + */ void check_admin(char *input_pass) { if (strcmp(input_pass, "SuperSecretAdminPassword123") == 0) { printf("Access Granted!\n"); } } -// 2. 内存泄漏 (Memory Leak) & 空指针解引用 (Null Pointer Dereference) +/** + * Demonstrates unsafe heap allocation that can cause a null-pointer dereference and a memory leak. + * + * Allocates 50 bytes on the heap, writes to the first byte without checking whether allocation succeeded, + * and returns without freeing the allocation. This may dereference a NULL pointer and results in leaked memory. + */ void memory_issues() { char *ptr = (char *)malloc(50); @@ -21,7 +32,12 @@ void memory_issues() { return; } -// 3. 释放后使用 (Use After Free) & 双重释放 (Double Free) +/** + * Demonstrates heap corruption by performing a use-after-free followed by a double-free. + * + * Allocates a small heap buffer, frees it, then writes to the freed memory and frees it again, + * causing undefined behavior and potential heap corruption. + */ void heap_corruption() { char *data = (char *)malloc(10); free(data); @@ -33,6 +49,13 @@ void heap_corruption() { free(data); } +/** + * Demonstrates unsafe handling of a caller-provided C string that can cause a stack buffer overflow and a format-string vulnerability. + * + * Copies the contents of `user_input` into a fixed 10-byte stack buffer without bounds checking, then passes `user_input` directly as the `printf` format string. This may overflow the stack buffer, cause memory corruption, allow arbitrary memory reads/writes, or crash the program. + * + * @param user_input Null-terminated input string provided by the caller; treated as untrusted data. + */ void risky_processing(char *user_input) { char buffer[10]; @@ -45,6 +68,10 @@ void risky_processing(char *user_input) { printf(user_input); } +/** + * Program entry point that reads a line from standard input, conditionally processes a command-line argument, and invokes demonstration routines that illustrate unsafe memory and input handling. + * @returns 0 on normal termination. + */ int main(int argc, char *argv[]) { char local_buf[100]; @@ -65,4 +92,4 @@ int main(int argc, char *argv[]) { return 0; printf("This line will never run."); -} +} \ No newline at end of file