Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion Lagrange.Core/Message/Entities/MultiMsgEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,34 @@ public async Task Preprocess(BotContext context, BotMessage message)
{
if (string.IsNullOrEmpty(ResId))
{
// Recursively preprocess internal messages
Console.WriteLine($"[MultiMsgEntity] Preprocessing {Messages.Count} messages for forward chain...");

foreach (var innerMsg in Messages)
{
foreach (var entity in innerMsg.Entities)
{
try
{
await entity.Preprocess(context, message);

if (entity is ImageEntity img)
{
if (img.MsgInfo != null)
Console.WriteLine($"[MultiMsgEntity] Image uploaded successfully. Size: {img.ImageSize}");
else
Console.WriteLine("[MultiMsgEntity] WARNING: Image MsgInfo is NULL after preprocess!");
}
}
catch (Exception ex)
{
Console.WriteLine($"[MultiMsgEntity] Error preprocessing entity: {ex.Message}");
}
}
}

var result = await context.EventContext.SendEvent<LongMsgSendEventResp>(new LongMsgSendEventReq(message.Receiver, Messages));
ResId = result.ResId;

}
}

Expand Down
45 changes: 45 additions & 0 deletions Lagrange.Proto.Test/CrashTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using NUnit.Framework;
using Lagrange.Proto.Utility;

namespace Lagrange.Proto.Test
{
[TestFixture]
public class CrashTest
{
[Test]
public void TestNegativeInt32VarIntLength()
{
// This test is used to reproduce the IndexOutOfRangeException Bug
int value = -1;

int length = ProtoHelper.GetVarIntLength(value);

// Verify: For a 32-bit all-ones number (0xFFFF), VarInt encoding should be 5 bytes
Assert.That(length, Is.EqualTo(5));
}

[Test]
public void TestNegativeInt64VarIntLength()
{
long value = -1;

// For 64-bit numbers with all 1s, VarInt encoding should be 10 bytes
int length = ProtoHelper.GetVarIntLength(value);

Assert.That(length, Is.EqualTo(10));
}

[Test]
public void TestOtherNegativeValues()
{
// Test other negative values to ensure stability
int val1 = -100;
int len1 = ProtoHelper.GetVarIntLength(val1);
Assert.That(len1, Is.GreaterThan(0));

long val2 = long.MinValue; // 0x8000000000000000
int len2 = ProtoHelper.GetVarIntLength(val2);
Assert.That(len2, Is.EqualTo(10));
}
}
}
3 changes: 2 additions & 1 deletion Lagrange.Proto/Primitives/ProtoWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ public void EncodeVarInt<T>(T value) where T : unmanaged, INumber<T>
{
if (_memory.Length - BytesPending >= 10)
{
if (value < T.CreateTruncating(0x80))
// For-1 (int), converting to ulong is 0xFF... FF, much greater than 0x80, will not mistakenly enter this branch.
if (ulong.CreateTruncating(value) < 0x80)
{
Unsafe.Add(ref MemoryMarshal.GetReference(_memory.Span), BytesPending++) = byte.CreateTruncating(value);
return;
Expand Down
6 changes: 3 additions & 3 deletions Lagrange.Proto/Utility/ProtoHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ public static unsafe int GetVarIntLength<T>(T value) where T : unmanaged, INumbe

if (sizeof(T) <= 4)
{
int leadingZeros = BitOperations.LeadingZeroCount(uint.CreateSaturating(value));
int leadingZeros = BitOperations.LeadingZeroCount(uint.CreateTruncating(value));
return VarIntLengths32[leadingZeros];
}
else
{
int leadingZeros = BitOperations.LeadingZeroCount(ulong.CreateSaturating(value));
int leadingZeros = BitOperations.LeadingZeroCount(ulong.CreateTruncating(value));
return VarIntLengths64[leadingZeros];
}
}
Expand Down Expand Up @@ -98,4 +98,4 @@ public static int CountBytes(ReadOnlySpan<byte> str)
{
return GetVarIntLength(str.Length) + str.Length;
}
}
}