From c05a97332af5a18bdf450ba4028c00cdecbc9e54 Mon Sep 17 00:00:00 2001 From: jdv Date: Thu, 6 Oct 2016 09:19:32 -0700 Subject: [PATCH] 8162461: Hang due to JNI up-call made whilst holding JNI critical lock Reviewed-by: prr, aghaisas --- .../native/sun/awt/image/jpeg/imageioJPEG.c | 87 +++++++++++++------ 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c index 342fe265d..18c7cb189 100644 --- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c +++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -553,30 +553,43 @@ sun_jpeg_error_exit (j_common_ptr cinfo) METHODDEF(void) sun_jpeg_output_message (j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; - jstring string; - imageIODataPtr data = (imageIODataPtr) cinfo->client_data; - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - jobject theObject; - - /* Create the message */ - (*cinfo->err->format_message) (cinfo, buffer); - - // Create a new java string from the message - string = (*env)->NewStringUTF(env, buffer); - CHECK_NULL(string); - - theObject = data->imageIOobj; - - if (cinfo->is_decompressor) { - (*env)->CallVoidMethod(env, theObject, - JPEGImageReader_warningWithMessageID, - string); - } else { - (*env)->CallVoidMethod(env, theObject, - JPEGImageWriter_warningWithMessageID, - string); - } + char buffer[JMSG_LENGTH_MAX]; + jstring string; + imageIODataPtr data = (imageIODataPtr) cinfo->client_data; + JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + jobject theObject; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + + // Create a new java string from the message + string = (*env)->NewStringUTF(env, buffer); + CHECK_NULL(string); + + theObject = data->imageIOobj; + + if (cinfo->is_decompressor) { + struct jpeg_source_mgr *src = ((j_decompress_ptr)cinfo)->src; + RELEASE_ARRAYS(env, data, src->next_input_byte); + (*env)->CallVoidMethod(env, theObject, + JPEGImageReader_warningWithMessageID, + string); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit(cinfo); + } + } else { + struct jpeg_destination_mgr *dest = ((j_compress_ptr)cinfo)->dest; + RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); + (*env)->CallVoidMethod(env, theObject, + JPEGImageWriter_warningWithMessageID, + string); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, + (const JOCTET **)(&dest->next_output_byte))) { + cinfo->err->error_exit(cinfo); + } + } } /* End of verbatim copy from jpegdecoder.c */ @@ -1043,6 +1056,7 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo) if (!GET_ARRAYS(env, data, &(src->next_input_byte))) { cinfo->err->error_exit((j_common_ptr) cinfo); } + RELEASE_ARRAYS(env, data, src->next_input_byte); return; } @@ -1798,9 +1812,14 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader cinfo->out_color_space, cinfo->num_components, profileData); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } if (reset) { jpeg_abort_decompress(cinfo); } + RELEASE_ARRAYS(env, data, src->next_input_byte); } return retval; @@ -2011,6 +2030,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage jpeg_start_decompress(cinfo); if (numBands != cinfo->output_components) { + RELEASE_ARRAYS(env, data, src->next_input_byte); JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid argument to native readImage"); return data->abortFlag; @@ -2019,6 +2039,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage if (cinfo->output_components <= 0 || cinfo->image_width > (0xffffffffu / (unsigned int)cinfo->output_components)) { + RELEASE_ARRAYS(env, data, src->next_input_byte); JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid number of output components"); return data->abortFlag; @@ -2042,15 +2063,24 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage // the first interesting pass. jpeg_start_output(cinfo, cinfo->input_scan_number); if (wantUpdates) { + RELEASE_ARRAYS(env, data, src->next_input_byte); (*env)->CallVoidMethod(env, this, JPEGImageReader_passStartedID, cinfo->input_scan_number-1); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } } } else if (wantUpdates) { + RELEASE_ARRAYS(env, data, src->next_input_byte); (*env)->CallVoidMethod(env, this, JPEGImageReader_passStartedID, 0); - + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } } // Skip until the first interesting line @@ -2138,8 +2168,13 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage done = TRUE; } if (wantUpdates) { + RELEASE_ARRAYS(env, data, src->next_input_byte); (*env)->CallVoidMethod(env, this, JPEGImageReader_passCompleteID); + if ((*env)->ExceptionOccurred(env) + || !GET_ARRAYS(env, data, &(src->next_input_byte))) { + cinfo->err->error_exit((j_common_ptr) cinfo); + } } } -- GitLab