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 JPG_SIZE_LIMIT (8 * 1024 * 1024)
#define PJG_APPVERSION1 (25)
#define PJG_APPVERSION2 (25)
struct packjpg_filter_data {
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);
}
/*
* Helper routine to bridge to packJPG C++ lib, without changing packJPG itself.
*/
int
pjg_version_supported(char ver)
{
return (ver >= PJG_APPVERSION1 && ver <= PJG_APPVERSION2);
}
ssize_t
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);
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.
* 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,
len, fi->block_size));
}

View file

@ -1393,13 +1393,15 @@ detect_type_by_ext(const char *path, int pathlen)
ub4 slot;
int i, len;
uint64_t extnum;
char extl[8];
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
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];
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
extnum = 0;
@ -1454,6 +1456,10 @@ out:
/*
* 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
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
/*
* Helper routine to bridge to packJPG C++ lib, without changing packJPG itself.
*/
size_t
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 > 4) pctx->enable_delta2_encode = 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) {
pctx->preprocess_mode = 1;