Have Invoice Description use UntrustedString
authorbenthecarman <benthecarman@live.com>
Tue, 14 Nov 2023 16:14:30 +0000 (10:14 -0600)
committerbenthecarman <benthecarman@live.com>
Wed, 15 Nov 2023 18:35:35 +0000 (12:35 -0600)
lightning-invoice/src/lib.rs
lightning-invoice/src/ser.rs
lightning-invoice/src/utils.rs
lightning/src/util/string.rs

index d283cba7a8ea671492c191561330c00ad68462e0..42d0a337e4a842ce17230c5977552fb6fa477dc7 100644 (file)
@@ -73,6 +73,7 @@ pub use lightning::ln::PaymentSecret;
 pub use lightning::routing::router::{RouteHint, RouteHintHop};
 #[doc(no_inline)]
 pub use lightning::routing::gossip::RoutingFees;
+use lightning::util::string::UntrustedString;
 
 mod de;
 mod ser;
@@ -480,7 +481,7 @@ impl Sha256 {
 /// # Invariants
 /// The description can be at most 639 __bytes__ long
 #[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Default)]
-pub struct Description(String);
+pub struct Description(UntrustedString);
 
 /// Payee public key
 #[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
@@ -684,7 +685,7 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool> InvoiceBui
        pub fn invoice_description(self, description: Bolt11InvoiceDescription) -> InvoiceBuilder<tb::True, H, T, C, S, M> {
                match description {
                        Bolt11InvoiceDescription::Direct(desc) => {
-                               self.description(desc.clone().into_inner())
+                               self.description(desc.clone().into_inner().0)
                        }
                        Bolt11InvoiceDescription::Hash(hash) => {
                                self.description_hash(hash.0)
@@ -1517,30 +1518,16 @@ impl Description {
                if description.len() > 639 {
                        Err(CreationError::DescriptionTooLong)
                } else {
-                       Ok(Description(description))
+                       Ok(Description(UntrustedString(description)))
                }
        }
 
-       /// Returns the underlying description [`String`]
-       pub fn into_inner(self) -> String {
+       /// Returns the underlying description [`UntrustedString`]
+       pub fn into_inner(self) -> UntrustedString {
                self.0
        }
 }
 
-impl From<Description> for String {
-       fn from(val: Description) -> Self {
-               val.into_inner()
-       }
-}
-
-impl Deref for Description {
-       type Target = str;
-
-       fn deref(&self) -> &str {
-               &self.0
-       }
-}
-
 impl Display for Description {
        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
                write!(f, "{}", self.0)
index dc5dba45da0fe46c24bbf6f8b664dbef76f175b5..fe42f72b6532f593083049832a07f31272cd43a5 100644 (file)
@@ -279,13 +279,13 @@ impl Base32Len for Sha256 {
 
 impl ToBase32 for Description {
        fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
-               self.as_bytes().write_base32(writer)
+               self.0.0.as_bytes().write_base32(writer)
        }
 }
 
 impl Base32Len for Description {
        fn base32_len(&self) -> usize {
-               self.0.as_bytes().base32_len()
+               self.0.0.as_bytes().base32_len()
        }
 }
 
index d551d248a6cc1471fee0e1393d37e9859b0deaa4..f3e642a2ef555877adc4b83f4b4ccbb670f84611 100644 (file)
@@ -158,7 +158,7 @@ where
 
        let invoice = match description {
                Bolt11InvoiceDescription::Direct(description) => {
-                       InvoiceBuilder::new(network).description(description.0.clone())
+                       InvoiceBuilder::new(network).description(description.0.0.clone())
                }
                Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0),
        };
@@ -538,7 +538,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has
 
        let invoice = match description {
                Bolt11InvoiceDescription::Direct(description) => {
-                       InvoiceBuilder::new(network).description(description.0.clone())
+                       InvoiceBuilder::new(network).description(description.0.0.clone())
                }
                Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0),
        };
@@ -808,6 +808,7 @@ mod test {
        use lightning::util::config::UserConfig;
        use crate::utils::{create_invoice_from_channelmanager_and_duration_since_epoch, rotate_through_iterators};
        use std::collections::HashSet;
+       use lightning::util::string::UntrustedString;
 
        #[test]
        fn test_prefer_current_channel() {
@@ -852,7 +853,7 @@ mod test {
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
                // If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`.
                assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
-               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string())));
+               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description(UntrustedString("test".to_string()))));
                assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
 
                // Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is
@@ -963,7 +964,7 @@ mod test {
                ).unwrap();
                assert_eq!(invoice.amount_pico_btc(), Some(100_000));
                assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
-               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string())));
+               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description(UntrustedString("test".to_string()))));
                assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&payment_hash.0[..]).unwrap());
        }
 
@@ -1315,7 +1316,7 @@ mod test {
                };
 
                assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
-               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string())));
+               assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description(UntrustedString("test".to_string()))));
                assert_eq!(invoice.route_hints().len(), 2);
                assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
                assert!(!invoice.features().unwrap().supports_basic_mpp());
index 3e5942f6f04c13b77ceae9401355f86c249bb346..6949c936e00e575ad8b4a848e61ee892a65b3eca 100644 (file)
@@ -16,7 +16,7 @@ use crate::ln::msgs;
 use crate::util::ser::{Writeable, Writer, Readable};
 
 /// Struct to `Display` fields in a safe way using `PrintableString`
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
 pub struct UntrustedString(pub String);
 
 impl Writeable for UntrustedString {