-
Notifications
You must be signed in to change notification settings - Fork 6k
8262297: ImageIO.write() method will throw IndexOutOfBoundsException #6151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back myano! A progress list of the required criteria for merging this PR into |
Webrevs
|
@@ -553,6 +553,9 @@ public void write(byte[] b) throws IOException { | |||
* @param off the start offset in the data. | |||
* @param len the number of bytes to write. | |||
* @throws IOException if an I/O error occurs. | |||
* @throws IndexOutOfBoundsException If {@code off} is negative, | |||
* {@code len} is negative, or {@code len} is greater than | |||
* {@code b.length - off} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The IOOBE is specified in the super interface, it's just not shown in the javadoc because it's a runtime exception. So I think what you want here is:
@throws IndexOutOfBoundsException {@inheritdoc}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately the parent class does not specify this exception via javadoc tags like "@throws IndexOutOfBoundsException", but instead just describe it in the method description
should we fix it separately from the imageio fix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately the parent class does not specify this exception via javadoc tags like "@throws IndexOutOfBoundsException", but instead just describe it in the method description
should we fix it separately from the imageio fix?
Yes, it might be better to separate them because we'll like need a CSR if we are missing @throws in a few places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understood to separate javadoc fix. I will remove the javadoc fix from this PR and issue another Bug ID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this means this PR will be image I/O only so I'll remove the core-libs label.
This needs looking at closely .. I don't know what's best but the imaging APIs are very exception heavy because of the arrays, indices, you name it that they consume. Most of the time its probably best for an IIO user to just get an IIOException wrapping the original cause. But there could be exceptions. |
/label remove core-libs |
@AlanBateman |
I am not sure that this is the right thing at all here. You need to dig deeper.
So for me this starts with the read, and a proper explanation of what happens there, and then an explanation as to what is wrong with the BufferedImage. I have no interest in slapping a sticking plaster on the observed symptom. It needs to be root cause explained and fixed. |
This problem occurs because the input png image depth is 2 bits per pixel. Because the png to read is the correct image at 2 bits per pixel, the BufferedImage is generated correctly and no exception is thrown. However, bmp can only create images with a depth of 0, 1, 4, 8, 16, 24, or 32 bits per pixel. Because the BMPImageWriter determines bitsPerPixel in the range of the color palette without checking the depth, images with depths other than 0, 1, 4, 8, 16, 24, 32 are set to the wrong bitsPerPixel and destScanlineBytes. Therefore, an incorrect length reference to the size of the Raster DataBuffer causes IIOBE to be thrown. So the fix should change the canEncodeImage method to check the color depth and throw an IOException if it is not 0, 1, 4, 8, 16, 24, or 32. |
/* | ||
* @test | ||
* @bug 8262297 | ||
* @summary Checks that ImageIO.write(..., ..., File) truncates the file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think with latest patch this summary should be updated to reflect what test is verifying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed summary to verify bit per pixel checking.
public class TruncatedPngTest { | ||
|
||
public static void main(String[] args) { | ||
String fileName = "0.png"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A 2KB image will not take much space but it would be better if we can create 2bpp PNG image programmatically and use it in the test case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed test to use generated BufferdImage and more bpp.
@@ -1456,6 +1456,9 @@ protected boolean canEncodeImage(int compression, ImageTypeSpecifier imgType) { | |||
} | |||
int biType = imgType.getBufferedImageType(); | |||
int bpp = imgType.getColorModel().getPixelSize(); | |||
if (bpp != 0 && bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably the exception message caused by this should be updated as well? Currently, it takes care of compression only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think the message should be change. I added bpp information at the end of the exception message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no other comments.
@masyano This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 382 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@mrserb, @jayathirthrao) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
/integrate |
imageType = BufferedImage.TYPE_BYTE_INDEXED; | ||
} | ||
BufferedImage img = new BufferedImage(10, 10, imageType, (IndexColorModel)cm); | ||
ImageIO.write(img, "BMP", new File("test.bmp")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed before sponsoring that this test will leave test.bmp file.
We should create temporary file and delete it on exit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am withdrawing my approval, since this needs to be fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed it to use createTempFile and deleteOnExit.
/reviewer remove @jayathirthrao |
@jayathirthrao Only the author (@masyano) is allowed to issue the |
imageType = BufferedImage.TYPE_BYTE_INDEXED; | ||
} | ||
BufferedImage img = new BufferedImage(10, 10, imageType, (IndexColorModel)cm); | ||
ImageIO.write(img, "BMP", new File("test.bmp")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am withdrawing my approval, since this needs to be fixed.
/reviewers 2 |
@jayathirthrao |
/integrate |
/sponsor |
Going to push as commit c733193.
Your commit was automatically rebased without conflicts. |
@jayathirthrao @masyano Pushed as commit c733193. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
This change has caused regression : https://bugs.openjdk.java.net/browse/JDK-8278047 |
@jayathirthrao @masyano @prrace @AlanBateman We also meet the same issue in PNGImageWriter.write, Do you have any idea how to fix it ? Thanks in advance. at java.desktop/javax.imageio.ImageWriter.write(ImageWriter.java:613) |
Could you please review the 8262297 bug fixes?
In this case, ImageIO.write() should throw java.io.IOException rather than java.lang.IndexOutOfBoundsException. IndexOutOfBoundsException is caught and wrapped in IIOException in ImageIO.write() with this fix. In addition, IndexOutOfBoundsException is not expected to throw by RandomAccessFile#write() according to its API specification. So it should be fixed.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/6151/head:pull/6151
$ git checkout pull/6151
Update a local copy of the PR:
$ git checkout pull/6151
$ git pull https://git.openjdk.java.net/jdk pull/6151/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 6151
View PR using the GUI difftool:
$ git pr show -t 6151
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/6151.diff