Index: core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c |
diff --git a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c |
index 683d0415cf0fe8231bfe7858f55daa80d98df37c..78a15026a970eae4402d0b540f5c2892ac779641 100644 |
--- a/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c |
+++ b/core/src/fxcodec/fx_libopenjpeg/libopenjpeg20/jp2.c |
@@ -764,6 +764,12 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, |
if (color->jp2_cdef) { |
opj_jp2_cdef_info_t *info = color->jp2_cdef->info; |
OPJ_UINT16 n = color->jp2_cdef->n; |
+ OPJ_UINT32 nr_channels = image->numcomps; /* FIXME image->numcomps == jp2->numcomps before color is applied ??? */ |
+ |
+ /* cdef applies to cmap channels if any */ |
+ if (color->jp2_pclr && color->jp2_pclr->cmap) { |
+ nr_channels = (OPJ_UINT32)color->jp2_pclr->nr_channels; |
+ } |
for (i = 0; i < n; i++) { |
if (info[i].cn >= image->numcomps) { |
@@ -775,6 +781,22 @@ static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, |
return OPJ_FALSE; |
} |
} |
+ |
+ /* issue 397 */ |
+ /* ISO 15444-1 states that if cdef is present, it shall contain a complete list of channel definitions. */ |
+ while (nr_channels > 0) |
+ { |
+ for(i = 0; i < n; ++i) { |
+ if ((OPJ_UINT32)info[i].cn == (nr_channels - 1U)) { |
+ break; |
+ } |
+ } |
+ if (i == n) { |
+ opj_event_msg(p_manager, EVT_ERROR, "Incomplete channel definitions.\n"); |
+ return OPJ_FALSE; |
+ } |
+ --nr_channels; |
+ } |
} |
/* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and |
@@ -1017,7 +1039,7 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2, |
if (bytes_to_read > sizeof(OPJ_UINT32)) |
bytes_to_read = sizeof(OPJ_UINT32); |
- if ((ptrdiff_t)p_pclr_header_size < p_pclr_header_data - orig_header_data + (ptrdiff_t)bytes_to_read) |
+ if ((ptrdiff_t)p_pclr_header_size < (ptrdiff_t)(p_pclr_header_data - orig_header_data) + (ptrdiff_t)bytes_to_read) |
return OPJ_FALSE; |
opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read); /* Cji */ |
@@ -1280,7 +1302,7 @@ OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2, |
} |
else if (jp2->meth > 2) |
{ |
- /* ISO/IEC 15444-1:2004 (E), Table I.9 Legal METH values: |
+ /* ISO/IEC 15444-1:2004 (E), Table I.9 Legal METH values: |
conforming JP2 reader shall ignore the entire Colour Specification box.*/ |
opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), " |
"so we will ignore the entire Colour Specification box. \n", jp2->meth); |
@@ -1843,7 +1865,7 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2, |
return OPJ_FALSE; |
} |
/* testcase 1851.pdf.SIGSEGV.ce9.948 */ |
- else if (box.length < l_nb_bytes_read) { |
+ else if (box.length < l_nb_bytes_read) { |
opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type); |
opj_free(l_current_data); |
return OPJ_FALSE; |
@@ -1853,6 +1875,12 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2, |
l_current_data_size = box.length - l_nb_bytes_read; |
if (l_current_handler != 00) { |
+ if ((OPJ_OFF_T)l_current_data_size > opj_stream_get_number_byte_left(stream)) { |
+ /* do not even try to malloc if we can't read */ |
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid box size %d for box '%c%c%c%c'. Need %d bytes, %d bytes remaining \n", box.length, (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0), l_current_data_size, (OPJ_UINT32)opj_stream_get_number_byte_left(stream)); |
+ opj_free(l_current_data); |
+ return OPJ_FALSE; |
+ } |
if (l_current_data_size > l_last_data_size) { |
OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size); |
if (!new_current_data) { |
@@ -2164,6 +2192,7 @@ static OPJ_BOOL opj_jp2_read_jp2h( opj_jp2_t *jp2, |
OPJ_UINT32 l_box_size=0, l_current_data_size = 0; |
opj_jp2_box_t box; |
const opj_jp2_header_handler_t * l_current_handler; |
+ OPJ_BOOL l_has_ihdr = 0; |
/* preconditions */ |
assert(p_header_data != 00); |
@@ -2204,10 +2233,19 @@ static OPJ_BOOL opj_jp2_read_jp2h( opj_jp2_t *jp2, |
jp2->jp2_img_state |= JP2_IMG_STATE_UNKNOWN; |
} |
+ if (box.type == JP2_IHDR) { |
+ l_has_ihdr = 1; |
+ } |
+ |
p_header_data += l_current_data_size; |
p_header_size -= box.length; |
} |
+ if (l_has_ihdr == 0) { |
+ opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box: no 'ihdr' box.\n"); |
+ return OPJ_FALSE; |
+ } |
+ |
jp2->jp2_state |= JP2_STATE_HEADER; |
return OPJ_TRUE; |
@@ -2276,7 +2314,10 @@ OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box, |
opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n"); |
return OPJ_FALSE; |
} |
- |
+ if (box->length < *p_number_bytes_read) { |
+ opj_event_msg(p_manager, EVT_ERROR, "Box length is inconsistent.\n"); |
+ return OPJ_FALSE; |
+ } |
return OPJ_TRUE; |
} |