Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
尽可能安全地在c中打开文件_C_File_Error Handling_Fopen - Fatal编程技术网

尽可能安全地在c中打开文件

尽可能安全地在c中打开文件,c,file,error-handling,fopen,C,File,Error Handling,Fopen,我会写一个程序如下 int main () { FILE *fp = fopen("test.txt", "r") if (fp == NULL) { printf("Sorry, file doesn't exist."); return 0; } return 0; } 在打开文件之前或之后,是否需要进行其他检查 如果打开文件会损坏系统(病毒),该怎么办?有支票吗 如果文件不是

我会写一个程序如下

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
,但是,当处理完文件*

时,模式
r
应仅用于打开文本文件。不同的系统有不同的文本存储方式,此模式将相应地自动翻译文件。例如,DOS/Windows使用
\r\n
表示新行,类似UNIX的系统使用
\n
,MAC使用
\r
以及其他可能的区别

要按原样打开和读取文件,请在二进制安全模式下使用
rb

此模式可让您完全控制写入二进制级别的内容,是读取和写入二进制数据(如
struct
dumps、加密信息等)的唯一安全方法

打开文件后


打开文件时要小心,读、写和关闭文件时也要小心。所以,一定要检查相关电话的结果,这样做。

我发现这是一个老问题。然而:

您可以执行一些额外的安全检查,以验证您正在打开的是真实的文件,而不是符号链接

原因:用指向另一个文件的链接替换文件是已知的攻击技术之一(与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;如果不是,则返回-1*/
静态整型测试文件类型(常量字符*文件)
{
结构统计;
如果(0!=lstat(文件(&st)){
fprintf(stderr,“lstat失败,可能没有这样的文件\n”);
佩罗尔(“lstat”);
返回(-1);
}
如果(S_IFREG!=(st.st_模式和S_IFMT)){
fprintf(stderr,“打开文件[%s]时出错:不是常规文件,而是”,文件);
开关(st.st\U模式和S\U IFMT){
案例S_IFSOCK:
fprintf(stderr,“socket\n”);
打破
案例S_IFLNK:
fprintf(stderr,“符号链接”);
打破
案例S_IFBLK:
fprintf(stderr,“块设备”);
打破
案例S_IFDIR:
fprintf(stderr,“目录\n”);
打破
案例S_IFCHR:
fprintf(stderr,“字符设备”);
打破
案例S_IFFO:
fprintf(标准“先进先出”);
打破
}
返回(-1);
}
返回(0);
}
如果此函数返回<0,则该文件不是常规文件。不要打开它


另外,请阅读

@cygwinnian我想知道为什么面试官会问这样一个简单的问题——你的错误信息可能会误导人。它表示该文件不存在,即使该文件存在,但当前用户没有打开该文件的权限。更好的错误:
fprintf(stderr,“错误:无法打开%s进行读取:%s\n”、“test.txt”、strerror(errno))
。如果在发生致命错误时
main
返回一个非零值(或使用非零退出代码调用
exit
),则可以使程序更有用。如果打开文件会损坏系统(病毒),该怎么办?有支票吗?如果文件不是.txt文件,用户刚刚将mp3文件重命名为txt文件,该怎么办?如果打开文件会损坏系统(病毒),该怎么办?有支票吗?如果文件不是.txt文件,用户刚刚将mp3文件重命名为txt文件,该怎么办?如果是二进制文件,请使用
rb
打开它<代码>r
用于文本文件。我不认为在文件上使用
r
调用
fopen
会像病毒那样损坏系统。