Search code examples
cpdfmupdffile-copying

Improper PDF file copy using C


I have written a code in C wherein I copy the contents of PDF file from one location to other for further processing. What I did is:

Open the file in binary read mode

if ((fp = fopen(argv[6],"rb")) == 0) {
        fprintf(stderr, "ERROR: Can't open input file %s\n",argv[6]);
        goto out;
}

Then I save the contents of the PDF file to a temporary location

/* save the contents for the file to a temporary location */
  tempfp = fopen(CUPS_IPTEMPFILE, "wb");
  while ((n = fread(buf, 1, BUFSIZ, fp)) > 0) {
    count = fwrite(buf, 1, BUFSIZ, tempfp);
  }
  fclose(tempfp);

I am using MuPDF to open the file; although MuPDF is able to display the file correctly, it gives the following error on the terminal:

$ mupdf cupsiptempfile.pdf 
error: cannot find startxref
warning: trying to repair broken xref

If I use Okular to display the same file, I DO NOT get any error

$ okular cupsiptempfile.pdf
okular(12821)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(12821)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(12821)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(12821)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:
okular(12821)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig:

Why there is difference here ? Am I doing something wrong with the copying part ?

Additional Info: When I open the original PDF file using MuPDF, it gives NO error.

Please feel free to ask any further information you want.


Solution

  • The problem is here:

    while ((n = fread(buf, 1, BUFSIZ, fp)) > 0) {
      count = fwrite(buf, 1, BUFSIZ, tempfp);
    }
    

    When you copy the file you write BUFSIZ characters out but you might not have read BUFSIZ characters in - the variable n is there to tell you how many characters were read so you should only write those n characters back out. It should probably look like this:

    while ((n = fread(buf, 1, BUFSIZ, fp)) > 0) {
      count = fwrite(buf, 1, n, tempfp);
    }