parent
b966e6cabd
commit
6f490ea9fa
5 changed files with 93 additions and 29 deletions
|
@ -34,6 +34,8 @@
|
||||||
#include "file_tar.h"
|
#include "file_tar.h"
|
||||||
|
|
||||||
static void register_header_check_tar(file_stat_t *file_stat);
|
static void register_header_check_tar(file_stat_t *file_stat);
|
||||||
|
static const unsigned char tar_header_gnu[6] = { 'u','s','t','a','r',0x00};
|
||||||
|
static const unsigned char tar_header_posix[8] = { 'u','s','t','a','r',' ',' ',0x00};
|
||||||
|
|
||||||
const file_hint_t file_hint_tar= {
|
const file_hint_t file_hint_tar= {
|
||||||
.extension="tar",
|
.extension="tar",
|
||||||
|
@ -44,26 +46,63 @@ const file_hint_t file_hint_tar= {
|
||||||
.register_header_check=®ister_header_check_tar
|
.register_header_check=®ister_header_check_tar
|
||||||
};
|
};
|
||||||
|
|
||||||
struct posix_header
|
/*@
|
||||||
{ /* byte offset */
|
@ requires \valid_read(h);
|
||||||
char name[100]; /* 0 */
|
@ assigns \nothing;
|
||||||
char mode[8]; /* 100 */
|
@*/
|
||||||
char uid[8]; /* 108 */
|
static int is_valid_checksum_format(const struct tar_posix_header *h)
|
||||||
char gid[8]; /* 116 */
|
{
|
||||||
char size[12]; /* 124 */
|
unsigned int i;
|
||||||
char mtime[12]; /* 136 */
|
int space_allowed=1;
|
||||||
char chksum[8]; /* 148 */
|
int all_null=1;
|
||||||
char typeflag; /* 156 */
|
/* No checksum ? */
|
||||||
char linkname[100]; /* 157 */
|
/*@
|
||||||
char magic[6]; /* 257 */
|
@ loop assigns i,all_null;
|
||||||
char version[2]; /* 263 */
|
@*/
|
||||||
char uname[32]; /* 265 */
|
for(i=0; i<8; i++)
|
||||||
char gname[32]; /* 297 */
|
if(h->chksum[i]!=0)
|
||||||
char devmajor[8]; /* 329 */
|
all_null=0;
|
||||||
char devminor[8]; /* 337 */
|
if(all_null!=0)
|
||||||
char prefix[155]; /* 345 */
|
return 1;
|
||||||
/* 500 */
|
/*
|
||||||
};
|
* Checksum should be stored as a six digit octal number with leading zeroes followed by a NUL and then a space.
|
||||||
|
* Various implementations do not adhere to this format, try to handle them
|
||||||
|
*/
|
||||||
|
/*@
|
||||||
|
@ loop assigns i,space_allowed;
|
||||||
|
@*/
|
||||||
|
for(i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
if(h->chksum[i] >= '0' || h->chksum[i] <= '7')
|
||||||
|
{
|
||||||
|
space_allowed=0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(h->chksum[i] == ' ')
|
||||||
|
{
|
||||||
|
if(space_allowed == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(h->chksum[6] == 0 || h->chksum[7] == ' ')
|
||||||
|
return 1;
|
||||||
|
if((h->chksum[6] >= '0' || h->chksum[6] <= '7') && h->chksum[7] == ' ')
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_valid_tar_header(const struct tar_posix_header *h)
|
||||||
|
{
|
||||||
|
/* Do not remove this check. */
|
||||||
|
if(memcmp(&h->magic,tar_header_gnu,sizeof(tar_header_gnu))!=0 &&
|
||||||
|
memcmp(&h->magic,tar_header_posix,sizeof(tar_header_posix))!=0)
|
||||||
|
return 0;
|
||||||
|
if(is_valid_checksum_format(h)==0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
@ requires buffer_size >= 512;
|
@ requires buffer_size >= 512;
|
||||||
|
@ -74,10 +113,10 @@ struct posix_header
|
||||||
@ requires file_recovery_new->blocksize > 0;
|
@ requires file_recovery_new->blocksize > 0;
|
||||||
@ requires separation: \separated(&file_hint_tar, buffer+(..), file_recovery, file_recovery_new);
|
@ requires separation: \separated(&file_hint_tar, buffer+(..), file_recovery, file_recovery_new);
|
||||||
@*/
|
@*/
|
||||||
int header_check_tar(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 int header_check_tar(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)
|
||||||
{
|
{
|
||||||
const struct posix_header *h=(const struct posix_header *)buffer;
|
const struct tar_posix_header *h=(const struct tar_posix_header *)buffer;
|
||||||
if(!isspace(h->chksum[0]) && !((unsigned) (h->chksum[0]) - '0' <= 7))
|
if(is_valid_tar_header(h)==0)
|
||||||
return 0;
|
return 0;
|
||||||
if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_tar)
|
if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_tar)
|
||||||
{
|
{
|
||||||
|
@ -95,9 +134,9 @@ int header_check_tar(const unsigned char *buffer, const unsigned int buffer_size
|
||||||
@*/
|
@*/
|
||||||
static void register_header_check_tar(file_stat_t *file_stat)
|
static void register_header_check_tar(file_stat_t *file_stat)
|
||||||
{
|
{
|
||||||
static const unsigned char tar_header_gnu[6] = { 'u','s','t','a','r',0x00};
|
|
||||||
static const unsigned char tar_header_posix[8] = { 'u','s','t','a','r',' ',' ',0x00};
|
|
||||||
register_header_check(0x101, tar_header_gnu,sizeof(tar_header_gnu), &header_check_tar, file_stat);
|
register_header_check(0x101, tar_header_gnu,sizeof(tar_header_gnu), &header_check_tar, file_stat);
|
||||||
|
#ifndef __FRAMAC__
|
||||||
register_header_check(0x101, tar_header_posix,sizeof(tar_header_posix), &header_check_tar, file_stat);
|
register_header_check(0x101, tar_header_posix,sizeof(tar_header_posix), &header_check_tar, file_stat);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,7 +25,32 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int header_check_tar(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);
|
struct tar_posix_header
|
||||||
|
{ /* byte offset */
|
||||||
|
char name[100]; /* 0 */
|
||||||
|
char mode[8]; /* 100 */
|
||||||
|
char uid[8]; /* 108 */
|
||||||
|
char gid[8]; /* 116 */
|
||||||
|
char size[12]; /* 124 */
|
||||||
|
char mtime[12]; /* 136 */
|
||||||
|
char chksum[8]; /* 148 */
|
||||||
|
char typeflag; /* 156 */
|
||||||
|
char linkname[100]; /* 157 */
|
||||||
|
char magic[6]; /* 257 */
|
||||||
|
char version[2]; /* 263 */
|
||||||
|
char uname[32]; /* 265 */
|
||||||
|
char gname[32]; /* 297 */
|
||||||
|
char devmajor[8]; /* 329 */
|
||||||
|
char devminor[8]; /* 337 */
|
||||||
|
char prefix[155]; /* 345 */
|
||||||
|
/* 500 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
@ requires \valid_read(h);
|
||||||
|
@ assigns \nothing;
|
||||||
|
@*/
|
||||||
|
int is_valid_tar_header(const struct tar_posix_header *h);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* closing brace for extern "C" */
|
} /* closing brace for extern "C" */
|
||||||
|
|
|
@ -103,7 +103,7 @@ pstatus_t photorec_find_blocksize(struct ph_param *params, const struct ph_optio
|
||||||
file_recovery_new.blocksize=blocksize;
|
file_recovery_new.blocksize=blocksize;
|
||||||
file_recovery_new.location.start=offset;
|
file_recovery_new.location.start=offset;
|
||||||
if(file_recovery.file_stat!=NULL && file_recovery.file_stat->file_hint==&file_hint_tar &&
|
if(file_recovery.file_stat!=NULL && file_recovery.file_stat->file_hint==&file_hint_tar &&
|
||||||
header_check_tar(buffer-0x200,0x200,0,&file_recovery,&file_recovery_new))
|
is_valid_tar_header((const struct tar_posix_header *)(buffer-0x200)))
|
||||||
{ /* Currently saving a tar, do not check the data for know header */
|
{ /* Currently saving a tar, do not check the data for know header */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -146,7 +146,7 @@ inline static pstatus_t photorec_check_header(file_recovery_t *file_recovery, st
|
||||||
file_recovery_new.blocksize=blocksize;
|
file_recovery_new.blocksize=blocksize;
|
||||||
file_recovery_new.location.start=offset;
|
file_recovery_new.location.start=offset;
|
||||||
if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_tar &&
|
if(file_recovery->file_stat!=NULL && file_recovery->file_stat->file_hint==&file_hint_tar &&
|
||||||
header_check_tar(buffer-0x200,0x200, 0, file_recovery, &file_recovery_new))
|
is_valid_tar_header((const struct tar_posix_header *)(buffer-0x200)))
|
||||||
{ /* Currently saving a tar, do not check the data for know header */
|
{ /* Currently saving a tar, do not check the data for know header */
|
||||||
if(options->verbose > 1)
|
if(options->verbose > 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,7 +98,7 @@ pstatus_t QPhotorec::photorec_find_blocksize(alloc_data_t *list_search_space)
|
||||||
{
|
{
|
||||||
file_recovery_t file_recovery_new;
|
file_recovery_t file_recovery_new;
|
||||||
if(file_recovery.file_stat!=NULL && file_recovery.file_stat->file_hint==&file_hint_tar &&
|
if(file_recovery.file_stat!=NULL && file_recovery.file_stat->file_hint==&file_hint_tar &&
|
||||||
header_check_tar(buffer-0x200,0x200,0,&file_recovery,&file_recovery_new))
|
is_valid_tar_header((const struct tar_posix_header *)(buffer-0x200)))
|
||||||
{ /* Currently saving a tar, do not check the data for know header */
|
{ /* Currently saving a tar, do not check the data for know header */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue