release graphics if an exception will be thrown in PDFPrintable.print method#440
Conversation
|
I thought this looked good but I asked copilot because I can use it for free. Your PR disposes the wrong object if the exception is too early. Here's the important parts (AI is too verbose): ==== Change the code to dispose only the image graphics created by image.createGraphics(): ===== Here's the full review: ===== PR #440 is conceptually aiming at the right thing (avoid leaking/holding onto graphics resources when print() exits via an exception), but the implementation as shown in the patch has a bug and likely doesn’t do what the author intended. It hoists Graphics2D graphics2D and Graphics2D printerGraphics out of the try block and adds a finally intended to dispose graphics if something goes wrong. Patch excerpt (from the PR “files” view):
...
...
...
...
Main issue: finally disposes the wrong object In the rasterization branch (existing code), the flow is: So if rasterization is enabled, the thing you must dispose is the image graphics, i.e. the graphics2D after reassignment. But in the PR’s finally, the condition is if (printerGraphics != null) (meaning rasterization happened), and then it calls graphics2D.dispose(). At the end of the try-block, graphics2D will usually still refer to the image graphics (good)… unless an exception happens before graphics2D = image.createGraphics() is executed, in which case graphics2D still refers to the printer graphics and the finally would dispose a graphics object it probably does not own. Also: the PR removed the existing graphics2D.dispose() in the normal (non-exception) rasterization flow, but the finally only disposes when printerGraphics != null; so disposal would still happen on success. That part is fine if it’s always the correct graphics instance—but as explained, it’s not guaranteed. If the PR title is “release graphics if an exception will be thrown…”, the safe pattern is usually: That suggests the PR should track something like Graphics2D imageGraphics = null; and if (imageGraphics != null) imageGraphics.dispose(); in finally. Bottom line |
|
As I understand it, the main argument of Claude's is that the wrong graphics object can be disposed if an exception occurs before calling "image.createGraphics()." This is potentially possible. That is, the code is written in such a way that if another programmer changes it in the future, such an error could occur. I checked my proposed code for such an error, if it is an IOException. You can comment out lines 202 and 318-321. Then you will see that the exception never occurs before the "image.createGraphics()" command. Therefore, disposing the wrong object is only possible if an entirely different exception (OOM?) is thrown. I modified the code to eliminate the potential error of disposing the wrong Graphics2D object. |
|
Here are some more things that look like bugs:
This calls graphics (the original parameter), not graphics2D. All the configuration just set on graphics2D (transform,
|
|
Thank you, these are very good observations. Please create 3 different tickets if you want, but AFTER this one is done, and not at the same time. The correction here looks good to me but lets see what copilot says. |
|
copilot (GPT 5.2) agrees and made a separate (unrelated) suggestion for clarity that I will commit separately. |
No description provided.