lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit 65eb3825d7f932535fba7fdb563108c7ff19e205
parent 265d1fbb21ec1ae7b17af2c554b60530b99be8da
Author: triesap <tyson@radroots.org>
Date:   Sun, 14 Jun 2026 22:29:23 -0700

trade: prevent unchecked canonical draft deserialization

Diffstat:
Mcrates/trade/src/listing/draft.rs | 17++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/crates/trade/src/listing/draft.rs b/crates/trade/src/listing/draft.rs @@ -37,7 +37,7 @@ impl RadrootsListingDraftDocumentV1 { } } -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] #[derive(Clone, Debug)] pub struct RadrootsCanonicalListingDraft { listing: RadrootsListing, @@ -266,6 +266,21 @@ mod tests { assert_eq!(document.listing.product.title, "Coffee"); } + #[cfg(feature = "serde_json")] + #[test] + fn draft_document_deserializes_as_untrusted_input() { + let json = serde_json::to_string(&RadrootsListingDraftDocumentV1::new(listing())) + .expect("serialize document"); + + let document: RadrootsListingDraftDocumentV1 = + serde_json::from_str(&json).expect("deserialize document"); + let canonical = + canonicalize_listing_draft(&seller_actor(), document).expect("canonical draft"); + + assert_eq!(canonical.seller_pubkey().as_str(), SELLER); + assert_eq!(canonical.listing().product.title, "Coffee"); + } + #[test] fn canonical_draft_carries_seller_listing_and_addresses() { let seller_pubkey = RadrootsPublicKey::parse(SELLER).expect("seller");