fix(ui): bounds-guard out-of-range list access in pop-out and tabs UI
Two pre-existing upstream defects fixed in v1.0.0: - Ui/Popout.cs PopOutDocked[Idx] now bounds-checks Idx against ChatLogWindow.PopOutDocked.Count before reading or writing. A popout instance can outlive a list resize when AddPopOutsToDraw() rebuilds the docked-state list while a draw frame is in flight, which previously produced an out-of-range crash on tab drop - Ui/SettingsTabs/Tabs.cs guards against an empty worlds list before indexing worlds[selectedWorld]. Empty lists can occur briefly when switching characters or before the datacenter sheet finishes loading — the previous code would crash with an ArgumentOutOfRangeException
This commit is contained in:
@@ -80,7 +80,10 @@ internal class Popout : Window
|
||||
if (!Tab.CanResize)
|
||||
Flags |= ImGuiWindowFlags.NoResize;
|
||||
|
||||
if (!ChatLogWindow.PopOutDocked[Idx])
|
||||
// Idx may point past the end if PopOutDocked was resized (e.g., a tab
|
||||
// dropped) between the AddPopOutsToDraw() snapshot and this frame.
|
||||
// Guard the read so we don't index into stale state.
|
||||
if (Idx >= 0 && Idx < ChatLogWindow.PopOutDocked.Count && !ChatLogWindow.PopOutDocked[Idx])
|
||||
{
|
||||
if (Tab.IndependentOpacity)
|
||||
{
|
||||
@@ -195,6 +198,7 @@ internal class Popout : Window
|
||||
|
||||
public override void PostDraw()
|
||||
{
|
||||
if (Idx >= 0 && Idx < ChatLogWindow.PopOutDocked.Count)
|
||||
ChatLogWindow.PopOutDocked[Idx] = ImGui.IsWindowDocked();
|
||||
|
||||
if (Plugin.Config is { OverrideStyle: true, ChosenStyle: not null })
|
||||
|
||||
@@ -181,6 +181,16 @@ internal sealed class Tabs : ISettingsTab
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
// Guard against an empty worlds list — can happen briefly
|
||||
// when switching characters or if the datacenter sheet
|
||||
// has not yet populated. Without the guard the indexed
|
||||
// access into worlds[selectedWorld] would crash.
|
||||
if (worlds.Count == 0)
|
||||
{
|
||||
ImGui.TextDisabled("(no worlds available)");
|
||||
}
|
||||
else
|
||||
{
|
||||
var selectedWorld = worlds.FindIndex(world => world.RowId == tab.TellTarget.World);
|
||||
if (selectedWorld == -1)
|
||||
selectedWorld = 0;
|
||||
@@ -207,6 +217,7 @@ internal sealed class Tabs : ISettingsTab
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var target = (Plugin.TargetManager.SoftTarget ?? Plugin.TargetManager.Target) as IPlayerCharacter;
|
||||
using (ImRaii.Disabled(target == null))
|
||||
|
||||
Reference in New Issue
Block a user