0

My "recovery" programm works - all 50 jpg files are recovered and pictures are visible. The programm terminates with returned 0. But as I run check50 it tells ":( recovers 000.jpg correctly - failed to execute program due to segmentation fault".

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint8_t  BYTE;

int main(int argc, char *argv[])
{
    FILE *inptr = fopen(argv[1], "r"); // open source file

    // block for storing the read chunk of 512 bytes
    BYTE *block_ptr = malloc(512);

    char jpgName[4]; // array for 3 symbols with trailing 0
    FILE *img = NULL;
    int fileCounter = 0;
    int jpgOpen = 0; // shows if there is a jpg in process, 1 - yes, 0 - no

    // reads blocks while fread function returns 1 -
    // amount of succefully read blocks
    while (fread(block_ptr, 512, 1, inptr) == 1)

    {
        // check if start of jpg is found ("signature")
        if (block_ptr[0] == 0xff && block_ptr[1] == 0xd8 &&
            block_ptr[2] == 0xff && (block_ptr[3] & 0xf0) == 0xe0)
        {
            // check if this is the 1st jpg or the previous
            // should be closed before creating a new one
            if (jpgOpen == 0)
            {
                jpgOpen = 1;
            }
            else
            {
                fclose(img);
            }

            // give a name and write the 1st block
            sprintf(jpgName, "%03i.jpg", fileCounter);
            fileCounter++;
            img = fopen(jpgName, "w");
            fwrite(block_ptr, 512, 1, img);
        }

        else // block does not contain jpg header
        {
            // if there is a jpg in process - write the block to files
            if (jpgOpen == 1)
            {
                fwrite(block_ptr, 512, 1, img);
            }
        }
    }

    fclose(img);
    return 0;
}
1

The problem is due to a data overwrite bug. The problem lies in these two lines:

char jpgName[4]; // array for 3 symbols with trailing 0
....
        // give a name and write the 1st block
        sprintf(jpgName, "%03i.jpg", fileCounter);

The full file name is 8 chars long (7 for the name and 1 for the \0) and is written to jpgName. Since only 4 chars were allocated to jpgName, the next 4 chars will overwrite whatever is stored in memory immediately following the allocated space. The next item in memory is block_ptr, so the address in this pointer gets corrupted and the results become unpredictable.

Depending on the system and its usage the results can be a seg fault, corrupt data, or other unpredictable results.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

| improve this answer | |
  • Thank you very much! In addition I also added free(block_ptr) and then it works fine! – RomanBlade Sep 3 '18 at 22:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .