Add more robust checks for Jpeg and packJPG format files in filter routine.

Use case-insensitive checks for extension names.
Enable more features based on compression level, when archiving.
This commit is contained in:
Moinak Ghosh 2013-12-08 23:24:06 +05:30
parent 733e6f8245
commit 393fd790b0
4 changed files with 37 additions and 9 deletions

View file

@ -44,6 +44,8 @@
#define PACKJPG_DEF_BUFSIZ (512 * 1024) #define PACKJPG_DEF_BUFSIZ (512 * 1024)
#define JPG_SIZE_LIMIT (8 * 1024 * 1024) #define JPG_SIZE_LIMIT (8 * 1024 * 1024)
#define PJG_APPVERSION1 (25)
#define PJG_APPVERSION2 (25)
struct packjpg_filter_data { struct packjpg_filter_data {
uchar_t *in_buff; uchar_t *in_buff;
@ -126,9 +128,12 @@ write_archive_data(struct archive *aw, uchar_t *out_buf, size_t len, int block_s
return (tot); return (tot);
} }
/* int
* Helper routine to bridge to packJPG C++ lib, without changing packJPG itself. pjg_version_supported(char ver)
*/ {
return (ver >= PJG_APPVERSION1 && ver <= PJG_APPVERSION2);
}
ssize_t ssize_t
packjpg_filter(struct filter_info *fi, void *filter_private) packjpg_filter(struct filter_info *fi, void *filter_private)
{ {
@ -150,9 +155,14 @@ packjpg_filter(struct filter_info *fi, void *filter_private)
} }
/* /*
* We are trying to compress and this is not a jpeg. Skip. * We are trying to compress and this is not a proper jpeg. Skip.
*/ */
if (mapbuf[0] != 0xFF && mapbuf[1] != 0xD8) { if (mapbuf[0] != 0xFF || mapbuf[1] != 0xD8) {
munmap(mapbuf, len);
return (FILTER_RETURN_SKIP);
}
if (strncmp((char *)&mapbuf[6], "Exif", 4) != 0 &&
strncmp((char *)&mapbuf[6], "JFIF", 4) != 0) {
munmap(mapbuf, len); munmap(mapbuf, len);
return (FILTER_RETURN_SKIP); return (FILTER_RETURN_SKIP);
} }
@ -187,9 +197,10 @@ packjpg_filter(struct filter_info *fi, void *filter_private)
/* /*
* We are trying to decompress and this is not a packJPG file. * We are trying to decompress and this is not a packJPG file.
* Write the raw data and skip. * Write the raw data and skip. Third byte in PackJPG file is
* version number. We also check if it is supported.
*/ */
if (mapbuf[0] != 'J' && mapbuf[1] != 'S') { if (mapbuf[0] != 'J' || mapbuf[1] != 'S' || !pjg_version_supported(mapbuf[2])) {
return (write_archive_data(fi->target_arc, pjdat->in_buff, return (write_archive_data(fi->target_arc, pjdat->in_buff,
len, fi->block_size)); len, fi->block_size));
} }

View file

@ -1393,13 +1393,15 @@ detect_type_by_ext(const char *path, int pathlen)
ub4 slot; ub4 slot;
int i, len; int i, len;
uint64_t extnum; uint64_t extnum;
char extl[8];
for (i = pathlen-1; i > 0 && path[i] != '.' && path[i] != PATHSEP_CHAR; i--); for (i = pathlen-1; i > 0 && path[i] != '.' && path[i] != PATHSEP_CHAR; i--);
if (i == 0 || path[i] != '.') goto out; // If extension not found give up if (i == 0 || path[i] != '.') goto out; // If extension not found give up
len = pathlen - i - 1; len = pathlen - i - 1;
if (len == 0) goto out; // If extension is empty give up if (len == 0 || len > 8) goto out; // If extension is empty give up
ext = &path[i+1]; ext = &path[i+1];
slot = phash(ext, len); for (i = 0; i < len; i++) extl[i] = tolower(ext[i]);
slot = phash(extl, len);
if (slot >= PHASHNKEYS) goto out; // Extension maps outside hash table range, give up if (slot >= PHASHNKEYS) goto out; // Extension maps outside hash table range, give up
extnum = 0; extnum = 0;
@ -1454,6 +1456,10 @@ out:
/* /*
* Detect a few file types from looking at magic signatures. * Detect a few file types from looking at magic signatures.
* NOTE: Jpeg files must be detected via '.jpg' or '.jpeg' (case-insensitive)
* extensions. Do not add Jpeg header detection here. it will break
* context based PackJPG processing. Jpeg files not have proper
* extension must not be processed via PackJPG.
*/ */
static int static int
detect_type_by_data(uchar_t *buf, size_t len) detect_type_by_data(uchar_t *buf, size_t len)

View file

@ -65,6 +65,9 @@ typedef unsigned char uchar_t;
#define POLAROID_LE 0x64696f72616c6f50 #define POLAROID_LE 0x64696f72616c6f50
/*
* Helper routine to bridge to packJPG C++ lib, without changing packJPG itself.
*/
size_t size_t
packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf) packjpg_filter_process(uchar_t *in_buf, size_t len, uchar_t **out_buf)
{ {

View file

@ -3230,6 +3230,14 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
if (pctx->level > 8) pctx->dispack_preprocess = 1; if (pctx->level > 8) pctx->dispack_preprocess = 1;
if (pctx->level > 4) pctx->enable_delta2_encode = 1; if (pctx->level > 4) pctx->enable_delta2_encode = 1;
if (pctx->level > 9) pctx->lzp_preprocess = 1; if (pctx->level > 9) pctx->lzp_preprocess = 1;
if (pctx->level > 3) {
pctx->enable_rabin_global = 1;
pctx->enable_rabin_scan = 1;
pctx->enable_rabin_split = 1;
pctx->rab_blk_size = 2;
if (pctx->level > 4) pctx->rab_blk_size = 1;
if (pctx->level > 8) pctx->rab_blk_size = 0;
}
} }
if (pctx->lzp_preprocess || pctx->enable_delta2_encode || pctx->dispack_preprocess) { if (pctx->lzp_preprocess || pctx->enable_delta2_encode || pctx->dispack_preprocess) {
pctx->preprocess_mode = 1; pctx->preprocess_mode = 1;