Segfault cs50 pset4 recover - c

I'm always getting a segfault when trying to run the code.
I think it is caused by the last lines fclose(file) and fclose(img), but I don't really seem to understand why exactly.
If I delete both lines nothing happens.
Could someone please explain to me why segfault is called and why it is not creating new .jpg's?
(I have to implement a program that recovers JPEGs from a forensic image)
https://cs50.harvard.edu/college/2020/fall/psets/4/recover/
#include <stdlib.h>
#include <stdint.h>
#include <cs50.h>
int main(int argc, char *argv[])
{
//open file
FILE *file = fopen(argv[1], "r");
//promting user
if(argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
else if (file == NULL)
{
printf("Empty file.\n");
return 2;
}
int i = 0;
int found = 0;
unsigned char buffer[512];
FILE *img = NULL;
while (fread(buffer, 512, 1, file))
{
//start of new Jpeg?
if (buffer[0] == 0xff && buffer[1] == 0xff && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
//close file if found
if(found == 1)
{
fclose(img);
}
// open new one
else
{
found = 1;
}
char filename[8];
sprintf(filename, "%03i.jpg", i);
img = fopen(filename, "w");
i++;
}
if(found == 1)
{
fwrite(buffer, 512, 1, img);
}
}
fclose(file);
fclose(img);
return 0;
}

Related

Can I declare and open a file in different lines of code, like in this question I need to keep writing once my file is open

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int blocksize = 512;
int main(int argc, char *argv[])
{
if( argc != 2 )
{
printf("mention the file name or too many commands\n");
return 1;
}
FILE *in = fopen(argv[1], "r");
FILE *out;
if (in == NULL)
{
printf("could not open the file %s", argv[1]);
return 1;
}
uint8_t buffer[blocksize];
int count = 0;
int precount = 1;
int flag = 1;
while(fread(buffer, sizeof(uint8_t), 512, in) == blocksize)
{
if((buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && ((buffer[3] & 0xf0) == 0xe0)) || flag == 1)
{
if (flag == 0)
{
char filename[9];
sprintf(filename, "%03i.jpg", count);
out = fopen(filename, "w");
count++;
flag = 1;
}
if(count == precount)
{
fwrite(buffer, sizeof(uint8_t), 512, out);
}
else
{
fclose(out);
precount++;
flag = 0;
}
}
}
return 0;
}
First I am searching for headers then once I find it, I write it in the out file.
I want to keep writing until I find the required headers again and then I want to close the existing file and open a new file until I find those headers again.
Now the problem is when I declare the FILE *out inside the if statement it becomes if's local variable and if I do this the way the code here I get seg fault.

Invalid or Unsupported Image Format Recover CS50

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
// open memory card
if(argc > 2 )
{
printf("Usage: ./recover image");
return 1;
}
FILE *file = fopen(argv[1], "r");
FILE *img;
// repeat until end
int i = 0;
// 512 bytes into buffer
uint8_t buffer[2048];
char *filename = malloc(8);
// if start of new jpeg
while(fread(&buffer, 512, 4, file)) // read card
{
if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0) // if start new jpeg
{
// if first
i++;
sprintf(filename, "%03i.jpg", i);
img = fopen(filename, "w");
fwrite(&buffer, sizeof(uint8_t), 1, img); // fixed
}
//else
else
{
// if still reading jpeg
if(img != NULL)
{
fwrite(&buffer, sizeof(uint8_t), 1, img);
}
}
}
//close
free(filename);
fclose(file);
return 0;
}
I think my code is pretty close to being done but the images returned are invalid or unsupported image format. It compiles fine and it returns 12 images. I do not want to look at a solution to fix this. Where did my code mess up?

Does "if" Interrupt a "while" function?

I'm trying to solve the problem sets of CS50.
Task is, to recover jpegs from data.
My code produces jpegs, but it seems to take just one chunk of 512 bytes instead of the whole picture.
Does my "if" interrupt my "while" condition.
Here my code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
const int FAT_SIZE = 512;
typedef uint8_t FAT [FAT_SIZE];
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover card.raw\n");
return 1;
}
// Open files and determine scaling factor
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
FAT fats;
int number = 0;
char filename[8];
FILE *jpg;
// Going through the input file
while (fread(&fats, 512, 1, input))
{
if (fats[0] == 0xff && fats[1] == 0xd8 && fats[2] == 0xff && (fats[3] & 0xf0) == 0xe0)
{
if (number == 0)
{
sprintf(filename, "%03i.jpg" , 0);
jpg = fopen(filename, "w");
number++;
fwrite(&fats,512, 1, jpg);
} else {
fclose(jpg);
sprintf(filename, "%03i.jpg" , number);
number++;
jpg = fopen(filename, "w");
fwrite(&fats,512, 1, jpg);
}
}
}
fclose(input);
fclose(jpg);
return 0;
}
I found a solution , but I want to understand, why my code is wrong
I didnt write following code. It's written by JosephR , it's just for comparision.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
else
{
// Open card.raw
char *input_file_name = argv[1];
FILE *input_pointer = fopen(input_file_name, "r");
if (input_pointer == NULL)
{
printf("Error: cannot open %s\n", input_file_name);
return 2;
}
// Initialise variables
BYTE buffer[512];
int count = 0;
FILE *img_pointer = NULL;
char filename[8];
// Repeat until end of card:
while (fread(&buffer, 512, 1, input_pointer) == 1)
{
// If start of a new JPEG (0xff 0xd8 0xff 0xe*):
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
// If not first JPEG, close previous
if (!(count == 0))
{
fclose(img_pointer);
}
// Initialise file
sprintf(filename, "%03i.jpg", count);
img_pointer = fopen(filename, "w");
count++;
}
// If JPEG has been found, write to file
if (!(count == 0))
{
fwrite(&buffer, 512, 1, img_pointer);
}
}
fclose(input_pointer);
fclose(img_pointer);
return 0;
}
}

Segmentation Fault in CS50 recover

I have been trying to find out what is the issue with my code for hours. I referred to other people's code but I still don't know what's wrong. The code compiles fine but the debugger says that the segmentation fault occurs at line 44 (below the comment). Suggestions to improve my code are welcome too. Please help and thank you.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
FILE *f = fopen(argv[1],"r");
if (!f)
{
return 2;
}
BYTE buffer[512];
FILE* img = NULL;
int i = 0;
while (fread(buffer, 512, 1, f) == 1)
{
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff
&& (buffer[3] & 0xf0) == 0xe0)
{
//create jpeg
char filename[8];
if (img != NULL)
{
fclose(img);
i++;
sprintf(filename, "%03i.jpg",i);
img = fopen(filename, "w");
fwrite(buffer, 512 , 1, img);
}
else
{
sprintf(filename, "%03i.jpg",i);
img = fopen(filename, "w");
//error in the line below :(
fwrite(buffer, 512 , 1, img);
}
}
else if (i > 0)
{
fwrite(buffer, 512 , 1, img);
}
}
fclose(img);
fclose(f);
}
It looks like the most likely failure reason for that line you call out, is that the file handle could be invalid. Hence the first thing I would be doing is checking that every file opens correctly, something like:
img = fopen(filename, "w");
if (img == NULL) {
printf("Error opening file '%s'\n", filename);
exit(1);
}
It's generally a good idea to check for failure conditions in functions than can fail, and this also includes the fwrite calls:
if (fwrite(buffer, 512 , 1, img) != 1) {
printf("Error writing to file\n");
exit(1);
}

Pset4 recover fails check50 test

I'm struggling with the CS50 course pset4 "recover". The code works, but when I test it (check50), it shows two errors:
:( recovers middle files correctly
:( recovers last file correctly
Here's the sandbox.
Could anyone help me with it, please? :)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define BLOCK 512
typedef uint8_t BYTE;
int main(int argc, char* argv[])
{
if(argc !=2)
{
fprintf(stderr, "Usage: ./copy infile\n");
return 1;
}
char* infile = argv[1];
FILE* card = fopen(infile, "r");
if(card == NULL)
{
fprintf(stderr, "Couldn't open %s!\n", infile);
return 2;
}
FILE* img = NULL;
int counter = 0;
char image[8];
BYTE data[BLOCK];
//checking if the end of the card is reached
while(fread(&data, sizeof(BLOCK), 1, card) !=0)
{
//checking if it's a new jpeg
if(data[0] == 0xff && data[1] == 0xd8 && data[2] == 0xff && (data[3] & 0xf0)==0xe0)
{
//if it's not the first new jpeg, close the previous
if(img !=NULL)
{
fclose(img);
}
sprintf(image, "%03i.jpg", counter);
img = fopen(image, "w");
if(img == NULL)
{
fprintf(stderr, "Couldn't open %s!\n", image);
fclose(card);
return 3;
}
counter++;
}
if(img !=NULL)
{
fwrite(&data, sizeof(BLOCK), 1, img);
}
}
fclose(img);
fclose(card);
return 0;
}

Resources