33use {
44 crate :: display_to_jsvalue,
55 js_sys:: { Array , Uint8Array } ,
6+ solana_address:: { ADDRESS_BYTES , MAX_SEEDS , MAX_SEED_LEN } ,
67 wasm_bindgen:: { prelude:: wasm_bindgen, JsCast , JsValue } ,
78} ;
89
@@ -15,20 +16,33 @@ pub struct Address {
1516crate :: conversion:: impl_inner_conversion!( Address , solana_address:: Address ) ;
1617
1718fn js_value_to_seeds_vec ( array_of_uint8_arrays : & [ JsValue ] ) -> Result < Vec < Vec < u8 > > , JsValue > {
18- let vec_vec_u8 = array_of_uint8_arrays
19+ if array_of_uint8_arrays. len ( ) > MAX_SEEDS {
20+ return Err ( JsValue :: from ( std:: format!(
21+ "Too many seeds: {} > {}" ,
22+ array_of_uint8_arrays. len( ) ,
23+ MAX_SEEDS
24+ ) ) ) ;
25+ }
26+
27+ array_of_uint8_arrays
1928 . iter ( )
20- . filter_map ( |u8_array| {
21- u8_array
29+ . enumerate ( )
30+ . map ( |( i, u8_array_js) | {
31+ let u8_array = u8_array_js
2232 . dyn_ref :: < Uint8Array > ( )
23- . map ( |u8_array| u8_array. to_vec ( ) )
24- } )
25- . collect :: < Vec < _ > > ( ) ;
33+ . ok_or_else ( || JsValue :: from ( std:: format!( "Invalid seed type at index {}" , i) ) ) ?;
34+ if u8_array. length ( ) as usize > MAX_SEED_LEN {
35+ return Err ( JsValue :: from ( std:: format!(
36+ "Seed {} too long: {} > {}" ,
37+ i,
38+ u8_array. length( ) ,
39+ MAX_SEED_LEN
40+ ) ) ) ;
41+ }
2642
27- if vec_vec_u8. len ( ) != array_of_uint8_arrays. len ( ) {
28- Err ( "Invalid Array of Uint8Arrays" . into ( ) )
29- } else {
30- Ok ( vec_vec_u8)
31- }
43+ Ok ( u8_array. to_vec ( ) )
44+ } )
45+ . collect :: < Result < Vec < _ > , _ > > ( )
3246}
3347
3448#[ allow( non_snake_case) ]
@@ -45,26 +59,40 @@ impl Address {
4559 . map ( Into :: into)
4660 . map_err ( display_to_jsvalue)
4761 } else if let Some ( uint8_array) = value. dyn_ref :: < Uint8Array > ( ) {
48- solana_address:: Address :: try_from ( uint8_array. to_vec ( ) )
49- . map ( Into :: into)
50- . map_err ( |err| JsValue :: from ( std:: format!( "Invalid Uint8Array address: {err:?}" ) ) )
62+ if uint8_array. length ( ) as usize != ADDRESS_BYTES {
63+ return Err ( std:: format!(
64+ "Invalid Uint8Array length: expected {}, got {}" ,
65+ ADDRESS_BYTES ,
66+ uint8_array. length( )
67+ )
68+ . into ( ) ) ;
69+ }
70+ let mut bytes = [ 0u8 ; ADDRESS_BYTES ] ;
71+ uint8_array. copy_to ( & mut bytes) ;
72+ Ok ( solana_address:: Address :: new_from_array ( bytes) . into ( ) )
5173 } else if let Some ( array) = value. dyn_ref :: < Array > ( ) {
52- let mut bytes = std:: vec![ ] ;
74+ if array. length ( ) as usize != ADDRESS_BYTES {
75+ return Err ( std:: format!(
76+ "Invalid Array length: expected {}, got {}" ,
77+ ADDRESS_BYTES ,
78+ array. length( )
79+ )
80+ . into ( ) ) ;
81+ }
82+ let mut bytes = [ 0u8 ; ADDRESS_BYTES ] ;
5383 let iterator = js_sys:: try_iter ( & array. values ( ) ) ?. expect ( "array to be iterable" ) ;
54- for x in iterator {
84+ for ( i , x ) in iterator. enumerate ( ) {
5585 let x = x?;
5686
5787 if let Some ( n) = x. as_f64 ( ) {
5888 if n >= 0. && n <= 255. {
59- bytes. push ( n as u8 ) ;
89+ bytes[ i ] = n as u8 ;
6090 continue ;
6191 }
6292 }
6393 return Err ( std:: format!( "Invalid array argument: {:?}" , x) . into ( ) ) ;
6494 }
65- solana_address:: Address :: try_from ( bytes)
66- . map ( Into :: into)
67- . map_err ( |err| JsValue :: from ( std:: format!( "Invalid Array address: {err:?}" ) ) )
95+ Ok ( solana_address:: Address :: new_from_array ( bytes) . into ( ) )
6896 } else if value. is_undefined ( ) {
6997 Ok ( solana_address:: Address :: default ( ) . into ( ) )
7098 } else {
0 commit comments