我将写一个程序如下
int main ()
{
FILE *fp = fopen("test.txt", "r")
if (fp == NULL)
{
printf("Sorry, file doesn't exist.");
return 0;
}
return 0;
}
在打开文件之前或之后,有什么其他需要确认的检查吗?
如果打开文件会损坏系统(病毒),有什么检查方法吗?
如果文件不是一个.txt文件,用户只是把mp3文件改名为txt文件,怎么办?
不需要其他检查。
我也总是在实践中调用 fclose
然而,当完成FILE*。
模式 r
应仅用于打开文本文件。不同的系统有不同的文本存储方式,这种模式会自动对文件进行相应的翻译。例如,DOSWindows使用 \r\n
来表示新行,类UNIX系统使用 \n
,MAC使用 \r
在其他可能的差异中。
要想真正如实地打开和读取一个文件,在 二进制安全模式,你应该使用 rb
.
这种模式可以让你完全控制你要写到二进制级别的东西,是唯一安全的读写二进制数据的方式,如 struct
转储、加密信息等。
打开文件后
正如你在打开文件时的小心翼翼一样,你在读写和关闭文件时也应该如此。所以一定要检查涉及到的调用结果才行。
我看这是个老问题。不过。
你可以做一些额外的安全检查 来验证你打开的是一个真正的文件,而不是一个符号链接。
原因:用指向另一个文件的链接替换文件是已知的攻击技术之一(与CWE-362有关).文件可以被指向一个包含序列的工程文件的链接替换,该序列应该黑客崩溃你的应用程序,而不是预期的文件。
所以,最好的做法是添加这样的代码。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/* Return: 0 if file is a regular file, -1 if not */
static int test_file_type(const char *file)
{
struct stat st;
if (0 != lstat(file, &st)) {
fprintf(stderr, "lstat failed, probably no such a file\n");
perror("lstat");
return (-1);
}
if (S_IFREG != (st.st_mode & S_IFMT)) {
fprintf(stderr, "Error on file [%s] opening: not a regular file, but ", file);
switch (st.st_mode & S_IFMT) {
case S_IFSOCK:
fprintf(stderr, "socket\n");
break;
case S_IFLNK:
fprintf(stderr, "symbolic link\n");
break;
case S_IFBLK:
fprintf(stderr, "block device\n");
break;
case S_IFDIR:
fprintf(stderr, "directory\n");
break;
case S_IFCHR:
fprintf(stderr, "character device\n");
break;
case S_IFIFO:
fprintf(stderr, "FIFO\n");
break;
}
return (-1);
}
return (0);
}
如果这个函数返回< 0, 这个文件就不是一个常规文件. 不要打开它。
另外,请阅读 此处