Mercurial > hg > release > icedtea6-1.12
view patches/openjdk/6791502-invalid_icc_profile.patch @ 3024:3b654e7cbe51
Backport a number of JPEG fixes from 7u.
S4893408: JPEGReader throws IllegalArgException when setting the destination to BYTE_GRAY
S6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
S6791502: IIOException "Invalid icc profile" on jpeg after update from JDK5 to JDK6
S6793818: JpegImageReader is too greedy creating color profiles
S6888215: memory leak in jpeg plugin
S6989760: cmm native compiler warnings
S6989774: imageio compiler warnings in native code
S7013519: [parfait] Integer overflows in 2D code
S7018912: [parfait] potential buffer overruns in imageio jpeg
S8005194: [parfait] #353 sun/awt/image/jpeg/imageioJPEG.c Memory leak of pointer 'scale' allocated with calloc()
S8020983, RH976897: OutOfMemoryError caused by non garbage collected JPEGImageWriter Instances
2013-08-30 Andrew John Hughes <gnu.andrew@redhat.com>
* Makefile.am:
(ICEDTEA_PATCHES): Add new patches.
* NEWS: Updated with new patches.
* patches/imageiojpeg_sync.patch:
Bring in changes to imageioJPEG.c made between
the start of OpenJDK 6 and the start of OpenJDK 7's
hg repositories.
* patches/libraries.patch: Updated against patches below.
* patches/openjdk/4893408-jpegreader_byte_gray.patch,
* patches/openjdk/6631559-dont_load_libjpeg_to_register_imageio_plugins.patch,
* patches/openjdk/6791502-invalid_icc_profile.patch,
* patches/openjdk/6793818-jpegimagereader_too_greedy.patch,
* patches/openjdk/6888215-jpeg_memory_leak.patch,
* patches/openjdk/6989760-native_warnings.patch,
* patches/openjdk/6989774-imageio_compiler_warnings.patch,
* patches/openjdk/7013519-integer_overflows.patch,
* patches/openjdk/7018912-potential_buffer_overruns_in_jpeg.patch,
* patches/openjdk/8005194-scale_memory_leak.patch,
* patches/openjdk/8020983-outofmemoryerror_jpegimagewriter.patch:
New backports from OpenJDK 7u.
author | Andrew John Hughes <gnu.andrew@redhat.com> |
---|---|
date | Tue, 19 Nov 2013 18:39:31 +0000 |
parents | |
children |
line wrap: on
line source
diff -Nru openjdk.orig/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c openjdk/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c --- openjdk.orig/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c 2013-08-30 15:28:52.333056323 +0100 +++ openjdk/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c 2013-08-30 15:31:17.627316140 +0100 @@ -403,7 +403,7 @@ data->jpegObj = cinfo; cinfo->client_data = data; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("new structures: data is %p, cinfo is %p\n", data, cinfo); #endif @@ -686,7 +686,7 @@ j_decompress_ptr decomp; qlen = (*env)->GetArrayLength(env, qtables); -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("in setQTables, qlen = %d, write is %d\n", qlen, write); #endif if (qlen > NUM_QUANT_TBLS) { @@ -912,7 +912,7 @@ return FALSE; } -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("Filling input buffer, remaining skip is %ld, ", sb->remaining_skip); printf("Buffer length is %d\n", sb->bufferLength); @@ -942,7 +942,7 @@ cinfo->err->error_exit((j_common_ptr) cinfo); } -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("Buffer filled. ret = %d\n", ret); #endif /* @@ -953,7 +953,7 @@ */ if (ret <= 0) { jobject reader = data->imageIOobj; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("YO! Early EOI! ret = %d\n", ret); #endif RELEASE_ARRAYS(env, data, src->next_input_byte); @@ -1252,21 +1252,24 @@ { jpeg_saved_marker_ptr marker; int num_markers = 0; + int num_found_markers = 0; int seq_no; JOCTET *icc_data; + JOCTET *dst_ptr; unsigned int total_length; #define MAX_SEQ_NO 255 // sufficient since marker numbers are bytes - char marker_present[MAX_SEQ_NO+1]; // 1 if marker found - unsigned int data_length[MAX_SEQ_NO+1]; // size of profile data in marker - unsigned int data_offset[MAX_SEQ_NO+1]; // offset for data in marker + jpeg_saved_marker_ptr icc_markers[MAX_SEQ_NO + 1]; + int first; // index of the first marker in the icc_markers array + int last; // index of the last marker in the icc_markers array jbyteArray data = NULL; /* This first pass over the saved markers discovers whether there are * any ICC markers and verifies the consistency of the marker numbering. */ - for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) - marker_present[seq_no] = 0; + for (seq_no = 0; seq_no <= MAX_SEQ_NO; seq_no++) + icc_markers[seq_no] = NULL; + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { if (marker_is_icc(marker)) { @@ -1278,37 +1281,58 @@ return NULL; } seq_no = GETJOCTET(marker->data[12]); - if (seq_no <= 0 || seq_no > num_markers) { + + /* Some third-party tools produce images with profile chunk + * numeration started from zero. It is inconsistent with ICC + * spec, but seems to be recognized by majority of image + * processing tools, so we should be more tolerant to this + * departure from the spec. + */ + if (seq_no < 0 || seq_no > num_markers) { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid icc profile: bad sequence number"); return NULL; } - if (marker_present[seq_no]) { + if (icc_markers[seq_no] != NULL) { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid icc profile: duplicate sequence numbers"); return NULL; } - marker_present[seq_no] = 1; - data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN; + icc_markers[seq_no] = marker; + num_found_markers ++; } } if (num_markers == 0) return NULL; // There is no profile - /* Check for missing markers, count total space needed, - * compute offset of each marker's part of the data. - */ + if (num_markers != num_found_markers) { + JNU_ThrowByName(env, "javax/imageio/IIOException", + "Invalid icc profile: invalid number of icc markers"); + return NULL; + } + + first = icc_markers[0] ? 0 : 1; + last = num_found_markers + first; + /* Check for missing markers, count total space needed. + */ total_length = 0; - for (seq_no = 1; seq_no <= num_markers; seq_no++) { - if (marker_present[seq_no] == 0) { + for (seq_no = first; seq_no < last; seq_no++) { + unsigned int length; + if (icc_markers[seq_no] == NULL) { JNU_ThrowByName(env, "javax/imageio/IIOException", "Invalid icc profile: missing sequence number"); return NULL; } - data_offset[seq_no] = total_length; - total_length += data_length[seq_no]; + /* check the data length correctness */ + length = icc_markers[seq_no]->data_length; + if (ICC_OVERHEAD_LEN > length || length > MAX_BYTES_IN_MARKER) { + JNU_ThrowByName(env, "javax/imageio/IIOException", + "Invalid icc profile: invalid data length"); + return NULL; + } + total_length += (length - ICC_OVERHEAD_LEN); } if (total_length <= 0) { @@ -1337,19 +1361,14 @@ } /* and fill it in */ - for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { - if (marker_is_icc(marker)) { - JOCTET FAR *src_ptr; - JOCTET *dst_ptr; - unsigned int length; - seq_no = GETJOCTET(marker->data[12]); - dst_ptr = icc_data + data_offset[seq_no]; - src_ptr = marker->data + ICC_OVERHEAD_LEN; - length = data_length[seq_no]; - while (length--) { - *dst_ptr++ = *src_ptr++; - } - } + dst_ptr = icc_data; + for (seq_no = first; seq_no < last; seq_no++) { + JOCTET FAR *src_ptr = icc_markers[seq_no]->data + ICC_OVERHEAD_LEN; + unsigned int length = + icc_markers[seq_no]->data_length - ICC_OVERHEAD_LEN; + + memcpy(dst_ptr, src_ptr, length); + dst_ptr += length; } /* finally, unpin the array */ @@ -1565,6 +1584,7 @@ j_decompress_ptr cinfo; struct jpeg_source_mgr *src; sun_jpeg_error_ptr jerr; + jbyteArray profileData = NULL; if (data == NULL) { JNU_ThrowByName(env, @@ -1592,7 +1612,7 @@ return retval; } -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("In readImageHeader, data is %p cinfo is %p\n", data, cinfo); printf("clearFirst is %d\n", clearFirst); #endif @@ -1619,7 +1639,7 @@ if (ret == JPEG_HEADER_TABLES_ONLY) { retval = JNI_TRUE; imageio_term_source(cinfo); // Pushback remaining buffer contents -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("just read tables-only image; q table 0 at %p\n", cinfo->quant_tbl_ptrs[0]); #endif @@ -1726,6 +1746,14 @@ } } RELEASE_ARRAYS(env, data, src->next_input_byte); + + /* read icc profile data */ + profileData = read_icc_profile(env, cinfo); + + if ((*env)->ExceptionCheck(env)) { + return retval; + } + (*env)->CallVoidMethod(env, this, JPEGImageReader_setImageDataID, cinfo->image_width, @@ -1733,7 +1761,7 @@ cinfo->jpeg_color_space, cinfo->out_color_space, cinfo->num_components, - read_icc_profile(env, cinfo)); + profileData); if (reset) { jpeg_abort_decompress(cinfo); } @@ -1898,7 +1926,7 @@ (*env)->ReleaseIntArrayElements(env, bandSizes, bandSize, JNI_ABORT); -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("---- in reader.read ----\n"); printf("numBands is %d\n", numBands); printf("bands array: "); @@ -2578,7 +2606,7 @@ data->streamBuf.suspendable = FALSE; if (qtables != NULL) { -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("in writeTables: qtables not NULL\n"); #endif setQTables(env, (j_common_ptr) cinfo, qtables, TRUE); @@ -2854,7 +2882,7 @@ cinfo->restart_interval = restartInterval; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG printf("writer setup complete, starting compressor\n"); #endif @@ -2905,13 +2933,13 @@ for (; (in < pixelLimit) && (out < scanLineLimit); in += pixelStride) { for (i = 0; i < numBands; i++) { *out++ = data->scale[i][*(in+i)]; -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG if (in == data->pixelBuf.buf.bp){ // Just the first pixel printf("in %d -> out %d, ", *(in+i), *(out-i-1)); } #endif } -#ifdef DEBUG +#ifdef DEBUG_IIO_JPEG if (in == data->pixelBuf.buf.bp){ // Just the first pixel printf("\n"); }