0

my code for pset4 recovery only detects one jpeg signature.

Here's my code:

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

typedef uint8_t Byte;

bool check_jpeg(Byte *identity_bytes);

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }
    FILE *infile = fopen(argv[1], "r");
    if (infile == NULL)
    {
        printf("Could not open %s.\n", argv[1]);
    }
    do
    {
        Byte *bytes = calloc(512, sizeof(char));
        Byte *identity_bytes = calloc(4, sizeof(char));
        // Read first 512B block into the buffer.
        fread(bytes, sizeof(char), 512, infile);
        // Copy first 4 bytes for signature check.
        memcpy(identity_bytes, bytes, sizeof(int));
        // To make file if signature found
        if(check_jpeg(identity_bytes))
        {
            int filename = 0;
            char *outname = malloc(36);
            sprintf(outname, "%03d.txt", filename);
            FILE *outfile = fopen(outname, "w");
            // makefile(bytes, infile, outname);
            filename++;
            fclose(outfile);
            free(outname);
        }
        free(bytes);
        free(identity_bytes);
    } while (!feof(infile));
    fclose(infile);
}

// To find jpeg in given image.
bool check_jpeg(Byte *identity_bytes)
{
    Byte check[3] = {0xff, 0xd8, 0xff};
    for (int i = 0; i < 3; i++)
    {
        if (identity_bytes[i] != check[i])
        {
            return false;
        }
    }
    Byte check_4 = 0xe0;
    for (int i = 0; i < 16; i++)
    {
        if (identity_bytes[3] == check_4)
        {
            return true;
        }
        check_4++;
    }
    return false;
}

I haven't written the code for actually making jpegs yet because i wanted to test if its able to verify jpeg signatures first but it is only able to find one. Ive tried using debug50 and i cant seem to figure out where i went wrong.

Thanks for your help :)

1

The code is detecting all the file signatures. The problem is that although filename is being incremented, it is being reset to 0 inside the do loop.

Try creating and initializing filename before the start of the do/while loop.

Also, perhaps a different var name would be appropriate, like filecount?

| improve this answer | |
  • Thank you, that solved it. Also, its not a substantial doubt, but could you elaborate on what would change if in the line Byte *bytes = calloc(512, sizeof(char)); i make it int *bytes instead. – Akarsh Jun 12 at 1:26
  • Well, it would change bytes to a pointer that points at integers. Remember, an int is 8 bytes, not 1. The calloc would allocate 512 bytes to the pointer. That's room for 32 integers. Would having only 32 integers cause problems storing 512 bytes? That could wreak havoc on how the raw data is stored and retrieved. Ask yourself this. Would it store 1 byte from a read into each 8 bytes allocated? or would it store 8 bytes? Does it do anything unexpected, like reversing the order of the bytes stored in each int? How would storing data in a type that uses two's compliment to store signed ints? – Cliff B Jun 12 at 1:43
  • Bottom line is this - when trying to store and work with raw data, it's best to use a single byte unsigned type, like uint8_t or a byte. – Cliff B Jun 12 at 1:44

You must log in to answer this question.

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