[1.5] Import patch from trunk to make test passes. Affects: NR-DEC-2977.pdf.asan.67.2198.jp2-52-decode & NR-DEC-4149.pdf.SIGSEGV.cf7.3501.jp2-50-decode

This commit is contained in:
Mathieu Malaterre 2014-03-18 14:05:44 +00:00
parent 69cd4f9211
commit 910af7edec
2 changed files with 94 additions and 1 deletions

View File

@ -737,6 +737,84 @@ opj_bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio, opj_jp2_color_t *color)
}/* jp2_read_jp2h() */ }/* jp2_read_jp2h() */
static opj_bool opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_common_ptr cinfo)
{
int i;
/* testcase 4149.pdf.SIGSEGV.cf7.3501 */
if (color->jp2_cdef) {
opj_jp2_cdef_info_t *info = color->jp2_cdef->info;
int n = color->jp2_cdef->n;
for (i = 0; i < n; i++) {
if (info[i].cn >= image->numcomps) {
opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps);
return OPJ_FALSE;
}
if (info[i].asoc > 0 && (info[i].asoc - 1) >= image->numcomps) {
opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps);
return OPJ_FALSE;
}
}
}
/* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and
66ea31acbb0f23a2bbc91f64d69a03f5_signal_sigsegv_13937c0_7030_5725.pdf */
if (color->jp2_pclr && color->jp2_pclr->cmap) {
int nr_channels = color->jp2_pclr->nr_channels;
opj_jp2_cmap_comp_t *cmap = color->jp2_pclr->cmap;
opj_bool *pcol_usage, is_sane = OPJ_TRUE;
/* verify that all original components match an existing one */
for (i = 0; i < nr_channels; i++) {
if (cmap[i].cmp >= image->numcomps) {
opj_event_msg(cinfo, EVT_ERROR, "Invalid component index %d (>= %d).\n", cmap[i].cmp, image->numcomps);
is_sane = OPJ_FALSE;
}
}
pcol_usage = opj_calloc(nr_channels, sizeof(opj_bool));
if (!pcol_usage) {
opj_event_msg(cinfo, EVT_ERROR, "Unexpected OOM.\n");
return OPJ_FALSE;
}
/* verify that no component is targeted more than once */
for (i = 0; i < nr_channels; i++) {
int pcol = cmap[i].pcol;
assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1);
if (pcol >= nr_channels) {
opj_event_msg(cinfo, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol);
is_sane = OPJ_FALSE;
}
else if (pcol_usage[pcol] && cmap[i].mtyp == 1) {
opj_event_msg(cinfo, EVT_ERROR, "Component %d is mapped twice.\n", pcol);
is_sane = OPJ_FALSE;
}
else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) {
/* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then
* the value of this field shall be 0. */
opj_event_msg(cinfo, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i, pcol);
is_sane = OPJ_FALSE;
}
else
pcol_usage[pcol] = OPJ_TRUE;
}
/* verify that all components are targeted at least once */
for (i = 0; i < nr_channels; i++) {
if (!pcol_usage[i] && cmap[i].mtyp != 0) {
opj_event_msg(cinfo, EVT_ERROR, "Component %d doesn't have a mapping.\n", i);
is_sane = OPJ_FALSE;
}
}
opj_free(pcol_usage);
if (!is_sane) {
return OPJ_FALSE;
}
}
return OPJ_TRUE;
}
opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
opj_codestream_info_t *cstr_info) opj_codestream_info_t *cstr_info)
{ {
@ -770,6 +848,10 @@ opj_image_t* opj_jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio,
} }
if (!jp2->ignore_pclr_cmap_cdef){ if (!jp2->ignore_pclr_cmap_cdef){
if (!opj_jp2_check_color(image, &color, cinfo)) {
opj_event_msg(cinfo, EVT_ERROR, "Failed to decode PCRL box\n");
return NULL;
}
/* Set Image Color Space */ /* Set Image Color Space */
if (jp2->enumcs == 16) if (jp2->enumcs == 16)

View File

@ -32,6 +32,7 @@
#define _ISOC99_SOURCE /* lrintf is C99 */ #define _ISOC99_SOURCE /* lrintf is C99 */
#include "opj_includes.h" #include "opj_includes.h"
#include <assert.h>
void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) { void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
int tileno, compno, resno, bandno, precno;/*, cblkno;*/ int tileno, compno, resno, bandno, precno;/*, cblkno;*/
@ -1493,10 +1494,18 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
int tw = tilec->x1 - tilec->x0; int tw = tilec->x1 - tilec->x0;
int w = imagec->w; int w = imagec->w;
int i, j;
int offset_x = int_ceildivpow2(imagec->x0, imagec->factor); int offset_x = int_ceildivpow2(imagec->x0, imagec->factor);
int offset_y = int_ceildivpow2(imagec->y0, imagec->factor); int offset_y = int_ceildivpow2(imagec->y0, imagec->factor);
if( res->x0 > offset_x || offset_x > res->x1
|| res->y0 > offset_y || offset_y > res->y1 )
{
opj_event_msg(tcd->cinfo, EVT_ERROR, "Impossible offsets\n");
return OPJ_FALSE;
}
assert( res->x0 <= offset_x && offset_x <= res->x1 );
assert( res->y0 <= offset_y && offset_y <= res->y1 );
int i, j;
if(!imagec->data){ if(!imagec->data){
imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int)); imagec->data = (int*) opj_malloc(imagec->w * imagec->h * sizeof(int));
} }
@ -1510,6 +1519,7 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
for(i = res->x0; i < res->x1; ++i) { for(i = res->x0; i < res->x1; ++i) {
int v = tilec->data[i - res->x0 + (j - res->y0) * tw]; int v = tilec->data[i - res->x0 + (j - res->y0) * tw];
v += adjust; v += adjust;
/*assert( (i - offset_x) + (j - offset_y) * w >= 0 );*/
imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
} }
} }
@ -1519,6 +1529,7 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw]; float tmp = ((float*)tilec->data)[i - res->x0 + (j - res->y0) * tw];
int v = lrintf(tmp); int v = lrintf(tmp);
v += adjust; v += adjust;
/*assert( (i - offset_x) + (j - offset_y) * w >= 0 );*/
imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max); imagec->data[(i - offset_x) + (j - offset_y) * w] = int_clamp(v, min, max);
} }
} }