Fix crash on Windows due to b7594c0fcb9dd3aa6356d72c4a525d76168da689
authorEven Rouault <even.rouault@spatialys.com>
Wed, 5 Jul 2017 23:05:24 +0000 (01:05 +0200)
committerEven Rouault <even.rouault@spatialys.com>
Mon, 7 Aug 2017 16:32:49 +0000 (18:32 +0200)
b7594c0fcb9dd3aa6356d72c4a525d76168da689 may put opj_tcd_tilecomp_t->data
allocated by opj_alloc_tile_component_data() as the image->comps[].data. As
opj_alloc_tile_component_data() use opj_aligned_malloc() we must be sure to
ue opj_alined_malloc()/_free() in all places where we alloc/free
image->comps[].data.

Note: this might have some compatibility impact in case user code does itself
the allocation/free of image->comps[].data

src/lib/openjp2/image.c
src/lib/openjp2/j2k.c

index d00a23701b1545be80a673f1929794bfee062857..ecd65eceb373e154e3d3f10f312503a82861f8fb 100644 (file)
@@ -68,19 +68,21 @@ opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts,
             comp->prec = cmptparms[compno].prec;
             comp->bpp = cmptparms[compno].bpp;
             comp->sgnd = cmptparms[compno].sgnd;
-            if (comp->h != 0 && (OPJ_SIZE_T)comp->w > SIZE_MAX / comp->h) {
+            if (comp->h != 0 &&
+                    (OPJ_SIZE_T)comp->w > SIZE_MAX / comp->h / sizeof(OPJ_INT32)) {
                 // TODO event manager
                 opj_image_destroy(image);
                 return NULL;
             }
-            comp->data = (OPJ_INT32*) opj_calloc((OPJ_SIZE_T)comp->w * comp->h,
-                                                 sizeof(OPJ_INT32));
+            comp->data = (OPJ_INT32*) opj_aligned_malloc(
+                             (size_t)comp->w * comp->h * sizeof(OPJ_INT32));
             if (!comp->data) {
                 /* TODO replace with event manager, breaks API */
                 /* fprintf(stderr,"Unable to allocate memory for image.\n"); */
                 opj_image_destroy(image);
                 return NULL;
             }
+            memset(comp->data, 0, (size_t)comp->w * comp->h * sizeof(OPJ_INT32));
         }
     }
 
@@ -97,7 +99,7 @@ void OPJ_CALLCONV opj_image_destroy(opj_image_t *image)
             for (compno = 0; compno < image->numcomps; compno++) {
                 opj_image_comp_t *image_comp = &(image->comps[compno]);
                 if (image_comp->data) {
-                    opj_free(image_comp->data);
+                    opj_aligned_free(image_comp->data);
                 }
             }
             opj_free(image->comps);
index b665924d01bd5676d6fab72a6c86435840d174f8..afbcc9c55e7fcd34a93eaaaa9012dd1111aea9b0 100644 (file)
@@ -8798,15 +8798,18 @@ static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd, OPJ_BYTE * p_data,
             OPJ_SIZE_T l_width = l_img_comp_dest->w;
             OPJ_SIZE_T l_height = l_img_comp_dest->h;
 
-            if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height))) {
+            if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height)) ||
+                    l_width * l_height > SIZE_MAX / sizeof(OPJ_INT32)) {
                 /* would overflow */
                 return OPJ_FALSE;
             }
-            l_img_comp_dest->data = (OPJ_INT32*) opj_calloc(l_width * l_height,
+            l_img_comp_dest->data = (OPJ_INT32*) opj_aligned_malloc(l_width * l_height *
                                     sizeof(OPJ_INT32));
             if (! l_img_comp_dest->data) {
                 return OPJ_FALSE;
             }
+            /* Do we really need this memset ? */
+            memset(l_img_comp_dest->data, 0, l_width * l_height * sizeof(OPJ_INT32));
         }
 
         /* Copy info from decoded comp image to output image */
@@ -10416,7 +10419,7 @@ static OPJ_BOOL opj_j2k_decode_tiles(opj_j2k_t *p_j2k,
 
         /* Transfer TCD data to output image data */
         for (i = 0; i < p_j2k->m_output_image->numcomps; i++) {
-            opj_free(p_j2k->m_output_image->comps[i].data);
+            opj_aligned_free(p_j2k->m_output_image->comps[i].data);
             p_j2k->m_output_image->comps[i].data =
                 p_j2k->m_tcd->tcd_image->tiles->comps[i].data;
             p_j2k->m_output_image->comps[i].resno_decoded =
@@ -10821,7 +10824,7 @@ OPJ_BOOL opj_j2k_get_tile(opj_j2k_t *p_j2k,
             p_j2k->m_output_image->comps[compno].resno_decoded;
 
         if (p_image->comps[compno].data) {
-            opj_free(p_image->comps[compno].data);
+            opj_aligned_free(p_image->comps[compno].data);
         }
 
         p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data;