tab items must end conditionally

Fixes random heap corruption after opening the settings window
This commit is contained in:
goat 2024-05-08 22:01:35 +02:00
parent 616980f99f
commit 48931dd8d2
2 changed files with 19 additions and 29 deletions

View file

@ -158,7 +158,6 @@ internal class SettingsWindow : Window
} }
ImGui.EndChild(); ImGui.EndChild();
ImGui.EndTabItem();
} }
else if (settingsTab.IsOpen) else if (settingsTab.IsOpen)
{ {

View file

@ -109,40 +109,31 @@ public static partial class ImRaii
public static unsafe IEndObject TabItem(string label, ImGuiTabItemFlags flags) public static unsafe IEndObject TabItem(string label, ImGuiTabItemFlags flags)
{ {
ArgumentNullException.ThrowIfNull(label);
// One-off for now, we should make this into a generic solution if we need it more often // One-off for now, we should make this into a generic solution if we need it more often
const int ImGuiNET_Util_StackAllocationSizeLimit = 2048; const int labelMaxAlloc = 2048;
byte* native_label; var labelByteCount = Encoding.UTF8.GetByteCount(label);
int label_byteCount = 0;
if (label != null)
{
label_byteCount = Encoding.UTF8.GetByteCount(label);
if (label_byteCount > ImGuiNET_Util_StackAllocationSizeLimit) if (labelByteCount > labelMaxAlloc)
{ {
throw new ArgumentOutOfRangeException("label", "Label is too long. (Longer than 2048 bytes)"); throw new ArgumentOutOfRangeException(nameof(label), $"Label is too long. (Longer than {labelMaxAlloc} bytes)");
} }
byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1]; var nativeLabelStackBytes = stackalloc byte[labelByteCount + 1];
native_label = native_label_stackBytes;
int native_label_offset; int nativeLabelOffset;
fixed (char* utf16Ptr = label) fixed (char* utf16Ptr = label)
{ {
native_label_offset = Encoding.UTF8.GetBytes(utf16Ptr, label.Length, native_label, label_byteCount); nativeLabelOffset = Encoding.UTF8.GetBytes(utf16Ptr, label.Length, nativeLabelStackBytes, labelByteCount);
} }
native_label[native_label_offset] = 0; nativeLabelStackBytes[nativeLabelOffset] = 0;
}
else
{
native_label = null;
}
byte* p_open = null; var ret = ImGuiNative.igBeginTabItem(nativeLabelStackBytes, null, flags);
byte ret = ImGuiNative.igBeginTabItem(native_label, p_open, flags);
return new EndUnconditionally(ImGuiNative.igEndTabItem, ret != 0); return new EndConditionally(ImGuiNative.igEndTabItem, ret != 0);
} }
public static IEndObject TabItem(string label, ref bool open) public static IEndObject TabItem(string label, ref bool open)