summaryrefslogtreecommitdiffstats
path: root/src/file_xcf.c
diff options
context:
space:
mode:
authorChristophe Grenier <grenier@cgsecurity.org>2014-07-26 22:54:44 +0200
committerChristophe Grenier <grenier@cgsecurity.org>2014-07-26 22:54:44 +0200
commit0acad5b54c041051e3c959ff5b3dd395e0225049 (patch)
treec481859fed7258f30dae95eb3f303fcf2592e5bb /src/file_xcf.c
parent7862b761c6495bb8dca25c23edb310507626a307 (diff)
PhotoRec: stricter check for .xcf
Diffstat (limited to 'src/file_xcf.c')
-rw-r--r--src/file_xcf.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/src/file_xcf.c b/src/file_xcf.c
index 122d942..8e58e18 100644
--- a/src/file_xcf.c
+++ b/src/file_xcf.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include "types.h"
#include "filegen.h"
+#include "common.h"
static void register_header_check_xcf(file_stat_t *file_stat);
static int header_check_xcf(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);
@@ -43,25 +44,34 @@ const file_hint_t file_hint_xcf= {
.register_header_check=&register_header_check_xcf
};
-// version 0: gimp xcf file
-// version 1: gimp xcf v001
-static const unsigned char xcf_header_v0[13]= {'g','i','m','p',' ','x','c','f',' ','f','i','l','e'};
-static const unsigned char xcf_header_v1[10]= {'g','i','m','p',' ','x','c','f',' ','v'};
+// https://git.gnome.org/browse/gimp/tree/devel-docs/xcf.txt
+struct xcf_header
+{
+ unsigned char magic[9];
+ unsigned char version[4];
+ unsigned char zero;
+ uint32_t width;
+ uint32_t heigth;
+ uint32_t base_type;
+} __attribute__ ((__packed__));
-static void register_header_check_xcf(file_stat_t *file_stat)
+static int header_check_xcf(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)
{
- register_header_check(0, xcf_header_v0,sizeof(xcf_header_v0), &header_check_xcf, file_stat);
- register_header_check(0, xcf_header_v1,sizeof(xcf_header_v1), &header_check_xcf, file_stat);
+ const struct xcf_header *hdr=(const struct xcf_header *)buffer;
+ if(hdr->zero!=0)
+ return 0;
+ if(be32(hdr->width)==0 || be32(hdr->heigth)==0)
+ return 0;
+ if(be32(hdr->base_type) > 2)
+ return 0;
+ reset_file_recovery(file_recovery_new);
+ file_recovery_new->extension=file_hint_xcf.extension;
+ return 1;
}
-static int header_check_xcf(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 void register_header_check_xcf(file_stat_t *file_stat)
{
- if(memcmp(buffer,xcf_header_v0, sizeof(xcf_header_v0))==0 ||
- memcmp(buffer,xcf_header_v1, sizeof(xcf_header_v1))==0)
- {
- reset_file_recovery(file_recovery_new);
- file_recovery_new->extension=file_hint_xcf.extension;
- return 1;
- }
- return 0;
+ register_header_check(0, "gimp xcf file", 13, &header_check_xcf, file_stat);
+ register_header_check(0, "gimp xcf v001", 13, &header_check_xcf, file_stat);
+ register_header_check(0, "gimp xcf v002", 13, &header_check_xcf, file_stat);
}