@@ -40,80 +40,42 @@ fn maybe_decompress_gzip(data: &[u8]) -> Option<Cow<'_, [u8]>> {
4040mod tests {
4141 use super :: * ;
4242
43- /// Build a minimal valid WASM module with the given custom sections.
44- /// Each entry is (section_name, section_data).
45- fn build_wasm_with_custom_sections ( sections : & [ ( & str , & [ u8 ] ) ] ) -> Vec < u8 > {
46- let mut wasm = vec ! [
47- 0x00 , 0x61 , 0x73 , 0x6d , // magic: \0asm
48- 0x01 , 0x00 , 0x00 , 0x00 , // version: 1
49- ] ;
50- for ( name, data) in sections {
51- let name_bytes = name. as_bytes ( ) ;
52- // Custom section: id=0, then LEB128 length, then name (LEB128 len + bytes), then data
53- let section_payload_len =
54- leb128_len ( name_bytes. len ( ) as u32 ) + name_bytes. len ( ) + data. len ( ) ;
55- wasm. push ( 0x00 ) ; // custom section id
56- write_leb128 ( & mut wasm, section_payload_len as u32 ) ;
57- write_leb128 ( & mut wasm, name_bytes. len ( ) as u32 ) ;
58- wasm. extend_from_slice ( name_bytes) ;
59- wasm. extend_from_slice ( data) ;
60- }
61- wasm
62- }
63-
64- fn write_leb128 ( buf : & mut Vec < u8 > , mut value : u32 ) {
65- loop {
66- let mut byte = ( value & 0x7f ) as u8 ;
67- value >>= 7 ;
68- if value != 0 {
69- byte |= 0x80 ;
70- }
71- buf. push ( byte) ;
72- if value == 0 {
73- break ;
74- }
75- }
76- }
77-
78- fn leb128_len ( mut value : u32 ) -> usize {
79- let mut len = 0 ;
80- loop {
81- value >>= 7 ;
82- len += 1 ;
83- if value == 0 {
84- break ;
85- }
86- }
87- len
88- }
43+ // (module
44+ // (@custom "icp:public some_other" "irrelevant")
45+ // (@custom "icp:public candid:service" "service : {}")
46+ // (@custom "another_section" "more data")
47+ // )
48+ const UNRELATED_SECTIONS : & [ u8 ] = b"\x00 \x61 \x73 \x6d \x01 \x00 \x00 \x00 \x00 \x20 \x15 \x69 \x63 \x70 \x3a \x70 \x75 \x62 \x6c \x69 \x63 \x20 \x73 \x6f \x6d \x65 \x5f \x6f \x74 \x68 \x65 \x72 \x69 \x72 \x72 \x65 \x6c \x65 \x76 \x61 \x6e \x74 \x00 \x26 \x19 \x69 \x63 \x70 \x3a \x70 \x75 \x62 \x6c \x69 \x63 \x20 \x63 \x61 \x6e \x64 \x69 \x64 \x3a \x73 \x65 \x72 \x76 \x69 \x63 \x65 \x73 \x65 \x72 \x76 \x69 \x63 \x65 \x20 \x3a \x20 \x7b \x7d \x00 \x19 \x0f \x61 \x6e \x6f \x74 \x68 \x65 \x72 \x5f \x73 \x65 \x63 \x74 \x69 \x6f \x6e \x6d \x6f \x72 \x65 \x20 \x64 \x61 \x74 \x61 " ;
49+ // (module (@custom "icp:public some_other" "data") )
50+ const NO_CANDID_SECTION : & [ u8 ] = b"\x00 \x61 \x73 \x6d \x01 \x00 \x00 \x00 \x00 \x1a \x15 \x69 \x63 \x70 \x3a \x70 \x75 \x62 \x6c \x69 \x63 \x20 \x73 \x6f \x6d \x65 \x5f \x6f \x74 \x68 \x65 \x72 \x64 \x61 \x74 \x61 " ;
51+ // (module (@custom "icp:private candid:service" "service : { hello : () -> () }") )
52+ const PRIVATE_SERVICE : & [ u8 ] = b"\x00 \x61 \x73 \x6d \x01 \x00 \x00 \x00 \x00 \x39 \x1a \x69 \x63 \x70 \x3a \x70 \x72 \x69 \x76 \x61 \x74 \x65 \x20 \x63 \x61 \x6e \x64 \x69 \x64 \x3a \x73 \x65 \x72 \x76 \x69 \x63 \x65 \x73 \x65 \x72 \x76 \x69 \x63 \x65 \x20 \x3a \x20 \x7b \x20 \x68 \x65 \x6c \x6c \x6f \x20 \x3a \x20 \x28 \x29 \x20 \x2d \x3e \x20 \x28 \x29 \x20 \x7d " ;
53+ // (module (@custom "icp:public candid:service" "service : { greet : (text) -> (text) }") )
54+ const PUBLIC_SERVICE : & [ u8 ] = b"\x00 \x61 \x73 \x6d \x01 \x00 \x00 \x00 \x00 \x40 \x19 \x69 \x63 \x70 \x3a \x70 \x75 \x62 \x6c \x69 \x63 \x20 \x63 \x61 \x6e \x64 \x69 \x64 \x3a \x73 \x65 \x72 \x76 \x69 \x63 \x65 \x73 \x65 \x72 \x76 \x69 \x63 \x65 \x20 \x3a \x20 \x7b \x20 \x67 \x72 \x65 \x65 \x74 \x20 \x3a \x20 \x28 \x74 \x65 \x78 \x74 \x29 \x20 \x2d \x3e \x20 \x28 \x74 \x65 \x78 \x74 \x29 \x20 \x7d " ;
8955
9056 #[ test]
9157 fn extracts_public_candid_service ( ) {
92- let candid = b"service : { greet : (text) -> (text) }" ;
93- let wasm = build_wasm_with_custom_sections ( & [ ( "icp:public candid:service" , candid) ] ) ;
94- let result = extract_candid_service ( & wasm) ;
9558 assert_eq ! (
96- result . as_deref( ) ,
59+ extract_candid_service ( PUBLIC_SERVICE ) . as_deref( ) ,
9760 Some ( "service : { greet : (text) -> (text) }" )
9861 ) ;
9962 }
10063
10164 #[ test]
10265 fn extracts_private_candid_service ( ) {
103- let candid = b"service : { hello : () -> () }" ;
104- let wasm = build_wasm_with_custom_sections ( & [ ( "icp:private candid:service" , candid ) ] ) ;
105- let result = extract_candid_service ( & wasm ) ;
106- assert_eq ! ( result . as_deref ( ) , Some ( "service : { hello : () -> () }" ) ) ;
66+ assert_eq ! (
67+ extract_candid_service ( PRIVATE_SERVICE ) . as_deref ( ) ,
68+ Some ( "service : { hello : () -> () }" )
69+ ) ;
10770 }
10871
10972 #[ test]
11073 fn returns_none_when_no_candid_section ( ) {
111- let wasm = build_wasm_with_custom_sections ( & [ ( "icp:public some_other" , b"data" ) ] ) ;
112- assert ! ( extract_candid_service( & wasm) . is_none( ) ) ;
74+ assert ! ( extract_candid_service( NO_CANDID_SECTION ) . is_none( ) ) ;
11375 }
11476
11577 #[ test]
116- fn returns_none_for_empty_wasm ( ) {
78+ fn returns_none_for_empty_input ( ) {
11779 assert ! ( extract_candid_service( & [ ] ) . is_none( ) ) ;
11880 }
11981
@@ -127,29 +89,21 @@ mod tests {
12789 use flate2:: write:: GzEncoder ;
12890 use std:: io:: Write ;
12991
130- let candid = b"service : { greet : (text) -> (text) }" ;
131- let wasm = build_wasm_with_custom_sections ( & [ ( "icp:public candid:service" , candid) ] ) ;
132-
13392 let mut encoder = GzEncoder :: new ( Vec :: new ( ) , flate2:: Compression :: default ( ) ) ;
134- encoder. write_all ( & wasm ) . unwrap ( ) ;
93+ encoder. write_all ( PUBLIC_SERVICE ) . unwrap ( ) ;
13594 let compressed = encoder. finish ( ) . unwrap ( ) ;
13695
137- let result = extract_candid_service ( & compressed) ;
13896 assert_eq ! (
139- result . as_deref( ) ,
97+ extract_candid_service ( & compressed ) . as_deref( ) ,
14098 Some ( "service : { greet : (text) -> (text) }" )
14199 ) ;
142100 }
143101
144102 #[ test]
145103 fn skips_unrelated_sections ( ) {
146- let candid = b"service : {}" ;
147- let wasm = build_wasm_with_custom_sections ( & [
148- ( "icp:public some_other" , b"irrelevant" ) ,
149- ( "icp:public candid:service" , candid) ,
150- ( "another_section" , b"more data" ) ,
151- ] ) ;
152- let result = extract_candid_service ( & wasm) ;
153- assert_eq ! ( result. as_deref( ) , Some ( "service : {}" ) ) ;
104+ assert_eq ! (
105+ extract_candid_service( UNRELATED_SECTIONS ) . as_deref( ) ,
106+ Some ( "service : {}" )
107+ ) ;
154108 }
155109}
0 commit comments