diff src/share/native/sun/awt/medialib/awt_ImagingLib.c @ 6381:2a9c79db0040

8012597: Better image channel verification Reviewed-by: ahgross, vadim, prr
author bae
date Tue, 30 Apr 2013 04:20:46 +0400
parents b79d56eee18e
children c103e0918d60 26edfc8182bb
line wrap: on
line diff
--- a/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Tue Apr 30 12:25:32 2013 -0700
+++ b/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Tue Apr 30 04:20:46 2013 +0400
@@ -2604,6 +2604,41 @@
     return 0;
 }
 
+#define ERR_BAD_IMAGE_LAYOUT (-2)
+
+#define CHECK_DST_ARRAY(start_offset, elements_per_pixel)             \
+    do {                                                              \
+        int offset = (start_offset);                                  \
+        int lastScanOffset;                                           \
+                                                                      \
+        if (!SAFE_TO_MULT(rasterP->scanlineStride,                    \
+                          (rasterP->height - 1)))                     \
+        {                                                             \
+            return ERR_BAD_IMAGE_LAYOUT;                              \
+        }                                                             \
+        lastScanOffset = rasterP->scanlineStride *                    \
+            (rasterP->height - 1);                                    \
+                                                                      \
+        if (!SAFE_TO_ADD(offset, lastScanOffset)) {                   \
+            return ERR_BAD_IMAGE_LAYOUT;                              \
+        }                                                             \
+        lastScanOffset += offset;                                     \
+                                                                      \
+        if (!SAFE_TO_MULT((elements_per_pixel), rasterP->width)) {    \
+            return ERR_BAD_IMAGE_LAYOUT;                              \
+        }                                                             \
+        offset = (elements_per_pixel) * rasterP->width;               \
+                                                                      \
+        if (!SAFE_TO_ADD(offset, lastScanOffset)) {                   \
+            return ERR_BAD_IMAGE_LAYOUT;                              \
+        }                                                             \
+        lastScanOffset += offset;                                     \
+                                                                      \
+        if (dataArrayLength < lastScanOffset) {                       \
+            return ERR_BAD_IMAGE_LAYOUT;                              \
+        }                                                             \
+    } while(0);                                                       \
+
 static int
 storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
                 mlib_image *mlibImP) {
@@ -2611,6 +2646,7 @@
     unsigned char *cmDataP, *dataP, *cDataP;
     HintS_t *hintP = &dstP->hints;
     RasterS_t *rasterP = &dstP->raster;
+    jsize dataArrayLength = (*env)->GetArrayLength(env, rasterP->jdata);
     int y;
 
     /* REMIND: Store mlib data type? */
@@ -2629,14 +2665,15 @@
 
     if (hintP->packing == BYTE_INTERLEAVED) {
         /* Write it back to the destination */
+        CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
         cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
         mStride = mlib_ImageGetStride(mlibImP);
         dataP = (unsigned char *)(*env)->GetPrimitiveArrayCritical(env,
                                                       rasterP->jdata, NULL);
         if (dataP == NULL) return 0;
-        cDataP = dataP + hintP->dataOffset;
+        cDataP = dataP + hintP->channelOffset;
         for (y=0; y < rasterP->height;
-             y++, cmDataP += mStride, cDataP += hintP->sStride)
+             y++, cmDataP += mStride, cDataP += rasterP->scanlineStride)
         {
             memcpy(cDataP, cmDataP, rasterP->width*hintP->numChans);
         }
@@ -2647,13 +2684,14 @@
         /* Write it back to the destination */
         unsigned short *sdataP, *sDataP;
         unsigned short *smDataP = (unsigned short *)mlib_ImageGetData(mlibImP);
+        CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
         mStride = mlib_ImageGetStride(mlibImP);
         sdataP = (unsigned short *)(*env)->GetPrimitiveArrayCritical(env,
                                                       rasterP->jdata, NULL);
         if (sdataP == NULL) return -1;
-        sDataP = sdataP + hintP->dataOffset;
+        sDataP = sdataP + hintP->channelOffset;
         for (y=0; y < rasterP->height;
-             y++, smDataP += mStride, sDataP += hintP->sStride)
+            y++, smDataP += mStride, sDataP += rasterP->scanlineStride)
         {
             memcpy(sDataP, smDataP, rasterP->width*hintP->numChans);
         }
@@ -3446,7 +3484,8 @@
     unsigned char *inP = inDataP;
     unsigned char *lineOutP, *outP;
     jarray jOutDataP;
-    jint   *outDataP;
+    jsize dataArrayLength;
+    unsigned char *outDataP;
     int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
 
     if (rasterP->numBands > MAX_NUMBANDS) {
@@ -3455,11 +3494,18 @@
 
     /* Grab data ptr, strides, offsets from raster */
     jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
+    if (JNU_IsNull(env, jOutDataP)) {
+        return -1;
+    }
+
+    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
+    CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+
     outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
     if (outDataP == NULL) {
         return -1;
     }
-    lineOutP =  (unsigned char *)outDataP + rasterP->chanOffsets[0];
+    lineOutP = outDataP + rasterP->chanOffsets[0];
 
     if (component < 0) {
         for (c=0; c < rasterP->numBands; c++) {
@@ -3514,7 +3560,8 @@
     unsigned char *inP = inDataP;
     unsigned short *lineOutP, *outP;
     jarray jOutDataP;
-    jint   *outDataP;
+    jsize dataArrayLength;
+    unsigned short *outDataP;
     int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
 
     if (rasterP->numBands > MAX_NUMBANDS) {
@@ -3523,11 +3570,18 @@
 
     /* Grab data ptr, strides, offsets from raster */
     jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
+    if (JNU_IsNull(env, jOutDataP)) {
+        return -1;
+    }
+
+    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
+    CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+
     outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
     if (outDataP == NULL) {
         return -1;
     }
-    lineOutP =  (unsigned short *)outDataP + rasterP->chanOffsets[0];
+    lineOutP = outDataP + rasterP->chanOffsets[0];
 
     if (component < 0) {
         for (c=0; c < rasterP->numBands; c++) {
@@ -3582,7 +3636,8 @@
     unsigned char *inP = inDataP;
     unsigned int *lineOutP, *outP;
     jarray jOutDataP;
-    jint   *outDataP;
+    jsize dataArrayLength;
+    unsigned int *outDataP;
     int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
 
     if (rasterP->numBands > MAX_NUMBANDS) {
@@ -3591,11 +3646,18 @@
 
     /* Grab data ptr, strides, offsets from raster */
     jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
+    if (JNU_IsNull(env, jOutDataP)) {
+        return -1;
+    }
+
+    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
+    CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+
     outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
     if (outDataP == NULL) {
         return -1;
     }
-    lineOutP =  (unsigned int *)outDataP + rasterP->chanOffsets[0];
+    lineOutP = outDataP + rasterP->chanOffsets[0];
 
     if (component < 0) {
         for (c=0; c < rasterP->numBands; c++) {
@@ -3652,7 +3714,8 @@
     unsigned char *inP = inDataP;
     unsigned char *lineOutP, *outP;
     jarray jOutDataP;
-    jint   *outDataP;
+    jsize  dataArrayLength;
+    unsigned char *outDataP;
     int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
     int a = rasterP->numBands - 1;
 
@@ -3662,11 +3725,18 @@
 
     /* Grab data ptr, strides, offsets from raster */
     jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_BCRdataID);
+    if (JNU_IsNull(env, jOutDataP)) {
+        return -1;
+    }
+
+    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
+    CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+
     outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
     if (outDataP == NULL) {
         return -1;
     }
-    lineOutP =  (unsigned char *)outDataP + rasterP->chanOffsets[0];
+    lineOutP = outDataP + rasterP->chanOffsets[0];
 
     if (component < 0) {
         for (c=0; c < rasterP->numBands; c++) {
@@ -3742,7 +3812,8 @@
     unsigned char *inP = inDataP;
     unsigned short *lineOutP, *outP;
     jarray jOutDataP;
-    jint   *outDataP;
+    jsize dataArrayLength;
+    unsigned short *outDataP;
     int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
     int a = rasterP->numBands - 1;
 
@@ -3752,11 +3823,17 @@
 
     /* Grab data ptr, strides, offsets from raster */
     jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_SCRdataID);
+    if (JNU_IsNull(env, jOutDataP)) {
+        return -1;
+    }
+    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
+    CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+
     outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
     if (outDataP == NULL) {
         return -1;
     }
-    lineOutP =  (unsigned short *)outDataP + rasterP->chanOffsets[0];
+    lineOutP = outDataP + rasterP->chanOffsets[0];
 
     if (component < 0) {
         for (c=0; c < rasterP->numBands; c++) {
@@ -3832,7 +3909,8 @@
     unsigned char *inP = inDataP;
     unsigned int *lineOutP, *outP;
     jarray jOutDataP;
-    jint   *outDataP;
+    jsize dataArrayLength;
+    unsigned int *outDataP;
     int loff[MAX_NUMBANDS], roff[MAX_NUMBANDS];
     int a = rasterP->numBands - 1;
 
@@ -3842,11 +3920,18 @@
 
     /* Grab data ptr, strides, offsets from raster */
     jOutDataP = (*env)->GetObjectField(env, rasterP->jraster, g_ICRdataID);
+    if (JNU_IsNull(env, jOutDataP)) {
+        return -1;
+    }
+
+    dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
+    CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+
     outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
     if (outDataP == NULL) {
         return -1;
     }
-    lineOutP =  (unsigned int *)outDataP + rasterP->chanOffsets[0];
+    lineOutP = outDataP + rasterP->chanOffsets[0];
 
     if (component < 0) {
         for (c=0; c < rasterP->numBands; c++) {