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)); + } } }