@@ -35,6 +35,30 @@ use alloc::{boxed::Box, vec::Vec, string::String};
3535
3636use core:: convert:: TryFrom ;
3737
38+ /// [`core::slice::from_raw_parts`] requires the pointer to be non-NULL even if the len is 0, which
39+ /// is annoying, so we wrap it here and fill in garbage in that case.
40+ pub ( crate ) unsafe fn from_raw_parts_safer_mut < ' a , T > ( data : * mut T , len : usize ) -> & ' a mut [ T ] {
41+ if len == 0 {
42+ core:: slice:: from_raw_parts_mut ( core:: ptr:: NonNull :: dangling ( ) . as_ptr ( ) , len)
43+ } else {
44+ assert ! ( data != core:: ptr:: null_mut( ) ) ;
45+ assert ! ( data != core:: ptr:: NonNull :: dangling( ) . as_ptr( ) ) ;
46+ core:: slice:: from_raw_parts_mut ( data, len)
47+ }
48+ }
49+
50+ /// [`core::slice::from_raw_parts`] requires the pointer to be non-NULL even if the len is 0, which
51+ /// is annoying, so we wrap it here and fill in garbage in that case.
52+ pub ( crate ) unsafe fn from_raw_parts_safer < ' a , T > ( data : * const T , len : usize ) -> & ' a [ T ] {
53+ if len == 0 {
54+ core:: slice:: from_raw_parts ( core:: ptr:: NonNull :: dangling ( ) . as_ptr ( ) , len)
55+ } else {
56+ assert ! ( data != core:: ptr:: null( ) ) ;
57+ assert ! ( data != core:: ptr:: NonNull :: dangling( ) . as_ptr( ) ) ;
58+ core:: slice:: from_raw_parts ( data, len)
59+ }
60+ }
61+
3862#[ repr( C ) ]
3963/// A dummy struct of which an instance must never exist.
4064/// This corresponds to the Rust type `Infallible`, or, in unstable rust, `!`
@@ -575,7 +599,7 @@ impl Transaction {
575599 }
576600 pub ( crate ) fn into_bitcoin ( & self ) -> BitcoinTransaction {
577601 if self . datalen == 0 { panic ! ( "0-length buffer can never represent a valid Transaction" ) ; }
578- :: bitcoin:: consensus:: encode:: deserialize ( unsafe { core :: slice :: from_raw_parts ( self . data , self . datalen ) } ) . unwrap ( )
602+ :: bitcoin:: consensus:: encode:: deserialize ( unsafe { from_raw_parts_safer ( self . data , self . datalen ) } ) . unwrap ( )
579603 }
580604 pub ( crate ) fn from_bitcoin ( btc : & BitcoinTransaction ) -> Self {
581605 let vec = :: bitcoin:: consensus:: encode:: serialize ( btc) ;
@@ -591,7 +615,7 @@ impl Drop for Transaction {
591615}
592616impl Clone for Transaction {
593617 fn clone ( & self ) -> Self {
594- let sl = unsafe { core :: slice :: from_raw_parts ( self . data , self . datalen ) } ;
618+ let sl = unsafe { from_raw_parts_safer ( self . data , self . datalen ) } ;
595619 let mut v = Vec :: new ( ) ;
596620 v. extend_from_slice ( & sl) ;
597621 Self :: from_vec ( v)
@@ -624,7 +648,7 @@ impl Witness {
624648 }
625649 }
626650 pub ( crate ) fn into_bitcoin ( & self ) -> BitcoinWitness {
627- :: bitcoin:: consensus:: encode:: deserialize ( unsafe { core :: slice :: from_raw_parts ( self . data , self . datalen ) } ) . unwrap ( )
651+ :: bitcoin:: consensus:: encode:: deserialize ( unsafe { from_raw_parts_safer ( self . data , self . datalen ) } ) . unwrap ( )
628652 }
629653 pub ( crate ) fn from_bitcoin ( btc : & BitcoinWitness ) -> Self {
630654 let vec = :: bitcoin:: consensus:: encode:: serialize ( btc) ;
@@ -641,7 +665,7 @@ impl Drop for Witness {
641665}
642666impl Clone for Witness {
643667 fn clone ( & self ) -> Self {
644- let sl = unsafe { core :: slice :: from_raw_parts ( self . data , self . datalen ) } ;
668+ let sl = unsafe { from_raw_parts_safer ( self . data , self . datalen ) } ;
645669 let mut v = Vec :: new ( ) ;
646670 v. extend_from_slice ( & sl) ;
647671 Self :: from_vec ( v)
@@ -797,12 +821,7 @@ impl u8slice {
797821 }
798822 }
799823 pub ( crate ) fn to_slice ( & self ) -> & [ u8 ] {
800- if self . datalen == 0 { return & [ ] ; }
801- unsafe { core:: slice:: from_raw_parts ( self . data , self . datalen ) }
802- }
803- pub ( crate ) fn to_reader < ' a > ( & ' a self ) -> Cursor < & ' a [ u8 ] > {
804- let sl = self . to_slice ( ) ;
805- Cursor :: new ( sl)
824+ unsafe { from_raw_parts_safer ( self . data , self . datalen ) }
806825 }
807826 pub ( crate ) fn from_vec ( v : & derived:: CVec_u8Z ) -> u8slice {
808827 Self :: from_slice ( v. as_slice ( ) )
@@ -897,20 +916,20 @@ impl Into<Str> for &mut &str {
897916impl Str {
898917 pub ( crate ) fn into_str ( & self ) -> & ' static str {
899918 if self . len == 0 { return "" ; }
900- core:: str:: from_utf8 ( unsafe { core :: slice :: from_raw_parts ( self . chars , self . len ) } ) . unwrap ( )
919+ core:: str:: from_utf8 ( unsafe { from_raw_parts_safer ( self . chars , self . len ) } ) . unwrap ( )
901920 }
902921 pub ( crate ) fn into_string ( mut self ) -> String {
903922 let bytes = if self . len == 0 {
904923 Vec :: new ( )
905924 } else if self . chars_is_owned {
906925 let ret = unsafe {
907- Box :: from_raw ( core :: slice :: from_raw_parts_mut ( unsafe { self . chars as * mut u8 } , self . len ) )
926+ Box :: from_raw ( from_raw_parts_safer_mut ( unsafe { self . chars as * mut u8 } , self . len ) )
908927 } . into ( ) ;
909928 self . chars_is_owned = false ;
910929 ret
911930 } else {
912931 let mut ret = Vec :: with_capacity ( self . len ) ;
913- ret. extend_from_slice ( unsafe { core :: slice :: from_raw_parts ( self . chars , self . len ) } ) ;
932+ ret. extend_from_slice ( unsafe { from_raw_parts_safer ( self . chars , self . len ) } ) ;
914933 ret
915934 } ;
916935 String :: from_utf8 ( bytes) . unwrap ( )
0 commit comments