提交 f1409fc8 编写于 作者: B bae

6925710: IndexColorModel.finalize can be made to double free

Reviewed-by: igor, prr, hawtin
上级 a1cedac9
...@@ -129,6 +129,8 @@ public class IndexColorModel extends ColorModel { ...@@ -129,6 +129,8 @@ public class IndexColorModel extends ColorModel {
private boolean allgrayopaque; private boolean allgrayopaque;
private BigInteger validBits; private BigInteger validBits;
private sun.awt.image.BufImgSurfaceData.ICMColorData colorData = null;
private static int[] opaqueBits = {8, 8, 8}; private static int[] opaqueBits = {8, 8, 8};
private static int[] alphaBits = {8, 8, 8, 8}; private static int[] alphaBits = {8, 8, 8, 8};
...@@ -1511,7 +1513,6 @@ public class IndexColorModel extends ColorModel { ...@@ -1511,7 +1513,6 @@ public class IndexColorModel extends ColorModel {
* longer referenced. * longer referenced.
*/ */
public void finalize() { public void finalize() {
sun.awt.image.BufImgSurfaceData.freeNativeICMData(this);
} }
/** /**
......
...@@ -49,7 +49,7 @@ public class BufImgSurfaceData extends SurfaceData { ...@@ -49,7 +49,7 @@ public class BufImgSurfaceData extends SurfaceData {
private BufferedImageGraphicsConfig graphicsConfig; private BufferedImageGraphicsConfig graphicsConfig;
RenderLoops solidloops; RenderLoops solidloops;
private static native void initIDs(Class ICM); private static native void initIDs(Class ICM, Class ICMColorData);
private static final int DCM_RGBX_RED_MASK = 0xff000000; private static final int DCM_RGBX_RED_MASK = 0xff000000;
private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000; private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000;
...@@ -67,7 +67,7 @@ public class BufImgSurfaceData extends SurfaceData { ...@@ -67,7 +67,7 @@ public class BufImgSurfaceData extends SurfaceData {
private static final int DCM_ARGBBM_BLUE_MASK = 0x000000ff; private static final int DCM_ARGBBM_BLUE_MASK = 0x000000ff;
static { static {
initIDs(IndexColorModel.class); initIDs(IndexColorModel.class, ICMColorData.class);
} }
public static SurfaceData createData(BufferedImage bufImg) { public static SurfaceData createData(BufferedImage bufImg) {
...@@ -403,7 +403,7 @@ public class BufImgSurfaceData extends SurfaceData { ...@@ -403,7 +403,7 @@ public class BufImgSurfaceData extends SurfaceData {
// their pixels are immediately retrievable anyway. // their pixels are immediately retrievable anyway.
} }
public static native void freeNativeICMData(IndexColorModel icm); private static native void freeNativeICMData(long pData);
/** /**
* Returns destination Image associated with this SurfaceData. * Returns destination Image associated with this SurfaceData.
...@@ -411,4 +411,19 @@ public class BufImgSurfaceData extends SurfaceData { ...@@ -411,4 +411,19 @@ public class BufImgSurfaceData extends SurfaceData {
public Object getDestination() { public Object getDestination() {
return bufImg; return bufImg;
} }
public static final class ICMColorData {
private long pData = 0L;
private ICMColorData(long pData) {
this.pData = pData;
}
public void finalize() {
if (pData != 0L) {
BufImgSurfaceData.freeNativeICMData(pData);
pData = 0L;
}
}
}
} }
...@@ -48,9 +48,12 @@ static ColorData *BufImg_SetupICM(JNIEnv *env, BufImgSDOps *bisdo); ...@@ -48,9 +48,12 @@ static ColorData *BufImg_SetupICM(JNIEnv *env, BufImgSDOps *bisdo);
static jfieldID rgbID; static jfieldID rgbID;
static jfieldID mapSizeID; static jfieldID mapSizeID;
static jfieldID CMpDataID; static jfieldID colorDataID;
static jfieldID pDataID;
static jfieldID allGrayID; static jfieldID allGrayID;
static jclass clsICMCD;
static jmethodID initICMCDmID;
/* /*
* Class: sun_awt_image_BufImgSurfaceData * Class: sun_awt_image_BufImgSurfaceData
* Method: initIDs * Method: initIDs
...@@ -58,18 +61,23 @@ static jfieldID allGrayID; ...@@ -58,18 +61,23 @@ static jfieldID allGrayID;
*/ */
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_sun_awt_image_BufImgSurfaceData_initIDs Java_sun_awt_image_BufImgSurfaceData_initIDs
(JNIEnv *env, jclass bisd, jclass icm) (JNIEnv *env, jclass bisd, jclass icm, jclass cd)
{ {
if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) { if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
JNU_ThrowInternalError(env, "Private RasInfo structure too large!"); JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
return; return;
} }
clsICMCD = (*env)->NewWeakGlobalRef(env, cd);
initICMCDmID = (*env)->GetMethodID(env, cd, "<init>", "(J)V");
pDataID = (*env)->GetFieldID(env, cd, "pData", "J");
rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I"); rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I");
allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z"); allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z");
mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I"); mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I");
CMpDataID = (*env)->GetFieldID(env, icm, "pData", "J"); colorDataID = (*env)->GetFieldID(env, icm, "colorData",
if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || CMpDataID == 0) { "Lsun/awt/image/BufImgSurfaceData$ICMColorData;");
if (allGrayID == 0 || rgbID == 0 || mapSizeID == 0 || pDataID == 0|| colorDataID == 0 || initICMCDmID == 0) {
JNU_ThrowInternalError(env, "Could not get field IDs"); JNU_ThrowInternalError(env, "Could not get field IDs");
} }
} }
...@@ -81,18 +89,9 @@ Java_sun_awt_image_BufImgSurfaceData_initIDs ...@@ -81,18 +89,9 @@ Java_sun_awt_image_BufImgSurfaceData_initIDs
*/ */
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_sun_awt_image_BufImgSurfaceData_freeNativeICMData Java_sun_awt_image_BufImgSurfaceData_freeNativeICMData
(JNIEnv *env, jclass sd, jobject icm) (JNIEnv *env, jclass sd, jlong pData)
{ {
jlong pData; ColorData *cdata = (ColorData*)jlong_to_ptr(pData);
ColorData *cdata;
if (JNU_IsNull(env, icm)) {
JNU_ThrowNullPointerException(env, "IndexColorModel cannot be null");
return;
}
pData = (*env)->GetLongField (env, icm, CMpDataID);
cdata = (ColorData *)pData;
freeICMColorData(cdata); freeICMColorData(cdata);
} }
...@@ -259,15 +258,28 @@ static void BufImg_Release(JNIEnv *env, ...@@ -259,15 +258,28 @@ static void BufImg_Release(JNIEnv *env,
static ColorData *BufImg_SetupICM(JNIEnv *env, static ColorData *BufImg_SetupICM(JNIEnv *env,
BufImgSDOps *bisdo) BufImgSDOps *bisdo)
{ {
ColorData *cData; ColorData *cData = NULL;
jobject colorData;
if (JNU_IsNull(env, bisdo->icm)) { if (JNU_IsNull(env, bisdo->icm)) {
return (ColorData *) NULL; return (ColorData *) NULL;
} }
cData = (ColorData *) JNU_GetLongFieldAsPtr(env, bisdo->icm, CMpDataID); colorData = (*env)->GetObjectField(env, bisdo->icm, colorDataID);
if (JNU_IsNull(env, colorData)) {
if (JNU_IsNull(env, clsICMCD)) {
// we are unable to create a wrapper object
return (ColorData*)NULL;
}
} else {
cData = (ColorData*)JNU_GetLongFieldAsPtr(env, colorData, pDataID);
}
if (cData != NULL) {
return cData;
}
if (cData == NULL) {
cData = (ColorData*)calloc(1, sizeof(ColorData)); cData = (ColorData*)calloc(1, sizeof(ColorData));
if (cData != NULL) { if (cData != NULL) {
...@@ -284,7 +296,10 @@ static ColorData *BufImg_SetupICM(JNIEnv *env, ...@@ -284,7 +296,10 @@ static ColorData *BufImg_SetupICM(JNIEnv *env,
initDitherTables(cData); initDitherTables(cData);
JNU_SetLongFieldFromPtr(env, bisdo->icm, CMpDataID, cData); if (JNU_IsNull(env, colorData)) {
jlong pData = ptr_to_jlong(cData);
colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData);
(*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册