Skip to content

Possible fix for Oracle's Bug JDK-8314112#175

Closed
viktor-merkel wants to merge 5 commits intoapache:2.0from
viktor-merkel:2.0.30-NegArrSizeExcFix
Closed

Possible fix for Oracle's Bug JDK-8314112#175
viktor-merkel wants to merge 5 commits intoapache:2.0from
viktor-merkel:2.0.30-NegArrSizeExcFix

Conversation

@viktor-merkel
Copy link
Copy Markdown

This PR fixes the NegativeArraySizeException during print when scaling causes width and height to be 0, which can lead to application freeze unexpectedly.

The sun.awt.windows.WPathGraphics class in Java contains a code segment within the drawImageToPlatform function that can lead to a NegativeArraySizeException under specific conditions. This issue arises when the scaling values in AffineTransform are set in a way that causes w and h (width and height) to have a value of 0.

"Proposed Solution:
To prevent the occurrence of the NegativeArraySizeException, a check should be introduced in the code to ensure that w and h are not 0 before proceeding with the calculation of minDpi. If either w or h is found to be 0, an appropriate error handling mechanism should be implemented to avoid division by zero."
Oracle bug submission:
https://bugs.java.com/bugdatabase/view_bug?bug_id=JDK-8314112

This PR provides a fix for PDFBox that checks for a correct scale before forwarding the application flow to the problematic part of the JRE.

@THausherr
Copy link
Copy Markdown
Contributor

THausherr commented Jan 4, 2024

I'm wondering whether calls like setAccessible(true) will make trouble in newer java versions. Aren't these "unsafe"? I don't remember the details, I just remember that certain calls would be forbidden by default.

I'm also wondering whether these stunts are needed. isBitmaskTransparency() could be implemented without:
https://code.yawk.at/java/12/java.desktop/sun/print/PathGraphics.java#1210

Same for getPrinterJob(), PrintGraphics is a public interface.

@THausherr
Copy link
Copy Markdown
Contributor

I'm also wondering whether it wouldn't be easier (and faster on runtime) to just catch the NegativeArraySizeException in PageDrawer at the three places you indicated, until java fixes that bug. (despite all the work you put into that fix, sorry)

@PascalSchumacher
Copy link
Copy Markdown

I'm wondering whether calls like setAccessible(true) will make trouble in newer java versions. Aren't these "unsafe"? I don't remember the details, I just remember that certain calls would be forbidden by default.

Yes, on Java 16+ reflection to access the non-public elements of java.* packages, and all elements of sun.* and other internal packages is forbidden by default and has to be explicitly enabled, see: https://openjdk.org/jeps/396`https://openjdk.org/jeps/396 for details.

@lehmi
Copy link
Copy Markdown
Contributor

lehmi commented Jan 6, 2024

I agree with @THausherr the proposed patch is kind of hacky and it just solves a corner case. I'd prefer the alternative solution, catching the exception and waiting for a java fix

@viktor-merkel
Copy link
Copy Markdown
Author

@THausherr Thanks for taking a look at my pull request.

The problem with the simple "catch exceptions" solution is that it does not prevent the program from attempting to create a very large data buffer due to the division by zero, and this leads to an OutOfMemoryError of the entire application:

Caused by: java.lang.OutOfMemoryError: Java heap space
at java.desktop/java.awt.image.DataBufferByte.(DataBufferByte.java:76)
at java.desktop/java.awt.image.Raster.createInterleavedRaster(Raster.java:266)
at java.desktop/java.awt.image.BufferedImage.(BufferedImage.java:376)
at java.desktop/sun.awt.windows.WPathGraphics.redrawRegion(WPathGraphics.java:1399)
at java.desktop/sun.print.RasterPrinterJob.printPage(RasterPrinterJob.java:2320)
at java.desktop/sun.print.RasterPrinterJob.print(RasterPrinterJob.java:1654)
...

@THausherr
Copy link
Copy Markdown
Contributor

THausherr commented Jan 8, 2024

Yeah I should have tested your program. I reverted the whole thing for a different reason, the exception doesn't happen at the place where I catch it. So you're right, the method shouldn't be called at all, i.e. the call should be prevented.

Please try to adjust your code so that it doesn't do any of the "forbidden" calls, and without jdk code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants