@@ -28,8 +28,8 @@ extern "C" {
28
28
#[ cfg( feature = "iterator" ) ]
29
29
fn db_next ( iterator_id : u32 ) -> u32 ;
30
30
31
- fn canonicalize_address ( source : u32 , destination : u32 ) -> i32 ;
32
- fn humanize_address ( source : u32 , destination : u32 ) -> i32 ;
31
+ fn canonicalize_address ( source : u32 , destination : u32 ) -> u32 ;
32
+ fn humanize_address ( source : u32 , destination : u32 ) -> u32 ;
33
33
34
34
/// Executes a query on the chain (import). Not to be confused with the
35
35
/// query export, which queries the state of the contract.
@@ -157,9 +157,13 @@ impl Api for ExternalApi {
157
157
let send_ptr = & * send as * const Region as u32 ;
158
158
let canon = alloc ( CANONICAL_ADDRESS_BUFFER_LENGTH ) ;
159
159
160
- let read = unsafe { canonicalize_address ( send_ptr, canon as u32 ) } ;
161
- if read < 0 {
162
- return Err ( StdError :: generic_err ( "canonicalize_address returned error" ) ) ;
160
+ let result = unsafe { canonicalize_address ( send_ptr, canon as u32 ) } ;
161
+ if result != 0 {
162
+ let error = unsafe { consume_string_region_written_by_vm ( result as * mut Region ) } ;
163
+ return Err ( StdError :: generic_err ( format ! (
164
+ "canonicalize_address errored: {}" ,
165
+ error
166
+ ) ) ) ;
163
167
}
164
168
165
169
let out = unsafe { consume_region ( canon) } ;
@@ -171,18 +175,28 @@ impl Api for ExternalApi {
171
175
let send_ptr = & * send as * const Region as u32 ;
172
176
let human = alloc ( HUMAN_ADDRESS_BUFFER_LENGTH ) ;
173
177
174
- let read = unsafe { humanize_address ( send_ptr, human as u32 ) } ;
175
- if read < 0 {
176
- return Err ( StdError :: generic_err ( "humanize_address returned error" ) ) ;
178
+ let result = unsafe { humanize_address ( send_ptr, human as u32 ) } ;
179
+ if result != 0 {
180
+ let error = unsafe { consume_string_region_written_by_vm ( result as * mut Region ) } ;
181
+ return Err ( StdError :: generic_err ( format ! (
182
+ "humanize_address errored: {}" ,
183
+ error
184
+ ) ) ) ;
177
185
}
178
186
179
- let out = unsafe { consume_region ( human) } ;
180
- // we know input was correct when created, so let's save some bytes
181
- let result = unsafe { String :: from_utf8_unchecked ( out) } ;
182
- Ok ( HumanAddr ( result) )
187
+ let address = unsafe { consume_string_region_written_by_vm ( human) } ;
188
+ Ok ( address. into ( ) )
183
189
}
184
190
}
185
191
192
+ /// Takes a pointer to a Region and reads the data into a String.
193
+ /// This is for trusted string sources only.
194
+ unsafe fn consume_string_region_written_by_vm ( from : * mut Region ) -> String {
195
+ let data = consume_region ( from) ;
196
+ // We trust the VM/chain to return correct UTF-8, so let's save some gas
197
+ String :: from_utf8_unchecked ( data)
198
+ }
199
+
186
200
/// A stateless convenience wrapper around imports provided by the VM
187
201
pub struct ExternalQuerier { }
188
202
0 commit comments