opj_free(color->jp2_pclr); color->jp2_pclr = NULL;
}
+static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *p_manager)
+{
+ OPJ_UINT16 i;
+
+ /* testcase 4149.pdf.SIGSEGV.cf7.3501 */
+ if (color->jp2_cdef) {
+ opj_jp2_cdef_info_t *info = color->jp2_cdef->info;
+ OPJ_UINT16 n = color->jp2_cdef->n;
+
+ for (i = 0; i < n; i++) {
+ if (info[i].cn >= image->numcomps) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps);
+ return OPJ_FALSE;
+ }
+ if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= image->numcomps) {
+ opj_event_msg(p_manager, 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) {
+ OPJ_UINT16 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(p_manager, 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(p_manager, EVT_ERROR, "Unexpected OOM.\n");
+ return OPJ_FALSE;
+ }
+ /* verify that no component is targeted more than once */
+ for (i = 0; i < nr_channels; i++) {
+ OPJ_UINT16 pcol = cmap[i].pcol;
+ if (pcol >= nr_channels) {
+ opj_event_msg(p_manager, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol);
+ is_sane = OPJ_FALSE;
+ }
+ else if (pcol_usage[pcol]) {
+ opj_event_msg(p_manager, EVT_ERROR, "Component %d is mapped twice.\n", 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]) {
+ opj_event_msg(p_manager, 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;
+}
+
void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
{
opj_image_comp_t *old_comps, *new_comps;
for(i = 0; i < nr_channels; ++i) {
OPJ_INT32 bytes_to_read = (channel_size[i]+7)>>3;
+ 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 + bytes_to_read)
+ return OPJ_FALSE;
+
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 + bytes_to_read)
return OPJ_FALSE;
}
+ if (p_cmap_header_size < (OPJ_UINT32)nr_channels * 4) {
+ opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CMAP box.\n");
+ return OPJ_FALSE;
+ }
+
cmap = (opj_jp2_cmap_comp_t*) opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t));
if (!cmap)
return OPJ_FALSE;
return OPJ_FALSE;
}
+ if (p_cdef_header_size < 2) {
+ opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
+ return OPJ_FALSE;
+ }
+
opj_read_bytes(p_cdef_header_data,&l_value ,2); /* N */
p_cdef_header_data+= 2;
return OPJ_FALSE;
}
+ if (p_cdef_header_size < 2 + (OPJ_UINT32)(OPJ_UINT16)l_value * 6) {
+ opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n");
+ return OPJ_FALSE;
+ }
+
cdef_info = (opj_jp2_cdef_info_t*) opj_malloc(l_value * sizeof(opj_jp2_cdef_info_t));
if (!cdef_info)
return OPJ_FALSE;
++p_colr_header_data;
if (jp2->meth == 1) {
- if (p_colr_header_size != 7) {
- opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n");
+ if (p_colr_header_size < 7) {
+ opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
return OPJ_FALSE;
}
+ if (p_colr_header_size > 7) {
+ /* testcase Altona_Technical_v20_x4.pdf */
+ opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (bad size: %d)\n", p_colr_header_size);
+ }
opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4); /* EnumCS */
}
if (!jp2->ignore_pclr_cmap_cdef){
+ if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) {
+ return OPJ_FALSE;
+ }
/* Set Image Color Space */
if (jp2->enumcs == 16)
return OPJ_FALSE;
}
+ if (!opj_jp2_check_color(p_image, &(p_jp2->color), p_manager)) {
+ return OPJ_FALSE;
+ }
+
/* Set Image Color Space */
if (p_jp2->enumcs == 16)
p_image->color_space = OPJ_CLRSPC_SRGB;