On Wed, 12 Mar 2025 18:23:12 GMT, Jeremy Wood <d...@openjdk.org> wrote:

>> JPEG segments can only be 65535-bytes long. (The marker length is expressed 
>> as 2 bytes.) The problem in this ticket is that we were writing more than 
>> 65535 bytes to a segment, which later caused parsing errors when we tried to 
>> read the file back.
>> 
>> This includes 2 changes:
>> 
>> 1. We now clip the thumbnail width/height to fit within the available 
>> marker. We were already constraining the width & height to a max of 255. 
>> (Because the width & height are expressed as 1 byte.) So this new clipping 
>> is similar to something we were already doing, and we issue the same 
>> WARNING_THUMB_CLIPPED warning to the writer. (Does this require a CSR?)
>> 
>> 2. This adds a bounds check to `write2bytes`. IMO the bigger problem in this 
>> ticket was the `ImageIO.write(..)` caller thought they ended up with a valid 
>> JPEG. (We were violating the "do no harm / lose no data" doctrine.) Now if 
>> something like this ever comes up again: writing will fail with an 
>> IIOException. Technically you can argue this change is unnecessary because 
>> the new clipping avoids this error condition, but IMO including this safety 
>> net is an overall good thing to keep. If anyone disagrees I'm OK with 
>> removing it.
>> 
>> Separately:
>> I included (and reversed) a commit in this branch that provides an alternate 
>> solution. That commit anticipates the overflow problem and switches to a 
>> JPEG-encoded thumbnail. From an end user perspective this "just works": they 
>> get a (slightly lossly) thumbnail of the original dimensions. But I assume 
>> it would be more controversial compared to the clipping approach, since the 
>> clipping approach has a strong precedent in this codebase.
>
> Jeremy Wood has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - 8351110: adding a few clarifying comments
>  - 8351110: changing `catch` statement to support assertEquals's Error

Changes requested by aivanov (Reviewer).

src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java
 line 383:

> 381:             if (thumbWidth * thumbHeight > maxArea) {
> 382:                 
> writer.warningOccurred(JPEGImageWriter.WARNING_THUMB_CLIPPED);
> 383:                 double scale = Math.sqrt( ((double)maxArea) / 
> (double)(thumbWidth * thumbHeight));

Does it make sense to add a space before the closing parenthesis? For 
consistency with the opening one; or remove these spaces just inside the method 
call parentheses.
Suggestion:

                double scale = Math.sqrt( ((double)maxArea) / 
(double)(thumbWidth * thumbHeight) );

test/jdk/javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java line 66:

> 64:         boolean b2 = new WriteJPEGThumbnailTest(100, 219).run();
> 65:         if (!(b1 && b2))
> 66:             System.err.println("Test failed");

Suggestion:

        if (!(b1 && b2)) {
            System.err.println("Test failed");
            throw new Error("Test failed");
        }

Always use braces, even for one-line statement.

You must throw an exception, otherwise the test will never fail from jtreg 
point of view.


jdk> ./build/windows-x86_64-server-release/jdk/bin/java -jar 
../jtreg/lib/jtreg.jar \
    -w:./build/jtwork -nr -v \
    test/jdk/javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java
runner starting test: javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java
runner finished test: javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java
Passed. Execution successful
Test results: passed: 1

And I don't have your fix.

test/jdk/javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java line 86:

> 84:                 } finally {
> 85:                     jpegData = byteOut.toByteArray();
> 86:                 }

Does it have to be in the `finally` block?

You can assign `jpegData` outside of the `try` block. If an exception is thrown 
in `try`, the method stops executing and assigning to `jpegData` makes no sense.

test/jdk/javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java line 104:

> 102:             }
> 103:             System.out.println("\tTest passed");
> 104:         } catch(Throwable e) {

Suggestion:

        } catch (Throwable e) {

test/jdk/javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java line 142:

> 140:         g.fillRect(0,900,100,100);
> 141:         g.setColor(Color.magenta);
> 142:         g.fillRect(900,900,100,100);

Spaces after commas, upper-case color constants:
Suggestion:

        g.setColor(Color.RED);
        g.fillRect(0, 0, 100, 100);
        g.setColor(Color.GREEN);
        g.fillRect(900, 0, 900, 100);
        g.setColor(Color.ORANGE);
        g.fillRect(0, 900, 100, 100);
        g.setColor(Color.MAGENTA);
        g.fillRect(900, 900, 100, 100);

test/jdk/javax/imageio/plugins/jpeg/WriteJPEGThumbnailTest.java line 152:

> 150:         while(readers.hasNext()) {
> 151:             reader = readers.next();
> 152:             if(reader.canReadRaster()) {

Suggestion:

        while (readers.hasNext()) {
            reader = readers.next();
            if (reader.canReadRaster()) {

-------------

PR Review: https://git.openjdk.org/jdk/pull/23920#pullrequestreview-2743856146
PR Review Comment: https://git.openjdk.org/jdk/pull/23920#discussion_r2029289420
PR Review Comment: https://git.openjdk.org/jdk/pull/23920#discussion_r2029310112
PR Review Comment: https://git.openjdk.org/jdk/pull/23920#discussion_r2029297962
PR Review Comment: https://git.openjdk.org/jdk/pull/23920#discussion_r2029303202
PR Review Comment: https://git.openjdk.org/jdk/pull/23920#discussion_r2029301961
PR Review Comment: https://git.openjdk.org/jdk/pull/23920#discussion_r2029302608

Reply via email to