hphp/runtime/ext/gd/ext_gd.cpp
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo,
                                    char *dir_start, char *offset_base,
                                    char *end,
                                    size_t IFDlength, size_t displacement,
                                    int section_index) {
  int de;
  int NumDirEntries;
  int NextDirOffset;

  ImageInfo->sections_found |= FOUND_IFD0;

  CHECK_BUFFER_R(dir_start, end, 2, 0);
  NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->motorola_intel);

  if ((dir_start+2+NumDirEntries*12) > (offset_base+IFDlength)) {
    raise_warning("Illegal IFD size: x%04X + 2 + x%04X*12 = x%04X > x%04lX",
                    (int)((size_t)dir_start+2-(size_t)offset_base),
                    NumDirEntries,
                   (int)((size_t)dir_start+2+
                   NumDirEntries*12-(size_t)offset_base), IFDlength);
    return 0;
  }

  for (de=0;de<NumDirEntries;de++) {
    if (!exif_process_IFD_TAG(ImageInfo, dir_start + 2 + 12 * de,
                              offset_base, end, IFDlength, displacement,
                              section_index, 1,
                              exif_get_tag_table(section_index))) {
      return 0;
    }
  }
  /*
   * Ignore IFD2 if it purportedly exists
   */
  if (section_index == SECTION_THUMBNAIL) {
    return true;
  }
  /*
   * Hack to make it process IDF1 I hope
   * There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202)
   * to the thumbnail
   */
  CHECK_BUFFER_R(dir_start+2+12*de, end, 4, 0);
  NextDirOffset =
    php_ifd_get32u(dir_start+2+12*de, ImageInfo->motorola_intel);
  if (NextDirOffset) {
    /* the next line seems false but here IFDlength means
       length of all IFDs */
    if (offset_base + NextDirOffset < offset_base ||
        offset_base + NextDirOffset > offset_base+IFDlength) {
      raise_warning("Illegal IFD offset");
      return 0;
    }
    /* That is the IFD for the first thumbnail */
    if (exif_process_IFD_in_JPEG(ImageInfo, offset_base + NextDirOffset,
                                 offset_base, end, IFDlength, displacement,
                                 SECTION_THUMBNAIL)) {
      if (ImageInfo->Thumbnail.filetype != IMAGE_FILETYPE_UNKNOWN &&
          ImageInfo->Thumbnail.size &&
          ImageInfo->Thumbnail.offset &&
          ImageInfo->read_thumbnail) {
        exif_thumbnail_extract(ImageInfo, offset_base, IFDlength);
      }
      return 1;
    } else {
      return 0;
    }
  }
  return 1;
}
/* Process one of the nested IFDs directories. */
Process one of the nested IFDs directories.
Process one of the nested IFDs directories .
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo,
                                    char *dir_start, char *offset_base,
                                    char *end,
                                    size_t IFDlength, size_t displacement,
                                    int section_index) {
  int de;
  int NumDirEntries;
  int NextDirOffset;
  ImageInfo->sections_found |= FOUND_IFD0;
  CHECK_BUFFER_R(dir_start, end, 2, 0);
  NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->motorola_intel);
  if ((dir_start+2+NumDirEntries*12) > (offset_base+IFDlength)) {
    raise_warning("Illegal IFD size: x%04X + 2 + x%04X*12 = x%04X > x%04lX",
                    (int)((size_t)dir_start+2-(size_t)offset_base),
                    NumDirEntries,
                   (int)((size_t)dir_start+2+
                   NumDirEntries*12-(size_t)offset_base), IFDlength);
    return 0;
  }
  for (de=0;de<NumDirEntries;de++) {
    if (!exif_process_IFD_TAG(ImageInfo, dir_start + 2 + 12 * de,
                              offset_base, end, IFDlength, displacement,
                              section_index, 1,
                              exif_get_tag_table(section_index))) {
      return 0;
    }
  }
  if (section_index == SECTION_THUMBNAIL) {
    return true;
  }
  CHECK_BUFFER_R(dir_start+2+12*de, end, 4, 0);
  NextDirOffset =
    php_ifd_get32u(dir_start+2+12*de, ImageInfo->motorola_intel);
  if (NextDirOffset) {
    if (offset_base + NextDirOffset < offset_base ||
        offset_base + NextDirOffset > offset_base+IFDlength) {
      raise_warning("Illegal IFD offset");
      return 0;
    }
    if (exif_process_IFD_in_JPEG(ImageInfo, offset_base + NextDirOffset,
                                 offset_base, end, IFDlength, displacement,
                                 SECTION_THUMBNAIL)) {
      if (ImageInfo->Thumbnail.filetype != IMAGE_FILETYPE_UNKNOWN &&
          ImageInfo->Thumbnail.size &&
          ImageInfo->Thumbnail.offset &&
          ImageInfo->read_thumbnail) {
        exif_thumbnail_extract(ImageInfo, offset_base, IFDlength);
      }
      return 1;
    } else {
      return 0;
    }
  }
  return 1;
}
static int exif_process_IFD_in_JPEG ( image_info_type * ImageInfo , char * dir_start , char * offset_base , char * end , size_t IFDlength , size_t displacement , int section_index ) { int de ; int NumDirEntries ; int NextDirOffset ; ImageInfo -> sections_found |= FOUND_IFD0 ; CHECK_BUFFER_R ( dir_start , end , 2 , 0 ) ; NumDirEntries = php_ifd_get16u ( dir_start , ImageInfo -> motorola_intel ) ; if ( ( dir_start + 2 + NumDirEntries * 12 ) > ( offset_base + IFDlength ) ) { raise_warning ( " " , ( int ) ( ( size_t ) dir_start + 2 - ( size_t ) offset_base ) , NumDirEntries , ( int ) ( ( size_t ) dir_start + 2 + NumDirEntries * 12 - ( size_t ) offset_base ) , IFDlength ) ; return 0 ; } for ( de = 0 ; de < NumDirEntries ; de ++ ) { if ( ! exif_process_IFD_TAG ( ImageInfo , dir_start + 2 + 12 * de , offset_base , end , IFDlength , displacement , section_index , 1 , exif_get_tag_table ( section_index ) ) ) { return 0 ; } } if ( section_index == SECTION_THUMBNAIL ) { return true ; } CHECK_BUFFER_R ( dir_start + 2 + 12 * de , end , 4 , 0 ) ; NextDirOffset = php_ifd_get32u ( dir_start + 2 + 12 * de , ImageInfo -> motorola_intel ) ; if ( NextDirOffset ) { if ( offset_base + NextDirOffset < offset_base || offset_base + NextDirOffset > offset_base + IFDlength ) { raise_warning ( " " ) ; return 0 ; } if ( exif_process_IFD_in_JPEG ( ImageInfo , offset_base + NextDirOffset , offset_base , end , IFDlength , displacement , SECTION_THUMBNAIL ) ) { if ( ImageInfo -> Thumbnail . filetype != IMAGE_FILETYPE_UNKNOWN && ImageInfo -> Thumbnail . size && ImageInfo -> Thumbnail . offset && ImageInfo -> read_thumbnail ) { exif_thumbnail_extract ( ImageInfo , offset_base , IFDlength ) ; } return 1 ; } else { return 0 ; } } return 1 ; }
Process one of the nested IFDs directories.
Process one of the nested IFDs directories .
/*
   * Ignore IFD2 if it purportedly exists
   */ /*
   * Hack to make it process IDF1 I hope
   * There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202)
   * to the thumbnail
   */ /* the next line seems false but here IFDlength means
       length of all IFDs */ /* That is the IFD for the first thumbnail */