-support for out of section data

This commit is contained in:
Marcus Boerger 2002-03-08 20:56:44 +00:00
parent 58a52f93bc
commit 42e478c7aa

View File

@ -142,6 +142,15 @@ static size_t php_strnlen( char* str, size_t maxlen) {
}
/* }}} */
/* {{{ error messages
*/
static const char* EXIF_ERROR_EALLOC = "Cannot allocate memory for all data";
static const char* EXIF_ERROR_FILEEOF = "Unexpected end of file reached";
#define EXIF_ERRLOG_EALLOC php_error(E_ERROR,EXIF_ERROR_EALLOC);
#define EXIF_ERRLOG_FILEEOF php_error(E_WARNING,EXIF_ERROR_FILEEOF);
/* }}} */
/* {{{ format description defines
Describes format descriptor
*/
@ -691,7 +700,7 @@ static char *exif_get_sectionlist(int sectionlist)
for(i=0; i<SECTION_COUNT; i++) len += strlen(exif_get_sectionname(i))+2;
sections = emalloc(len+1);
if ( !sections) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return NULL;
}
sections[0] = '\0';
@ -722,6 +731,7 @@ typedef struct {
/* EXIF standard defines Copyright as "<Photographer> [ '\0' <Editor> ] ['\0']" */
/* This structure is used to store a section of a Jpeg file. */
typedef struct {
FILE *infile;
char *FileName;
time_t FileDateTime;
size_t FileSize;
@ -770,7 +780,7 @@ void exif_iif_add_value( image_info_type *image_info, int section_index, char *n
list = erealloc(image_info->info_list[section_index].list,(image_info->info_list[section_index].count+1)*sizeof(image_info_data));
if ( !list) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return;
}
image_info->info_list[section_index].list = list;
@ -781,7 +791,7 @@ void exif_iif_add_value( image_info_type *image_info, int section_index, char *n
info_data->length = length;
info_data->name = emalloc(strlen(name)+1);
if ( !info_data->name) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return;
}
info_value = &info_data->value;
@ -793,7 +803,7 @@ void exif_iif_add_value( image_info_type *image_info, int section_index, char *n
info_data->length = length;
info_value->s = emalloc(length+1);
if ( !info_value->s) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return;
}
strcpy(info_value->s,value);
@ -824,7 +834,7 @@ void exif_iif_add_value( image_info_type *image_info, int section_index, char *n
case TAG_FMT_UNDEFINED:
info_value->s = emalloc(length+1);
if ( !info_value->s) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return;
}
memcpy(info_value->s,value,length);
@ -845,7 +855,7 @@ void exif_iif_add_value( image_info_type *image_info, int section_index, char *n
if ( length>1) {
info_data->value.list = emalloc(length*sizeof(image_info_value));
if ( !info_data->value.list) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return;
}
info_value = &info_data->value.list[0];
@ -911,13 +921,12 @@ void exif_iif_add_tag( image_info_type *image_info, int section_index, char *nam
*/
void exif_iif_add_int( image_info_type *image_info, int section_index, char *name, int value)
{
int index;
image_info_data *info_data;
image_info_data *list;
list = erealloc(image_info->info_list[section_index].list,(image_info->info_list[section_index].count+1)*sizeof(image_info_data));
if ( !list) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return;
}
image_info->info_list[section_index].list = list;
@ -928,7 +937,7 @@ void exif_iif_add_int( image_info_type *image_info, int section_index, char *nam
info_data->length = 1;
info_data->name = emalloc(strlen(name)+1);
if ( !info_data->name) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return;
}
strcpy(info_data->name, name);
@ -1241,7 +1250,7 @@ static void exif_process_SOFn (image_info_type *ImageInfo, uchar *Data, int mark
}
/* }}} */
static void exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *DirStart, char *OffsetBase, unsigned IFDlength, int sub_section_index);
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *DirStart, char *OffsetBase, unsigned IFDlength, int sub_section_index);
/* {{{ exif_get_markername
Get name of marker */
@ -1334,7 +1343,7 @@ static void exif_extract_thumbnail(image_info_type *ImageInfo, char *offset, uns
}
ImageInfo->Thumbnail = emalloc(ImageInfo->ThumbnailSize);
if (!ImageInfo->Thumbnail) {
php_error(E_ERROR, "Could not allocate memory for thumbnail");
EXIF_ERRLOG_EALLOC
return;
} else {
/* Check to make sure we are not going to go past the ExifLength */
@ -1351,6 +1360,7 @@ static void exif_extract_thumbnail(image_info_type *ImageInfo, char *offset, uns
/* {{{ exif_process_string_raw
* Copy a string in Exif header to a character string returns length of allocated buffer if any. */
#ifdef EXIF_DEBUG
static int exif_process_string_raw(char **result,char *value,size_t byte_count) {
/* we cannot use strlcpy - here the problem is that we have to copy NUL
* chars up to byte_count, we also have to add a single NUL character to
@ -1359,7 +1369,7 @@ static int exif_process_string_raw(char **result,char *value,size_t byte_count)
if (byte_count) {
(*result) = emalloc(byte_count+1);
if ( !*result) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return 0;
}
memcpy(*result, value, byte_count);
@ -1368,6 +1378,7 @@ static int exif_process_string_raw(char **result,char *value,size_t byte_count)
}
return 0;
}
#endif
/* }}} */
/* {{{ exif_process_string
@ -1382,7 +1393,7 @@ static int exif_process_string(char **result,char *value,size_t byte_count) {
if ((byte_count=php_strnlen(value,byte_count)) > 0) {
(*result) = emalloc(byte_count+1);
if ( !*result) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return 0;
}
memcpy(*result, value, byte_count);
@ -1417,7 +1428,7 @@ static int exif_process_user_comment(char **pszInfoPtr,char *szEncoding,char *sz
if (l>1) {
*pszInfoPtr = emalloc(l+1);
if ( !*pszInfoPtr) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return 0;
}
wcstombs(*pszInfoPtr, (wchar_t*)(szValuePtr), l+1);
@ -1476,12 +1487,12 @@ static unsigned char* exif_char_dump( unsigned char * addr, int len)
/* {{{ exif_process_IFD_TAG
* Process one of the nested IFDs directories. */
static void exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, int section_index, int ReadNextIFD)
static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, int section_index, int ReadNextIFD)
{
int l;
int l, outside=0;
int tag, format, components;
char *value_ptr, tagname[64];
size_t byte_count, offset_val;
char *value_ptr, tagname[64], cbuf[32];
size_t byte_count, offset_val, fpos, fgot;
tag = php_ifd_get16u(dir_entry, ImageInfo->motorola_intel);
format = php_ifd_get16u(dir_entry+2, ImageInfo->motorola_intel);
@ -1490,7 +1501,7 @@ static void exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, ch
if ((format-1) >= NUM_FORMATS) {
/* (-1) catches illegal zero case as unsigned underflows to positive large. */
php_error(E_WARNING, "Illegal format code in IFD");
return;
return TRUE;
}
byte_count = components * php_tiff_bytes_per_format[format];
@ -1501,16 +1512,53 @@ static void exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, ch
value_ptr = offset_base+offset_val;
/*php_error(E_WARNING, "DE: x%08X, OB: x%08X, VP: x%08X, %s", dir_entry, offset_base, value_ptr, value_ptr<dir_entry?"error":"o.k.");*/
if (offset_val+byte_count > IFDlength || value_ptr < dir_entry) {
if (value_ptr < dir_entry) {
/* we can read this if offset_val > 0 */
/* some files have their values in other parts of the file */
php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X < x%04X)", tag, exif_get_tagname(tag,tagname,-13), offset_val, dir_entry);
} else {
/* this is for sure not allowed */
/* exception are IFD pointers */
php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X + x%04X = x%04X > x%04X)", tag, exif_get_tagname(tag,tagname,-13), offset_val, byte_count, offset_val+byte_count, IFDlength);
// It is important to check for IMAGE_FILETYPE_TIFF
// JPEG does not use absolute pointers instead its pointers are relative to the start
// of the TIFF header in APP1 section.
if (offset_val<0 || offset_val+byte_count>ImageInfo->FileSize || ImageInfo->FileType!=IMAGE_FILETYPE_TIFF) {
if (value_ptr < dir_entry) {
/* we can read this if offset_val > 0 */
/* some files have their values in other parts of the file */
php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X < x%04X)", tag, exif_get_tagname(tag,tagname,-13), offset_val, dir_entry);
} else {
/* this is for sure not allowed */
/* exception are IFD pointers */
php_error(E_WARNING, "process tag(x%04X=%s): Illegal pointer offset(x%04X + x%04X = x%04X > x%04X)", tag, exif_get_tagname(tag,tagname,-13), offset_val, byte_count, offset_val+byte_count, IFDlength);
}
return TRUE;
}
return;
if ( byte_count>sizeof(cbuf)) {
// mark as outside range and get buffer
outside = 1;
value_ptr = emalloc(byte_count);
if ( !value_ptr) {
EXIF_ERRLOG_EALLOC
return FALSE;
}
} else {
// in most cases we only access a small range so
// it is faster to use a static buffer there
// BUT it offers also th epossibility to have
// pointers read without the need to free them
// explicitley before returning.
value_ptr = cbuf;
}
fpos = ftell(ImageInfo->infile);
fseek(ImageInfo->infile, offset_val, SEEK_SET);
fgot = ftell(ImageInfo->infile);
if ( fgot!=offset_val) {
efree( value_ptr);
php_error(E_WARNING,"Wrong file pointer: 0x%08X != 0x08X", fgot, offset_val);
return FALSE;
}
fgot = fread(value_ptr, 1, byte_count, ImageInfo->infile);
fseek(ImageInfo->infile, fpos, SEEK_SET);
if ( fgot<byte_count) {
efree( value_ptr);
EXIF_ERRLOG_FILEEOF
return FALSE;
}
php_error(E_NOTICE,"Read %d bytes outside @ 0x%08X", byte_count, offset_val);
}
} else {
/* 4 bytes or less and value is in the dir entry itself */
@ -1527,7 +1575,7 @@ static void exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, ch
case TAG_JPEG_INTERCHANGE_FORMAT:
/* accept both formats */
ImageInfo->ThumbnailOffset = (int)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
return;
break;
case TAG_JPEG_INTERCHANGE_FORMAT_LEN:
ImageInfo->ThumbnailSize = (int)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
@ -1655,27 +1703,31 @@ static void exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, ch
SubdirStart = offset_base + php_ifd_get32u(value_ptr, ImageInfo->motorola_intel);
if (SubdirStart < offset_base || SubdirStart > offset_base+IFDlength) {
php_error(E_WARNING, "Illegal IFD Pointer");
return;
return FALSE;
}
exif_process_IFD_in_JPEG(ImageInfo, SubdirStart, offset_base, IFDlength, sub_section_index);
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"subsection %s done", exif_get_sectionname(sub_section_index));
#endif
return;
}
return;
}
}
/* correctly would be to set components as length
* but we are ignoring length for those types where it is not the same as byte_count
*/
exif_iif_add_tag( ImageInfo, section_index, exif_get_tagname(tag,tagname,sizeof(tagname)), tag, format, components, value_ptr);
if (outside) {
efree(value_ptr);
php_error(E_NOTICE,"Read %d bytes outside @ 0x%08X", byte_count, offset_val);
}
php_error(E_NOTICE,"processt tag_done");
return TRUE;
}
/* }}} */
/* {{{ exif_process_IFD_in_JPEG
* Process one of the nested IFDs directories. */
static void exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *DirStart, char *OffsetBase, unsigned IFDlength, int section_index)
static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *DirStart, char *OffsetBase, unsigned IFDlength, int section_index)
{
int de;
int NumDirEntries;
@ -1695,7 +1747,9 @@ static void exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *DirStart,
}
for (de=0;de<NumDirEntries;de++) {
exif_process_IFD_TAG(ImageInfo,DirStart+2+12*de,OffsetBase,IFDlength,section_index,1);
if ( !exif_process_IFD_TAG(ImageInfo,DirStart+2+12*de,OffsetBase,IFDlength,section_index,1)) {
return FALSE;
}
}
/*
* Hack to make it process IDF1 I hope
@ -1712,7 +1766,7 @@ static void exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *DirStart,
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"expect next IFD to be thumbnail");
#endif
exif_process_IFD_in_JPEG(ImageInfo, OffsetBase + NextDirOffset, OffsetBase, IFDlength, SECTION_THUMBNAIL);
return exif_process_IFD_in_JPEG(ImageInfo, OffsetBase + NextDirOffset, OffsetBase, IFDlength, SECTION_THUMBNAIL);
}
}
/* }}} */
@ -1795,7 +1849,7 @@ static void exif_process_APP12(image_info_type *ImageInfo, char *buffer, unsigne
/* {{{ exif_scan_JPEG_header
* Parse the marker stream until SOS or EOI is seen; */
static int exif_scan_JPEG_header(image_info_type *ImageInfo, FILE *infile)
static int exif_scan_JPEG_header(image_info_type *ImageInfo)
{
int a;
@ -1809,16 +1863,16 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo, FILE *infile)
#endif
#ifdef EXIF_DEBUG
fpos = ftell(infile);
fpos = ftell(ImageInfo->infile);
php_error(E_NOTICE,"needing section %d @ 0x%04X", ImageInfo->sections_count, fpos);
#endif
for (a=0;a<7;a++) {
marker = fgetc(infile);
marker = fgetc(ImageInfo->infile);
if (marker != 0xff) break;
}
#ifdef EXIF_DEBUG
fpos = ftell(infile);
fpos = ftell(ImageInfo->infile);
#endif
if (marker == 0xff) {
/* 0xff is legal padding, but if we get that many, something's wrong. */
@ -1829,8 +1883,8 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo, FILE *infile)
ImageInfo->sections[ImageInfo->sections_count].Type = marker;
/* Read the length of the section. */
lh = fgetc(infile);
ll = fgetc(infile);
lh = fgetc(ImageInfo->infile);
ll = fgetc(ImageInfo->infile);
itemlen = (lh << 8) | ll;
@ -1843,7 +1897,7 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo, FILE *infile)
Data = (uchar *)emalloc(itemlen+1); /* Add 1 to allow sticking a 0 at the end. */
if ( !Data) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return FALSE;
}
ImageInfo->sections[ImageInfo->sections_count].Data = Data;
@ -1852,7 +1906,7 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo, FILE *infile)
Data[0] = (uchar)lh;
Data[1] = (uchar)ll;
got = fread(Data+2, 1, itemlen-2, infile); /* Read the whole section. */
got = fread(Data+2, 1, itemlen-2, ImageInfo->infile); /* Read the whole section. */
if (got != itemlen-2) {
php_error(E_WARNING, "error reading from file: got=x%04X(=%d) != itemlen-2=x%04X(=%d)",got, got, itemlen-2, itemlen-2);
return FALSE;
@ -1868,19 +1922,19 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo, FILE *infile)
if (ImageInfo->read_all) {
int cp, ep, size;
/* Determine how much file is left. */
cp = ftell(infile);
fseek(infile, 0, SEEK_END);
ep = ftell(infile);
fseek(infile, cp, SEEK_SET);
cp = ftell(ImageInfo->infile);
fseek(ImageInfo->infile, 0, SEEK_END);
ep = ftell(ImageInfo->infile);
fseek(ImageInfo->infile, cp, SEEK_SET);
size = ep-cp;
Data = (uchar *)emalloc(size);
if (Data == NULL) {
php_error(E_ERROR, "could not allocate data for entire image");
EXIF_ERRLOG_EALLOC
return FALSE;
}
got = fread(Data, 1, size, infile);
got = fread(Data, 1, size, ImageInfo->infile);
if (got != size) {
php_error(E_WARNING, "could not read the rest of the image");
return FALSE;
@ -1954,26 +2008,23 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo, FILE *infile)
/* {{{ exif_process_IFD_in_TIFF
* Parse the TIFF header; */
static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, FILE *infile, size_t dir_offset, int section_index)
static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offset, int section_index)
{
int i, sn, num_entries, sub_section_index;
unsigned char *dir_entry;
size_t ifd_size, dir_size, entry_offset, next_offset, entry_length, entry_value;
int entry_tag , entry_type;
#ifdef EXIF_DEBUG
char tagname[64];
#endif
sn = ImageInfo->sections_count++;
if ( ImageInfo->FileSize >= dir_offset+2) {
ImageInfo->sections[sn].Size = 2;
ImageInfo->sections[sn].Data = emalloc(ImageInfo->sections[sn].Size);
if ( !ImageInfo->sections[sn].Data) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return FALSE;
}
fseek(infile,dir_offset,SEEK_SET); /* we do not know the order of sections */
fread(ImageInfo->sections[sn].Data, 1, 2, infile);
fseek(ImageInfo->infile,dir_offset,SEEK_SET); /* we do not know the order of sections */
fread(ImageInfo->sections[sn].Data, 1, 2, ImageInfo->infile);
num_entries = php_ifd_get16u(ImageInfo->sections[sn].Data, ImageInfo->motorola_intel);
dir_size = 2/*num dir entries*/ +12/*length of entry*/*num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/;
#ifdef EXIF_DEBUG
@ -1983,10 +2034,10 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, FILE *infile, si
ImageInfo->sections[sn].Size = dir_size;
ImageInfo->sections[sn].Data = erealloc(ImageInfo->sections[sn].Data,ImageInfo->sections[sn].Size);
if ( !ImageInfo->sections[sn].Data) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return FALSE;
}
fread(ImageInfo->sections[sn].Data+2, 1, dir_size-2, infile);
fread(ImageInfo->sections[sn].Data+2, 1, dir_size-2, ImageInfo->infile);
next_offset = php_ifd_get32u(ImageInfo->sections[sn].Data + dir_size - 4, ImageInfo->motorola_intel);
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"Read from TIFF done, next offset x%04X", next_offset);
@ -2054,20 +2105,20 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, FILE *infile, si
ImageInfo->sections[sn].Size = ifd_size;
ImageInfo->sections[sn].Data = erealloc(ImageInfo->sections[sn].Data,ImageInfo->sections[sn].Size);
if ( !ImageInfo->sections[sn].Data) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
return FALSE;
}
if ( ImageInfo->FileSize >= ImageInfo->sections[sn].Size) {
if ( ifd_size > dir_size) {
/* read values not stored in directory itself */
if ( ImageInfo->sections[sn].Size > ImageInfo->FileSize) {
php_error(E_ERROR,"Error in TIFF: filesize(x%04X) less than size of IFD(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, ifd_size);
php_error(E_WARNING,"Error in TIFF: filesize(x%04X) less than size of IFD(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, ifd_size);
return FALSE;
}
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"Read from TIFF: filesize(x%04X), IFD(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, ifd_size);
#endif
fread(ImageInfo->sections[sn].Data+dir_size, 1, ifd_size-dir_size, infile);
fread(ImageInfo->sections[sn].Data+dir_size, 1, ifd_size-dir_size, ImageInfo->infile);
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"Read from TIFF, done");
#endif
@ -2101,12 +2152,14 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, FILE *infile, si
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"Next IFD %s at x%04X", exif_get_sectionname(sub_section_index), entry_offset);
#endif
exif_process_IFD_in_TIFF(ImageInfo,infile,entry_offset,sub_section_index);
exif_process_IFD_in_TIFF(ImageInfo,entry_offset,sub_section_index);
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"Next IFD %s done", exif_get_sectionname(sub_section_index));
#endif
} else {
exif_process_IFD_TAG(ImageInfo,dir_entry,ImageInfo->sections[sn].Data-dir_offset,ifd_size,section_index,0);
if ( !exif_process_IFD_TAG(ImageInfo,dir_entry,ImageInfo->sections[sn].Data-dir_offset,ifd_size,section_index,0)) {
return FALSE;
}
}
}
if (next_offset && section_index != SECTION_THUMBNAIL) {
@ -2115,17 +2168,17 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, FILE *infile, si
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"Read next IFD (THUMBNAIL) at x%04X", next_offset);
#endif
exif_process_IFD_in_TIFF(ImageInfo,infile,next_offset,SECTION_THUMBNAIL);
exif_process_IFD_in_TIFF(ImageInfo,next_offset,SECTION_THUMBNAIL);
#ifdef EXIF_DEBUG
php_error(E_NOTICE,"Read THUMBNAIL @0x%04X + 0x%04X", ImageInfo->ThumbnailOffset, ImageInfo->ThumbnailSize);
#endif
if (ImageInfo->ThumbnailOffset && ImageInfo->ThumbnailSize) {
ImageInfo->Thumbnail = emalloc(ImageInfo->ThumbnailSize);
if (!ImageInfo->Thumbnail) {
php_error(E_ERROR, "Could not allocate memory for thumbnail");
EXIF_ERRLOG_EALLOC
} else {
fseek(infile,ImageInfo->ThumbnailOffset,SEEK_SET);
fread(ImageInfo->Thumbnail, 1, ImageInfo->ThumbnailSize, infile);
fseek(ImageInfo->infile,ImageInfo->ThumbnailOffset,SEEK_SET);
fread(ImageInfo->Thumbnail, 1, ImageInfo->ThumbnailSize, ImageInfo->infile);
}
}
#ifdef EXIF_DEBUG
@ -2134,15 +2187,15 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, FILE *infile, si
}
return TRUE;
} else {
php_error(E_ERROR,"Error in TIFF: filesize(x%04X) less than size of IFD(x%04X)", ImageInfo->sections[sn].Size);
php_error(E_WARNING,"Error in TIFF: filesize(x%04X) less than size of IFD(x%04X)", ImageInfo->sections[sn].Size);
return FALSE;
}
} else {
php_error(E_ERROR,"Error in TIFF: filesize(x%04X) less than size of IFD dir(x%04X)", ImageInfo->FileSize, dir_size);
php_error(E_WARNING,"Error in TIFF: filesize(x%04X) less than size of IFD dir(x%04X)", ImageInfo->FileSize, dir_size);
return FALSE;
}
} else {
php_error(E_ERROR,"Error in TIFF: filesize(x%04X) less than size of IFD dir(x%04X)", ImageInfo->FileSize, dir_offset+2);
php_error(E_WARNING,"Error in TIFF: filesize(x%04X) less than size of IFD dir(x%04X)", ImageInfo->FileSize, dir_offset+2);
return FALSE;
}
}
@ -2150,20 +2203,20 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, FILE *infile, si
/* {{{ exif_scan_FILE_header
* Parse the marker stream until SOS or EOI is seen; */
static int exif_scan_FILE_header (image_info_type *ImageInfo, FILE *infile)
static int exif_scan_FILE_header (image_info_type *ImageInfo)
{
unsigned char file_header[8];
ImageInfo->FileType = IMAGE_FILETYPE_UNKNOWN;
if ( ImageInfo->FileSize >= 2) {
fseek(infile, 0, SEEK_SET);
fread(file_header, 1, 2, infile);
fseek(ImageInfo->infile, 0, SEEK_SET);
fread(file_header, 1, 2, ImageInfo->infile);
if ( (file_header[0]==0xff) && (file_header[1]==M_SOI)) {
ImageInfo->FileType = IMAGE_FILETYPE_JPEG;
return exif_scan_JPEG_header(ImageInfo,infile);
return exif_scan_JPEG_header(ImageInfo);
} else if ( ImageInfo->FileSize >= 8) {
fread(file_header+2, 1, 6, infile);
fread(file_header+2, 1, 6, ImageInfo->infile);
if ( !memcmp(file_header,"II\x2A\x00", 4))
{
ImageInfo->FileType = IMAGE_FILETYPE_TIFF;
@ -2172,7 +2225,7 @@ static int exif_scan_FILE_header (image_info_type *ImageInfo, FILE *infile)
php_error(E_NOTICE,"File(%s) has TIFF/II format", ImageInfo->FileName);
#endif
ImageInfo->sections_found |= FOUND_IFD0;
return exif_process_IFD_in_TIFF(ImageInfo,infile,php_ifd_get32u(file_header+4,ImageInfo->motorola_intel),SECTION_IFD0);
return exif_process_IFD_in_TIFF(ImageInfo,php_ifd_get32u(file_header+4,ImageInfo->motorola_intel),SECTION_IFD0);
}
else
if ( !memcmp(file_header,"MM\x00\x2a", 4))
@ -2183,7 +2236,7 @@ static int exif_scan_FILE_header (image_info_type *ImageInfo, FILE *infile)
php_error(E_NOTICE,"File(%s) has TIFF/MM format", ImageInfo->FileName);
#endif
ImageInfo->sections_found |= FOUND_IFD0;
return exif_process_IFD_in_TIFF(ImageInfo,infile,php_ifd_get32u(file_header+4,ImageInfo->motorola_intel),SECTION_IFD0);
return exif_process_IFD_in_TIFF(ImageInfo,php_ifd_get32u(file_header+4,ImageInfo->motorola_intel),SECTION_IFD0);
} else {
php_error(E_WARNING,"File(%s) not supported", ImageInfo->FileName);
return FALSE;
@ -2235,18 +2288,18 @@ int php_exif_discard_imageinfo(image_info_type *ImageInfo)
int php_exif_read_file(image_info_type *ImageInfo, char *FileName, int read_thumbnail, int read_all TSRMLS_DC)
{
int ret;
FILE *infile;
/* Start with an empty image information structure. */
memset(ImageInfo, 0, sizeof(*ImageInfo));
ImageInfo->motorola_intel = 0;
infile = VCWD_FOPEN(FileName, "rb"); /* Unix ignores 'b', windows needs it. */
ImageInfo->infile = VCWD_FOPEN(FileName, "rb"); /* Unix ignores 'b', windows needs it. */
if (infile == NULL) {
if (ImageInfo->infile == NULL) {
php_error(E_WARNING, "Unable to open '%s'", FileName);
return FALSE;
}
/* Start with an empty image information structure. */
memset(ImageInfo, 0, sizeof(*ImageInfo));
ImageInfo->FileName = php_basename(FileName, strlen(FileName), NULL, 0);
ImageInfo->read_thumbnail = read_thumbnail;
@ -2265,12 +2318,12 @@ int php_exif_read_file(image_info_type *ImageInfo, char *FileName, int read_thum
}
/* Scan the JPEG headers. */
ret = exif_scan_FILE_header(ImageInfo, infile);
ret = exif_scan_FILE_header(ImageInfo);
if (!ret) {
php_error(E_WARNING, "Invalid JPEG/TIFF file: '%s'", FileName);
}
fclose(infile);
fclose(ImageInfo->infile);
return ret;
}
@ -2297,7 +2350,7 @@ PHP_FUNCTION(exif_read_data)
convert_to_string_ex(p_sections_needed);
sections_str = emalloc(strlen(Z_STRVAL_PP(p_sections_needed))+3);
if ( !sections_str) {
php_error(E_ERROR,"Cannot allocate memory for all data");
EXIF_ERRLOG_EALLOC
RETURN_FALSE;
}
sprintf(sections_str,",%s,",Z_STRVAL_PP(p_sections_needed));