RFR: 8282862: AwtWindow::SetIconData leaks old icon handles if an exception is detected [v3]
Alexey Ivanov
aivanov at openjdk.org
Tue Jan 7 21:26:36 UTC 2025
On Tue, 7 Jan 2025 19:37:24 GMT, Rajat Mahajan <rmahajan at openjdk.org> wrote:
>> **Issue:**
>> AwtWindow::SetIconData leaks the old icon handles in hOldIcon and hOldIconSm if CreateIconFromRaster raises an exception. Additionally, an exception is checked only after the first call to CreateIconFromRaster.
>>
>> **Solution:**
>> I have added the exception handling code to take care that the handles are properly destroyed and not leaked.
>>
>> **Testing:**
>> I have tested the code to make sure there are no regressions caused by this.
>
> Rajat Mahajan has updated the pull request incrementally with one additional commit since the last revision:
>
> Update copyright year
Changes requested by aivanov (Reviewer).
src/java.desktop/windows/native/libawt/windows/awt_Window.cpp line 2127:
> 2125: try {
> 2126: m_hIcon = CreateIconFromRaster(env, iconRaster, w, h);
> 2127: JNU_CHECK_EXCEPTION(env); // Might throw here
The comment is misleading, `JNU_CHECK_EXCEPTION` does not throw an exception.
https://github.com/openjdk/jdk/blob/27646e551686ec02740600fc73694fc2fbd00a88/src/java.base/share/native/libjava/jni_util.h#L278-L283
It checks if an exception is raised in Java code and returns immediately if there's a pending Java exception.
If a Java exception is raised at this line, after `m_hIcon` is assigned and its value is not `NULL`, it has to be deleted.
Perhaps, you have to handle it explicitly here:
if (env->ExceptionCheck()) {
if (m_hIcon) {
DestroyIcon(m_hIcon);
}
return;
}
It looks that the original values stored in `hOldIcon` and `hOldIconSm` should be restored if an error occurs.
src/java.desktop/windows/native/libawt/windows/awt_Window.cpp line 2129:
> 2127: JNU_CHECK_EXCEPTION(env); // Might throw here
> 2128: m_hIconSm = CreateIconFromRaster(env, smallIconRaster, smw, smh);
> 2129: JNU_CHECK_EXCEPTION(env); // Or here
The clean-up code here should delete both `m_hIcon` and `m_hIconSm`.
And restore the previous values?
src/java.desktop/windows/native/libawt/windows/awt_Window.cpp line 2130:
> 2128: m_hIconSm = CreateIconFromRaster(env, smallIconRaster, smw, smh);
> 2129: JNU_CHECK_EXCEPTION(env); // Or here
> 2130: } catch (...) {
At first I thought using C++ exception handling was a bad idea, but it's actually needed. The code in `CreateIconFromRaster` can throw a C++ exception, specifically `BitmapUtil::CreateTransparencyMaskFromARGB` and `BitmapUtil::CreateV4BitmapFromARGB`.
https://github.com/openjdk/jdk/blob/e413fc643c4a58e3c46d81025c3ac9fbf89db4b9/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp#L2075-L2087
Since the exception is re-thrown in the handler there, it has to be caught in `AwtWindow::SetIconData`. Yet you shouldn't re-throw the C++ exception here, it must not escape JNI code, otherwise, the unhandled exception will likely crash the Java process.
src/java.desktop/windows/native/libawt/windows/awt_Window.cpp line 2138:
> 2136: DestroyIcon(m_hIconSm);
> 2137: }
> 2138: throw; // Re-throw the exception
The C++ exception shouldn't be *re-thrown* here.
Whether we should raise a Java exception to indicate an error is to be discussed. If we restore the state of the `AwtWindow` object as if no failure occurred, it can continue. And I don't see any meaningful way to return an error back to Java here.
`CreateIconFromRaster` throws `NullPointerException` if it fails to get the image raster.
https://github.com/openjdk/jdk/blob/e413fc643c4a58e3c46d81025c3ac9fbf89db4b9/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp#L2076-L2078
where `JNI_CHECK_NULL_GOTO` is
https://github.com/openjdk/jdk/blob/27646e551686ec02740600fc73694fc2fbd00a88/src/java.desktop/windows/native/libawt/windows/awt.h#L48-L54
-------------
PR Review: https://git.openjdk.org/jdk/pull/22932#pullrequestreview-2535323825
PR Review Comment: https://git.openjdk.org/jdk/pull/22932#discussion_r1906029348
PR Review Comment: https://git.openjdk.org/jdk/pull/22932#discussion_r1906031377
PR Review Comment: https://git.openjdk.org/jdk/pull/22932#discussion_r1906013829
PR Review Comment: https://git.openjdk.org/jdk/pull/22932#discussion_r1906050261
More information about the client-libs-dev
mailing list