Skip to content

Fix: Null-guards and unmanaged memory leaks#240

Merged
AnnaSasDev merged 7 commits intoInfiniLore:corefrom
freakdaniel:bugfix
Apr 15, 2026
Merged

Fix: Null-guards and unmanaged memory leaks#240
AnnaSasDev merged 7 commits intoInfiniLore:corefrom
freakdaniel:bugfix

Conversation

@freakdaniel
Copy link
Copy Markdown
Contributor

Summary

Fixed critical memory safety and correctness bugs in InfiniFrame.Native and managed interop layer, addressing null pointer dereferences, memory corruption, memory leaks, and platform-specific build issues

Type of Change

  • Bug fix (non-breaking change fixing an issue)

Affected Modules / Scope

  • InfiniFrame
  • InfiniFrame.Native
  • InfiniFrame.Shared

Changes Introduced

  • Added heap-allocated string copies for C API getters (GetUserAgent, GetTitle, GetIconFileName) to match documented ownership contract
  • Added platform-specific AllocateStringCopy helper for safe string allocation across Windows/Linux/macOS
  • Fixed EventSubscription token sequence to start from 1 instead of 0, preventing first subscription from being unsubscribable
  • Fixed Linux/macOS CMake configuration by moving CMAKE_OSX_ARCHITECTURES to macOS-only section
  • Added null-guard for WM_ACTIVATE message handler to prevent crash when hwnd map lookup fails
  • Fixed bool/BOOL type mismatch in WebView2 getters by using intermediate BOOL variable for safe 4-byte to 1-byte conversion
  • Added null-checks for RefreshImmersiveColorPolicyState and GetIsImmersiveColorUsingHighContrast in IsColorSchemeChange
  • Implemented FreeCustomSchemeNames to release unmanaged memory after native constructor copies scheme names

Related Issues

Closes #224
Closes #226
Closes #223
Closes #231
Closes #232
Closes #151
Closes #182

Checklist

  • My code follows InfiniFrame's coding conventions
  • I added comments for complex or non-obvious code
  • Documentation updated (if applicable)
  • Existing tests pass
  • No new warnings or errors introduced
  • PR only includes changes relevant to the issue / feature

Additional Context

#224 - C API String Ownership Violation

  • Problem: GetUserAgent, GetTitle, GetIconFileName returned borrowed c_str() pointers but documentation stated callers must free them
  • Impact: Calling InfiniFrame_FreeString on these pointers caused undefined behavior and crashes
  • Fix: Implemented platform-specific AllocateStringCopy helper and changed all three getters to return heap-allocated copies

#223 - bool/BOOL Type Mismatch (Memory Corruption)

  • Problem: bool* (1 byte) cast to BOOL* (4 bytes) in WebView2 API calls caused stack corruption
  • Impact: WebView2 wrote 4 bytes into 1-byte storage, corrupting adjacent stack memory
  • Fix: Use intermediate BOOL variable and safe conversion: *enabled = (boolValue != FALSE)

#226 - Null Pointer Dereference in WM_ACTIVATE

  • Problem: WM_ACTIVATE handler dereferenced hwndToInfiniFrame[hwnd] without null-check
  • Impact: Crash when message arrives before map insertion or after removal
  • Fix: Added null-guard consistent with other message handlers (WM_CLOSE, WM_DESTROY, etc.)

#151 - Null Function Pointer in Dark Mode

  • Problem: IsColorSchemeChange unconditionally called RefreshImmersiveColorPolicyState and GetIsImmersiveColorUsingHighContrast
  • Impact: Crash on Windows < build 18362 or when uxtheme.dll load fails
  • Fix: Added null-checks before calling function pointers

#232 - EventSubscription Token 0 Bug

  • Problem: Token sequence started at 0, but Unsubscribe/IsActive checked m_token != 0
  • Impact: First subscription never unsubscribed, causing stale handlers
  • Fix: Changed m_nextToken initial value from 0 to 1

#231 - Platform-Specific CMake Variables

  • Problem: Linux build used CMAKE_OSX_ARCHITECTURES (macOS-only variable)
  • Impact: Misleading configuration, incorrect cross-compilation setup
  • Fix: Moved CMAKE_OSX_ARCHITECTURES to macOS section, Linux uses default detection

#182 - CustomSchemeNames Memory Leak

  • Problem: Memory allocated via Marshal.StringToHGlobalAnsi never freed
  • Impact: Unmanaged memory leak when creating/destroying windows with custom schemes
  • Fix: Added FreeCustomSchemeNames helper called after native constructor (which copies the strings)

Testing Notes

These fixes address memory safety issues that may not be caught by existing tests

- Add null-guards to WM_ACTIVATE and IsColorSchemeChange (InfiniLore#226, InfiniLore#151)
- Add safe conversion from BOOL to bool type (InfiniLore#223)
- Fix build variables for Linux and macOS (InfiniLore#231)
- Fix unmanaged first subscription by zero-value skip (InfiniLore#232)
- Fix unmanaged alloc in GetUserAgent, GetTitle, GetIconFileName getters by safe copying (InfiniLore#224)
Comment thread src/InfiniFrame/InfiniFrameWindow.cs Dismissed
@AnnaSasDev
Copy link
Copy Markdown
Member

D:\a\InfiniFrame\InfiniFrame\tests\InfiniFrameTests.Playwright\bin\Release\net8.0\InfiniFrameTests.Playwright.dll (net8.0|x64) Zero tests ran (7s 167ms)
Exit code: -1073741819
  Error output: Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  Repeat 2 times:
  --------------------------------
     at InfiniFrame.Native.InfiniFrameNative.<SendWebMessage>g____PInvoke|60_0(IntPtr, Byte*)
  --------------------------------
     at InfiniFrame.Native.InfiniFrameNative.SendWebMessage(IntPtr, System.String)
     at InfiniFrame.InfiniFrameWindow+<>c__DisplayClass147_0.<SendWebMessage>b__0()
     at InfiniFrame.Native.InfiniFrameNative.<WaitForExit>g____PInvoke|62_0(IntPtr)
     at InfiniFrame.Native.InfiniFrameNative.<WaitForExit>g____PInvoke|62_0(IntPtr)
     at InfiniFrame.Native.InfiniFrameNative.WaitForExit(IntPtr)
     at InfiniFrame.InfiniFrameWindow.<WaitForClose>b__144_0()
     at InfiniFrame.InfiniFrameWindow.Invoke(System.Action)
     at InfiniFrame.InfiniFrameWindow.WaitForClose()
     at InfiniFrameTests.Shared.InfiniFrameServerTestUtility+<>c__DisplayClass11_0.<Create>b__0()
     at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)

Seens to be that something went wrong with dotnet 8 and dotnet 9 Playwright

…ling during shutdown via Invoke double-check
@freakdaniel
Copy link
Copy Markdown
Contributor Author

@AnnaSasDev This problem appeared not bcs of me. I launched tests before the last merge from InfiniFrame upstream:
First one: https://github.com/freakdaniel/InfiniFrame/actions/runs/24452559864
And after macOS variable fix: https://github.com/freakdaniel/InfiniFrame/actions/runs/24453028634

So the problem comes with your commit here: bde0e05

@freakdaniel
Copy link
Copy Markdown
Contributor Author

Fixed with double-check in invoke. All tests passed: https://github.com/freakdaniel/InfiniFrame/actions/runs/24456388737

@AnnaSasDev AnnaSasDev merged commit e9e929d into InfiniLore:core Apr 15, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants