summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2020-08-27 18:13:24 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2020-08-27 18:13:24 +0200
commitcf101c1f468e2bcf2125ce0dc8760969775d3297 (patch)
tree7776eb53bf8211460743554439e1aa5ad92849dc
parentb5f43e2865ed59f33d073085df651f87b168fd1f (diff)
PhotoRec: stricter check for jpg
-rw-r--r--src/file_jpg.c131
1 files changed, 66 insertions, 65 deletions
diff --git a/src/file_jpg.c b/src/file_jpg.c
index cca6e47..45fb1a0 100644
--- a/src/file_jpg.c
+++ b/src/file_jpg.c
@@ -441,7 +441,6 @@ static int is_marker_valid(const unsigned int marker)
{
switch(marker)
{
- case 0x02 ... 0xbf: /* Reserved */
case 0xc0: /* SOF0 Start of Frame */
case 0xc1: /* SOF1 Extended sequential */
case 0xc2: /* SOF2 Progressive */
@@ -458,19 +457,22 @@ static int is_marker_valid(const unsigned int marker)
case 0xcd: /* SOF13 Differential sequential, arithmetic coding */
case 0xce: /* SOF14 Differential progressive, arithmetic coding */
case 0xcf: /* SOF15 Differential lossless, arithmetic coding */
- case 0xd0 ... 0xd7: /* JPEG_RST0 .. JPEG_RST7 markers */
-// case 0xd8: /* SOI Start of Image */
-// case 0xd9: /* EOI End of Image */
-// case 0xda: /* SOS: Start Of Scan */
case 0xdb: /* DQT: Define Quantization Table */
- case 0xdc: /* DNL: Define Number of Lines */
case 0xdd: /* DRI: define restart interval */
- case 0xde: /* DHP: define hierarchical progression */
case 0xe0 ... 0xef: /* APP0 - APP15 */
- case 0xf0 ... 0xfd: /* Reserved for JPEG extensions */
case 0xfe: /* COM */
case 0xff:
return 1;
+#if 0
+ case 0x02 ... 0xbf: /* Reserved */
+ case 0xd0 ... 0xd7: /* JPEG_RST0 .. JPEG_RST7 markers */
+ case 0xd8: /* SOI Start of Image */
+ case 0xd9: /* EOI End of Image */
+ case 0xda: /* SOS: Start Of Scan */
+ case 0xdc: /* DNL: Define Number of Lines */
+ case 0xde: /* DHP: define hierarchical progression */
+ case 0xf0 ... 0xfd: /* Reserved for JPEG extensions */
+#endif
default:
return 0;
}
@@ -549,10 +551,21 @@ static int header_check_jpg(const unsigned char *buffer, const unsigned int buff
i+=2+size;
}
}
+ if(i < file_recovery_new->blocksize && buffer[i]!=0xff)
+ return 0;
if(i+1 < file_recovery_new->blocksize && buffer[i+1]!=0xda)
return 0;
+ if(i < 512 && buffer[i]!=0xff)
+ return 0;
if(i+1 < 512 && buffer[i+1]!=0xda)
return 0;
+ if(file_recovery->file_stat==NULL)
+ {
+ if(i < buffer_size && buffer[i]!=0xff)
+ return 0;
+ if(i+1 < buffer_size && buffer[i+1]!=0xda)
+ return 0;
+ }
if(file_recovery->file_stat!=NULL)
{
static const unsigned char jpg_header_app0_avi[0x0c]= {
@@ -635,30 +648,32 @@ static int header_check_jpg(const unsigned char *buffer, const unsigned int buff
return 0;
}
#endif
- if(buffer[3]==0xdb) /* DQT */
+ switch(buffer[3])
{
- header_ignored(file_recovery_new);
- return 0;
- }
- if(buffer[3]==0xc4) /* DHT - needed to recover .cr2 */
- {
- header_ignored(file_recovery_new);
- return 0;
- }
- if(buffer[3]==0xe0 && (buffer[6]!='J' || buffer[7]!='F')) /* Should be JFIF/JFXX */
- {
- header_ignored(file_recovery_new);
- return 0;
- }
- if(buffer[3]==0xe1 && (buffer[6]!='E' || buffer[7]!='x' || buffer[8]!='i'|| buffer[9]!='f')) /* Should be EXIF */
- {
- header_ignored(file_recovery_new);
- return 0;
- }
- if(buffer[3]==0xfe && (!isprint(buffer[6]) || !isprint(buffer[7])))
- {
- header_ignored(file_recovery_new);
- return 0;
+ case 0xe0: /* APP0 */
+ if(buffer[6]!='J' || buffer[7]!='F') /* Should be JFIF/JFXX */
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
+ break;
+ case 0xe1: /* APP1 */
+ if(buffer[6]!='E' || buffer[7]!='x' || buffer[8]!='i'|| buffer[9]!='f') /* Should be Exif */
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
+ break;
+ case 0xfe: /* COM */
+ if(!isprint(buffer[6]) || !isprint(buffer[7]))
+ {
+ header_ignored(file_recovery_new);
+ return 0;
+ }
+ break;
+ default:
+ header_ignored(file_recovery_new);
+ return 0;
}
}
reset_file_recovery(file_recovery_new);
@@ -1920,19 +1935,10 @@ static uint64_t jpg_check_structure(file_recovery_t *file_recovery, const unsign
}
}
offset=2;
- while(offset + 4 < nbytes && (file_recovery->offset_error==0 || offset < file_recovery->offset_error))
+ while(offset + 4 < nbytes && buffer[offset]==0xff && is_marker_valid(buffer[offset+1]) && (file_recovery->offset_error==0 || offset < file_recovery->offset_error))
{
const unsigned int i=offset;
const unsigned int size=(buffer[i+2]<<8)+buffer[i+3];
- if(buffer[i]!=0xff)
- {
-#if defined(DEBUG_JPEG)
- log_info("%s no marker at 0x%x\n", file_recovery->filename, i);
-#endif
- file_recovery->offset_error=i;
- jpg_search_marker(file_recovery);
- return thumb_offset;
- }
if(buffer[i+1]==0xff)
{
/* See B.1.1.2 Markers in http://www.w3.org/Graphics/JPEG/itu-t81.pdf*/
@@ -1943,12 +1949,7 @@ static uint64_t jpg_check_structure(file_recovery_t *file_recovery, const unsign
log_info("%s marker 0x%02x at 0x%x\n", file_recovery->filename, buffer[i+1], i);
#endif
offset+=(uint64_t)2+size;
- if(buffer[i+1]==0xda) /* SOS: Start Of Scan */
- {
- file_recovery->offset_ok=i+1;
- return thumb_offset;
- }
- else if(buffer[i+1]==0xe1)
+ if(buffer[i+1]==0xe1)
{ /* APP1 Exif information */
if(jpg_check_app1(file_recovery, extract_thumb, buffer, i, offset, size, nbytes, &thumb_offset)==0)
return 0;
@@ -1960,26 +1961,26 @@ static uint64_t jpg_check_structure(file_recovery_t *file_recovery, const unsign
file_recovery->offset_error=i+2;
return thumb_offset;
}
- if(file_recovery->offset_ok<i+1)
- file_recovery->offset_ok=i+1;
- }
- else if(buffer[i+1]==0xdb || /* DQT */
- (buffer[i+1]>=0xc0 && buffer[i+1]<=0xcf) || /* SOF0 - SOF15 */
- buffer[i+1]==0xdd || /* DRI */
- (buffer[i+1]>=0xe0 && buffer[i+1]<=0xef) || /* APP0 - APP15 */
- buffer[i+1]==0xfe) /* COM */
- {
- if(file_recovery->offset_ok<i+1)
- file_recovery->offset_ok=i+1;
}
- else
- {
-#ifndef __FRAMAC__
- log_info("%s unknown marker 0x%02x at 0x%x\n", file_recovery->filename, buffer[i+1], i+1);
+ if(file_recovery->offset_ok<i+1)
+ file_recovery->offset_ok=i+1;
+ }
+ if(offset < nbytes && buffer[offset]!=0xff)
+ {
+#if defined(DEBUG_JPEG)
+ log_info("%s no marker at 0x%x\n", file_recovery->filename, offset);
#endif
- file_recovery->offset_error=i+1;
- return thumb_offset;
- }
+ file_recovery->offset_error=offset;
+ jpg_search_marker(file_recovery);
+ return thumb_offset;
+ }
+ if(offset + 4 < nbytes)
+ {
+ if(buffer[offset+1]==0xda) /* SOS: Start Of Scan */
+ file_recovery->offset_ok=offset+1;
+ else
+ file_recovery->offset_error=offset+1;
+ return thumb_offset;
}
if(offset > nbytes && nbytes < sizeof(buffer))
{