fix(chat): release Utf8String when linkshell check rejects channel
Cherry-pick from ChatTwo upstream f35b7d3 (Infiziert90, 2026-05-12). Chat.SetChannel allocates a native Utf8String for the target name and then runs a validity check. The previous early return on an invalid linkshell skipped Dtor and leaked the native allocation; every invalid linkshell switch added one Utf8String to the unmanaged heap. - Renamed ValidAnyLinkshell to IsChannelOrExistingLinkshell so the call-site reads naturally. - Wrapped ChangeChatChannel in the validity check instead of early-returning. Dtor now runs on every path. - ChatLogWindow follows the rename at its single call-site.
This commit is contained in:
@@ -423,16 +423,24 @@ internal sealed unsafe class Chat : IDisposable
|
||||
);
|
||||
}
|
||||
|
||||
// Check if channel is valid (non-linkshell or existing linkshell)
|
||||
internal static bool ValidAnyLinkshell(InputChannel channel)
|
||||
// ---------------------------------------------------------------
|
||||
// Cherry-picked from ChatTwo upstream f35b7d3 (Infiziert90, 2026-05-12)
|
||||
// - Renamed ValidAnyLinkshell -> IsChannelOrExistingLinkshell. The
|
||||
// name now states intent: returns true for any non-linkshell
|
||||
// channel, or a linkshell index that actually exists.
|
||||
// ---------------------------------------------------------------
|
||||
internal static bool IsChannelOrExistingLinkshell(InputChannel channel)
|
||||
{
|
||||
var idx = channel.LinkshellIndex();
|
||||
if (idx == uint.MaxValue || channel.IsExtraChatLinkshell())
|
||||
return true;
|
||||
if (channel.IsLinkshell() && ValidLinkshell(idx))
|
||||
return true;
|
||||
if (channel.IsCrossLinkshell() && ValidCrossLinkshell(idx))
|
||||
return true;
|
||||
|
||||
if (channel.IsLinkshell())
|
||||
return ValidLinkshell(idx);
|
||||
|
||||
if (channel.IsCrossLinkshell())
|
||||
return ValidCrossLinkshell(idx);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -531,12 +539,17 @@ internal sealed unsafe class Chat : IDisposable
|
||||
if (idx == uint.MaxValue)
|
||||
idx = 0;
|
||||
|
||||
if (!ValidAnyLinkshell(channel))
|
||||
return;
|
||||
// ---------------------------------------------------------------
|
||||
// Cherry-picked from ChatTwo upstream f35b7d3 (Infiziert90, 2026-05-12)
|
||||
// - Wrap ChangeChatChannel in the validity check instead of
|
||||
// early-returning. The previous early return skipped Dtor and
|
||||
// leaked the native Utf8String allocated a few lines above.
|
||||
// ---------------------------------------------------------------
|
||||
if (IsChannelOrExistingLinkshell(channel))
|
||||
RaptureShellModule
|
||||
.Instance()
|
||||
->ChangeChatChannel(tellTarget != null ? 17 : (int)channel, idx, target, true);
|
||||
|
||||
RaptureShellModule
|
||||
.Instance()
|
||||
->ChangeChatChannel(tellTarget != null ? 17 : (int)channel, idx, target, true);
|
||||
target->Dtor(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -272,7 +272,10 @@ public sealed class ChatLogWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
if (targetChannel == null || !GameFunctions.Chat.ValidAnyLinkshell(targetChannel.Value))
|
||||
if (
|
||||
targetChannel == null
|
||||
|| !GameFunctions.Chat.IsChannelOrExistingLinkshell(targetChannel.Value)
|
||||
)
|
||||
{
|
||||
Plugin.Log.Warning(
|
||||
$"Channel was set to an invalid value '{targetChannel}', ignoring"
|
||||
|
||||
Reference in New Issue
Block a user