summaryrefslogtreecommitdiffstats
path: root/src/file_gz.c
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2013-02-16 16:16:43 +0100
committerChristophe Grenier <grenier@cgsecurity.org>2013-02-16 16:16:43 +0100
commit199a661c307fad83f6fb6847fc8172b022f5f84f (patch)
treeb1dd8f21727e846df21c032749116cff7fc81f5d /src/file_gz.c
parentfaceca8b9a6f35385fd295e9ca9b259b5963291a (diff)
PhotoRec: stricter check for .gz file
Diffstat (limited to 'src/file_gz.c')
-rw-r--r--src/file_gz.c234
1 files changed, 117 insertions, 117 deletions
diff --git a/src/file_gz.c b/src/file_gz.c
index 021f10c..bbbf721 100644
--- a/src/file_gz.c
+++ b/src/file_gz.c
@@ -72,6 +72,8 @@ static void register_header_check_gz(file_stat_t *file_stat)
static int header_check_gz(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
static const unsigned char tar_header_posix[8] = { 'u','s','t','a','r',' ',' ',0x00};
+ unsigned int off=10;
+ const unsigned int flags=buffer[3];
/* gzip file format:
* a 10-byte header, containing a magic number, a version number and a timestamp
* optional extra headers, such as the original file name,
@@ -80,151 +82,149 @@ static int header_check_gz(const unsigned char *buffer, const unsigned int buffe
* the length (32 bits) of the original uncompressed data
*/
/* gzip, deflate */
- if(buffer[0]==0x1F && buffer[1]==0x8B && buffer[2]==0x08 && (buffer[3]&0xe0)==0)
- {
- unsigned int off=10;
- const unsigned int flags=buffer[3];
+ if(!(buffer[0]==0x1F && buffer[1]==0x8B && buffer[2]==0x08 && (buffer[3]&0xe0)==0))
+ return 0;
- /*
- 4,5,6,7: mtime
- 8: xfl/extra flags
- 9: OS 3 - Unix, 7 - Macintosh, 11 - NTFS filesystem (NT)
- */
- if((flags&GZ_FEXTRA)!=0)
+ /*
+ 4,5,6,7: mtime
+8: xfl/extra flags
+9: OS 3 - Unix, 7 - Macintosh, 11 - NTFS filesystem (NT)
+*/
+ if((flags&GZ_FEXTRA)!=0)
+ {
+ off+=2;
+ off+=buffer[10]|(buffer[11]<<8);
+ }
+ if((flags&GZ_FNAME)!=0)
+ {
+ while(off<buffer_size && buffer[off++]!='\0')
{
- off+=2;
- off+=buffer[10]|(buffer[11]<<8);
}
- if((flags&GZ_FNAME)!=0)
+ }
+ if((flags&GZ_FCOMMENT)!=0)
+ {
+ while(off<buffer_size && buffer[off++]!='\0')
{
- while(off<buffer_size && buffer[off++]!='\0')
+ }
+ }
+ if((flags&GZ_FHCRC)!=0)
+ {
+ off+=2;
+ }
+ if(off >= 512 || off >= buffer_size)
+ return 0;
+#if defined(HAVE_ZLIB_H) && defined(HAVE_LIBZ)
+ {
+ static const unsigned char schematic_header[12]={ 0x0a, 0x00, 0x09,
+ 'S', 'c', 'h', 'e', 'm', 'a', 't', 'i', 'c'};
+ const unsigned char *buffer_compr=buffer+off;
+ unsigned char buffer_uncompr[512];
+ const unsigned int comprLen=(buffer_size<512?buffer_size:512)-off;
+ const unsigned int uncomprLen=512-1;
+ int err;
+ z_stream d_stream; /* decompression stream */
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = (Bytef*)buffer_compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = buffer_uncompr;
+
+ err = inflateInit2(&d_stream, -MAX_WBITS);
+ if(err!=Z_OK)
+ return 0;
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if(err!=Z_OK)
{
+ /* Decompression has failed, free ressources */
+ inflateEnd(&d_stream);
+ return 0;
}
}
- if((flags&GZ_FCOMMENT)!=0)
+ err = inflateEnd(&d_stream);
+ if(err!=Z_OK)
+ return 0;
+ /* Probably too small to be a file */
+ if(d_stream.total_out < 16)
+ return 0;
+ buffer_uncompr[d_stream.total_out]='\0';
+ reset_file_recovery(file_recovery_new);
+ file_recovery_new->min_filesize=22;
+ file_recovery_new->time=buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
+ file_recovery_new->file_rename=&file_rename_gz;
+ if(memcmp(buffer_uncompr, "PVP ", 4)==0)
{
- while(off<buffer_size && buffer[off++]!='\0')
- {
- }
+ /* php Video Pro */
+ file_recovery_new->extension="pvp";
+ return 1;
}
- if((flags&GZ_FHCRC)!=0)
+ if(memcmp(buffer_uncompr, "<?xml version=\"1.0\" standalone=\"no\"?>\n<xournal", 46)==0)
{
- off+=2;
+ /* Xournal, http://xournal.sourceforge.net/ */
+ file_recovery_new->extension="xoj";
+ return 1;
}
-#if defined(HAVE_ZLIB_H) && defined(HAVE_LIBZ)
- if(buffer_size>off && 512>off)
+ if(strstr((const char*)&buffer_uncompr, "<!DOCTYPE KMYMONEY-FILE>")!=NULL)
{
- static const unsigned char schematic_header[12]={ 0x0a, 0x00, 0x09,
- 'S', 'c', 'h', 'e', 'm', 'a', 't', 'i', 'c'};
- const unsigned char *buffer_compr=buffer+off;
- unsigned char buffer_uncompr[512];
- const unsigned int comprLen=(buffer_size<512?buffer_size:512)-off;
- const unsigned int uncomprLen=512-1;
- int err;
- z_stream d_stream; /* decompression stream */
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = (Bytef*)buffer_compr;
- d_stream.avail_in = 0;
- d_stream.next_out = buffer_uncompr;
-
- err = inflateInit2(&d_stream, -MAX_WBITS);
- if(err!=Z_OK)
- return 0;
- while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
- d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- if(err!=Z_OK)
- {
- /* Decompression has failed, free ressources */
- inflateEnd(&d_stream);
- return 0;
- }
- }
- err = inflateEnd(&d_stream);
- if(err!=Z_OK)
- return 0;
- buffer_uncompr[d_stream.total_out]='\0';
- reset_file_recovery(file_recovery_new);
- file_recovery_new->min_filesize=22;
- file_recovery_new->time=buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
- file_recovery_new->file_rename=&file_rename_gz;
- if(memcmp(buffer_uncompr, "PVP ", 4)==0)
- {
- /* php Video Pro */
- file_recovery_new->extension="pvp";
- return 1;
- }
- if(memcmp(buffer_uncompr, "<?xml version=\"1.0\" standalone=\"no\"?>\n<xournal", 46)==0)
- {
- /* Xournal, http://xournal.sourceforge.net/ */
- file_recovery_new->extension="xoj";
- return 1;
- }
- if(strstr((const char*)&buffer_uncompr, "<!DOCTYPE KMYMONEY-FILE>")!=NULL)
- {
- file_recovery_new->extension="kmy";
- return 1;
- }
+ file_recovery_new->extension="kmy";
+ return 1;
+ }
#ifndef DJGPP
- if(memcmp(buffer_uncompr, "RDX2", 4)==0)
- {
- /* R - language and environment for statistical computing and graphics */
- file_recovery_new->extension="RData";
- return 1;
- }
- if(memcmp(buffer_uncompr, "<?xml version=", 14) == 0)
- {
- file_recovery_new->extension="xml.gz";
- return 1;
- }
- if(memcmp(buffer_uncompr, schematic_header, sizeof(schematic_header))==0)
- {
- /* Minecraft Schematic File */
- file_recovery_new->extension="schematic";
- return 1;
- }
+ if(memcmp(buffer_uncompr, "RDX2", 4)==0)
+ {
+ /* R - language and environment for statistical computing and graphics */
+ file_recovery_new->extension="RData";
+ return 1;
+ }
+ if(memcmp(buffer_uncompr, "<?xml version=", 14) == 0)
+ {
+ file_recovery_new->extension="xml.gz";
+ return 1;
+ }
+ if(memcmp(buffer_uncompr, schematic_header, sizeof(schematic_header))==0)
+ {
+ /* Minecraft Schematic File */
+ file_recovery_new->extension="schematic";
+ return 1;
+ }
+ {
+ unsigned int i;
+ for(i=0; i<d_stream.total_out && i< 256; i++)
{
- unsigned int i;
- for(i=0; i<d_stream.total_out && i< 256; i++)
+ if(buffer_uncompr[i]=='<')
{
- if(buffer_uncompr[i]=='<')
+ if(strncasecmp((const char*)&buffer_uncompr[i], "<html", 5)==0)
{
- if(strncasecmp((const char*)&buffer_uncompr[i], "<html", 5)==0)
- {
- file_recovery_new->extension="html.gz";
- return 1;
- }
+ file_recovery_new->extension="html.gz";
+ return 1;
}
}
}
+ }
#endif
- if(d_stream.total_out>0x110 &&
+ if(d_stream.total_out>0x110 &&
memcmp(&buffer_uncompr[0x101],tar_header_posix,sizeof(tar_header_posix))==0)
- {
+ {
#ifdef DJGPP
- file_recovery_new->extension="tgz";
+ file_recovery_new->extension="tgz";
#else
- file_recovery_new->extension="tar.gz";
+ file_recovery_new->extension="tar.gz";
#endif
- return 1;
- }
- file_recovery_new->extension=file_hint_gz.extension;
return 1;
}
+ }
#else
- reset_file_recovery(file_recovery_new);
- file_recovery_new->min_filesize=22;
- file_recovery_new->time=buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
- file_recovery_new->file_rename=&file_rename_gz;
- file_recovery_new->extension=file_hint_gz.extension;
- return 1;
+ reset_file_recovery(file_recovery_new);
+ file_recovery_new->min_filesize=22;
+ file_recovery_new->time=buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
+ file_recovery_new->file_rename=&file_rename_gz;
#endif
- }
- return 0;
+ file_recovery_new->extension=file_hint_gz.extension;
+ return 1;
}
static void file_rename_gz(const char *old_filename)