stb_image: loading of an invalid JPEG image succeeds
Jerry-G opened this issue · comments
Jerry commented
With the following malformed JPEG file
$ xxd input.jpg
00000000: ffd8 ffe0 0010 4a46 4946 0001 0100 0001 ......JFIF......
00000010: 0001 0000 ffdb 0043 0001 0101 0101 0101 .......C........
00000020: 0101 0101 0101 0101 0101 0101 0101 0101 ................
00000030: 0101 0101 0101 0101 0101 0101 0101 0101 ................
00000040: 0101 0101 0101 0101 0101 0101 0101 0101 ................
00000050: 0101 0101 0101 0101 01ff db00 4301 0101 ............C...
00000060: 0101 0101 0101 0101 0101 0101 0101 0101 ................
00000070: 0101 0101 0101 0101 0101 0101 0101 0101 ................
00000080: 0101 0101 0101 0101 0101 0101 0101 0101 ................
00000090: 0101 0101 0101 0101 0101 0101 0101 ffc0 ................
000000a0: 0011 0805 c802 d003 0122 0002 1101 0311 ........."......
000000b0: 01
stbi_load
returns a width of 720, a height of 1480, channels of 3.
For reference libjpeg
provides the following output when given the same file.
Premature end of JPEG file
Invalid JPEG file structure: missing SOS marker
Versions:
stb_image v2.29
libjpeg-turbo 3.0.2
Code used:
/* compiled with
* gcc stbi_test.c -lm
* */
#include <stdio.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
int main(int argc, char** argv){
char* file_name;
int width, height, channels;
if(argc < 2){
printf("no input\n");
return 0;
}
unsigned char *img = stbi_load(argv[1], &width, &height, &channels, 0);
printf("width : %d\n", width);
printf("height: %d\n", height);
printf("channs: %d\n", channels);
return 0;
}
/* compiled with
* gcc libjpeg_test.c -ljpeg
* */
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <jpeglib.h>
#include <jerror.h>
int main(int argc, char** argv){
if(argc < 2){
printf("no input\n");
return 0;
}
char* lpFilename = argv[1];
struct jpeg_decompress_struct info;
struct jpeg_error_mgr err;
unsigned long int imgWidth, imgHeight;
int numComponents;
unsigned long int dwBufferBytes;
unsigned char* lpData;
unsigned char* lpRowBuffer[1];
FILE* fHandle;
fHandle = fopen(lpFilename, "rb");
if(fHandle == NULL) {
fprintf(stderr, "%s:%u: Failed to read file %s\n", __FILE__, __LINE__, lpFilename);
return 1;
}
info.err = jpeg_std_error(&err);
jpeg_create_decompress(&info);
jpeg_stdio_src(&info, fHandle);
jpeg_read_header(&info, TRUE);
jpeg_start_decompress(&info);
imgWidth = info.output_width;
imgHeight = info.output_height;
numComponents = info.num_components;
fprintf(
stderr,
"%s:%u: Reading JPEG with dimensions %lu x %lu and %u components\n",
__FILE__, __LINE__,
imgWidth, imgHeight, numComponents
);
jpeg_finish_decompress(&info);
jpeg_destroy_decompress(&info);
fclose(fHandle);
return 0;
}