nothings / stb

stb single-file public domain libraries for C/C++

Home Page:https://twitter.com/nothings

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

stb_image: loading of an invalid JPEG image succeeds

Jerry-G opened this issue · comments

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;
}