C 语言中的危险函数

 

最危险:

gets 使用 fgets(buf, size, stdin)。这几乎总是一个大问题!


很危险:

strcpy 改为使用 strncpy。

strcat 改为使用 strncat。

sprintf 改为使用 snprintf,或者使用精度说明符。

scanf 使用精度说明符,或自己进行解析。

sscanf 使用精度说明符,或自己进行解析。

fscanf 使用精度说明符,或自己进行解析。

vfscanf 使用精度说明符,或自己进行解析。

vsprintf 改为使用 vsnprintf,或者使用精度说明符。

vscanf 使用精度说明符,或自己进行解析。

vsscanf 使用精度说明符,或自己进行解析。

streadd 确保分配的目的地参数大小是源参数大小的四倍。

strecpy 确保分配的目的地参数大小是源参数大小的四倍。


很危险(或稍小,取决于实现):

realpath 分配缓冲区大小为 MAXPATHLEN。同样,手工检查参数以确保输入参数不超过 MAXPATHLEN。

syslog 在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。

getopt 在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。

getopt_long 在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。

getpass 在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。


危险:

strtrns 手工检查来查看目的地大小是否至少与源字符串相等。


中等危险:

getchar   如果在循环中使用该函数,确保检查缓冲区边界。

fgetc 如果在循环中使用该函数,确保检查缓冲区边界。

getc 如果在循环中使用该函数,确保检查缓冲区边界。

read 如果在循环中使用该函数,确保检查缓冲区边界。


低危险:

bcopy 确保缓冲区大小与它所说的一样大。

fgets 确保缓冲区大小与它所说的一样大。

memcpy 确保缓冲区大小与它所说的一样大。

snprintf 确保缓冲区大小与它所说的一样大。

strccpy 确保缓冲区大小与它所说的一样大。

strcadd 确保缓冲区大小与它所说的一样大。

strncpy 确保缓冲区大小与它所说的一样大。

vsnprintf 确保缓冲区大小与它所说的一样大。

在 C 语言中,`system` 函数是一个标准库函数,定义在 `<stdlib.h>` 头文件中,用于在程序中执行操作系统命令。它的作用是调用操作系统的命令解释器(如 Windows 的 `cmd.exe` 或 Linux/Unix 的 `/bin/sh`),并执行传入的字符串所表示的命令。 ### 函数原型: ```c int system(const char *command); ``` - **参数**:`command` 是一个指向字符串的指针,表示要执行的系统命令。 - **返回值**: - 如果 `command` 不为 `NULL`,返回值依赖于系统实现,通常表示命令执行的结果状态。 - 如果 `command` 为 `NULL`,则判断系统是否支持命令处理器,若支持返回非零值,否则返回 0。 - 在 Windows 和 Linux 中,如果命令执行成功,通常返回 `0`;失败可能返回非零值(具体含义与系统有关)。 --- ### 示例代码 ```c #include <stdio.h> #include <stdlib.h> int main() { int result; // 检查系统是否支持命令处理器 if (system(NULL)) { printf("系统支持命令处理器。\n"); } else { printf("系统不支持命令处理器。\n"); return 1; } // 执行系统命令:在 Windows 中列出目录,在 Linux 中使用 ls #ifdef _WIN32 result = system("dir"); #else result = system("ls -l"); #endif if (result == 0) { printf("命令执行成功。\n"); } else { printf("命令执行失败。\n"); } return 0; } ``` --- ### 代码解释: 1. `#include <stdlib.h>`:必须包含此头文件才能使用 `system` 函数。 2. `system(NULL)`:用来检测系统是否具备可用的命令处理器,是一种可移植性检查。 3. `system("dir")` 或 `system("ls -l")`:分别在 Windows 和类 Unix 系统中列出当前目录内容。 4. `result` 接收返回值,可用于判断命令是否成功执行(但具体含义依赖平台)。 --- ### 注意事项: - **安全性问题**:使用 `system` 执行命令时,如果命令字符串来自用户输入,容易引发**命令注入**漏洞。例如: ```c char cmd[100]; sprintf(cmd, "echo %s", user_input); // 若 user_input 是 "hello && rm -rf /" system(cmd); // 危险! ``` 应尽量避免拼接不可信输入。 - **可移植性差**:不同操作系统命令不同(如 `dir` vs `ls`),影响跨平台运行。 - **性能开销大**:每次调用 `system` 都会启动一个新的 shell 进程,效率较低。 - **替代方案**: - 使用操作系统提供的原生 API(如 `fork()` + `exec()` 在 Linux,或 `CreateProcess` 在 Windows)更安全高效。 --- ### 常见用途举例: | 目的 | 示例代码 | |--------------------|-------------------------------| | 清屏 | `system("cls");` (Windows)<br>`system("clear");` (Linux) | | 延时 | `system("sleep 5");` (Linux)<br>`system("timeout 5");` (Windows) | | 创建目录 | `system("mkdir new_folder");` | | 打开网页(Linux) | `system("xdg-open https://www.example.com");` | --- ### 总结 `system` 函数提供了一种简单方式从 C 程序中调用外部命令,适合小型工具或教学示例,但在生产环境中应谨慎使用,优先考虑更安全、高效的替代方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值