Question

I would write a program as follows

int main ()
{
      FILE *fp = fopen("test.txt", "r")

      if (fp == NULL)
      {
           printf("Sorry, file doesn't exist.");
           return 0;     
      }

   return 0;
} 

Is there any other check that I would need to make sure before or after opening a file?

What if the opening of a file can damage the system(virus)? is there any check for that?

What if the file is not a .txt file, user just renamed mp3 file to a txt file?

Was it helpful?

Solution

No other check needed.

I always also make it a practice of calling fclose, however, when done with the FILE*.

OTHER TIPS

The mode r should be used to open text files only. Different systems have different ways of storing text, and this mode will automatically translate the file accordingly. For instance, DOS/Windows use \r\n to represent new lines, UNIX-like systems use \n, and MAC uses \r among other possible differences.

To open and read a file truly as it is, in binary-safe mode, you should use rb.

This mode gives you full control of what you're writing to binary level, and is the only safe way to read and write binary data such as struct dumps, encrypted information etc.

after opening a file

As careful as you are when opening the file, you should as well be when reading, writing and closing it. So always check the outcome of the calls involved to do so.

I see it is an old question. However:

You may do some additional security checks to validate you are opening a real file, not a symbolic link.

Reason: replacing file by a link to another file is one of the known attack technics (related to CWE-362). The file can be replaced by a link pointing to an engineered file containing a sequence that should hack/crash your application instead of the expected file.

So, the best practice is to add code like this:

   #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);
    }

If this function return < 0, the file is not a regular file. Don't open it.

Also, read here

you might prefer using fopen_s. fopen_s is a newer variant of fopen that has a parameter for validation and hands back an error code instead of a pointer for the case if something goes wrong during the open process. It is safer than the base variant because it accounts for more edge conditions.

I hope you find it helpful!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top