From 60e5c4d2dd6cecd9cc3dd04a9a7e896cdceff44f Mon Sep 17 00:00:00 2001 From: TimothyBanks Date: Thu, 24 Sep 2026 17:14:02 -0400 Subject: [PATCH] fix: Check the result of STI_VL against kMaxWasmDataLength on host side --- src/libxrpl/tx/wasm/HostFuncImplGetter.cpp | 5 +++ .../tx/wasm/host_functions/TxField.cpp | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp b/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp index 49a64e4826..84fdab5dc3 100644 --- a/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp +++ b/src/libxrpl/tx/wasm/HostFuncImplGetter.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,10 @@ getAnyFieldData(STBase const* obj) case STI_VL: { auto const* vl(static_cast(obj)); // NOLINT auto const& data = vl->value(); + if (data.size() > kMaxWasmDataLength) + { + return std::unexpected{HostFunctionError::DataFieldTooLarge}; + } return Bytes{data.begin(), data.end()}; } diff --git a/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp b/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp index c0dd8efdc7..ad6120e7b5 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp @@ -1,7 +1,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -12,6 +14,7 @@ #include #include +#include #include #include #include @@ -169,4 +172,37 @@ TEST_F(TxFieldImpl, EscrowTxMatchesGeneric) owner, sfGeneric, escrowFinishTx(ledger, owner), HostFunctionError::FieldNotFound); } +namespace { + +TxAssembler +bytecodeTx(Account const& acct, std::size_t size) +{ + return {.type = ttESCROW_CREATE, .build = [acct, size](STObject& obj) { + obj.setAccountID(sfAccount, acct.id()); + obj.setFieldVL(sfBytecode, Bytes(size, 0x42)); + }}; +} + +} // namespace + +TEST_F(TxFieldImpl, AnOversizedBlobIsRefusedWhereItIsRead) +{ + auto const owner = Account{"owner"}; + ledger.createAccount(owner, XRP(1000)); + checkTxFieldError( + owner, + sfBytecode, + bytecodeTx(owner, kMaxWasmDataLength + 1), + HostFunctionError::DataFieldTooLarge); +} + +TEST_F(TxFieldImpl, ABlobAtTheCapIsStillRead) +{ + auto const owner = Account{"owner"}; + ledger.createAccount(owner, XRP(1000)); + checkTxField(owner, sfBytecode, bytecodeTx(owner, kMaxWasmDataLength), [] { + return Bytes(kMaxWasmDataLength, 0x42); + }); +} + } // namespace xrpl::test