diff --git a/src/Neo/Network/P2P/Payloads/Transaction.cs b/src/Neo/Network/P2P/Payloads/Transaction.cs
index 69a1b179e9..16417beb43 100644
--- a/src/Neo/Network/P2P/Payloads/Transaction.cs
+++ b/src/Neo/Network/P2P/Payloads/Transaction.cs
@@ -458,6 +458,7 @@ public virtual VerifyResult VerifyStateIndependent(ProtocolSettings settings)
public StackItem ToStackItem(ReferenceCounter referenceCounter)
{
+ if (_signers == null || _signers.Length == 0) throw new ArgumentException("Sender is not specified in the transaction.");
return new Array(referenceCounter, new StackItem[]
{
// Computed properties
diff --git a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs
index 4314952eec..293b245bd7 100644
--- a/src/Neo/SmartContract/ApplicationEngine.Runtime.cs
+++ b/src/Neo/SmartContract/ApplicationEngine.Runtime.cs
@@ -327,9 +327,16 @@ protected internal BigInteger GetRandom()
/// The message of the log.
protected internal void RuntimeLog(byte[] state)
{
- if (state.Length > MaxNotificationSize) throw new ArgumentException(null, nameof(state));
- string message = Utility.StrictUTF8.GetString(state);
- Log?.Invoke(this, new LogEventArgs(ScriptContainer, CurrentScriptHash, message));
+ if (state.Length > MaxNotificationSize) throw new ArgumentException("Message is too long.", nameof(state));
+ try
+ {
+ string message = Utility.StrictUTF8.GetString(state);
+ Log?.Invoke(this, new LogEventArgs(ScriptContainer, CurrentScriptHash, message));
+ }
+ catch
+ {
+ throw new ArgumentException("Failed to convert byte array to string: Invalid or non-printable UTF-8 sequence detected.", nameof(state));
+ }
}
///
diff --git a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs
index 80bbf45e9d..75e6e7b6da 100644
--- a/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs
+++ b/tests/Neo.UnitTests/SmartContract/UT_ApplicationEngine.Runtime.cs
@@ -175,5 +175,17 @@ public void TestGetRandomDifferentBlock()
rand_4.Should().NotBe(rand_9);
rand_5.Should().NotBe(rand_10);
}
+
+ [TestMethod]
+ public void TestInvalidUtf8LogMessage()
+ {
+ var tx_1 = TestUtils.GetTransaction(UInt160.Zero);
+ using var engine = ApplicationEngine.Create(TriggerType.Application, tx_1, null, TestBlockchain.TheNeoSystem.GenesisBlock, settings: TestBlockchain.TheNeoSystem.Settings, gas: 1100_00000000);
+ var msg = new byte[]
+ {
+ 68, 216, 160, 6, 89, 102, 86, 72, 37, 15, 132, 45, 76, 221, 170, 21, 128, 51, 34, 168, 205, 56, 10, 228, 51, 114, 4, 218, 245, 155, 172, 132
+ };
+ Assert.ThrowsException(() => engine.RuntimeLog(msg));
+ }
}
}