git.delta.rocks / unique-network / refs/commits / cc62c5af1e87

difftreelog

fix(evm-coder) subresult parsing

Yaroslav Bolyukin2021-08-11parent: #36b556a.patch.diff
in: master
Subresult offset should be based on current subresult start, not on
current item offset

1 file changed

modifiedcrates/evm-coder/src/abi.rsdiffbeforeafterboth
19#[derive(Clone)]19#[derive(Clone)]
20pub struct AbiReader<'i> {20pub struct AbiReader<'i> {
21 buf: &'i [u8],21 buf: &'i [u8],
22 subresult_offset: usize,
22 offset: usize,23 offset: usize,
23}24}
24impl<'i> AbiReader<'i> {25impl<'i> AbiReader<'i> {
25 pub fn new(buf: &'i [u8]) -> Self {26 pub fn new(buf: &'i [u8]) -> Self {
26 Self { buf, offset: 0 }27 Self {
28 buf,
29 subresult_offset: 0,
30 offset: 0,
31 }
27 }32 }
28 pub fn new_call(buf: &'i [u8]) -> Result<(u32, Self)> {33 pub fn new_call(buf: &'i [u8]) -> Result<(u32, Self)> {
41 u32::from_be_bytes(method_id),
42 Self {
43 buf,
44 subresult_offset: 4,
45 offset: 4,
46 },
47 ))
36 }48 }
3749
38 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {50 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {
39 if self.buf.len() - self.offset < 32 {51 if self.buf.len() - self.offset < ABI_ALIGNMENT {
40 return Err(Error::Error(ExitError::OutOfOffset));52 return Err(Error::Error(ExitError::OutOfOffset));
41 }53 }
42 let mut block = [0; S];54 let mut block = [0; S];
106118
107 fn subresult(&mut self) -> Result<AbiReader<'i>> {119 fn subresult(&mut self) -> Result<AbiReader<'i>> {
108 let offset = self.read_usize()?;120 let offset = self.read_usize()?;
121 if offset + self.subresult_offset > self.buf.len() {
122 return Err(Error::Error(ExitError::InvalidRange));
123 }
109 Ok(AbiReader {124 Ok(AbiReader {
110 buf: self.buf,125 buf: self.buf,
126 subresult_offset: offset + self.subresult_offset,
111 offset: offset + self.offset,127 offset: offset + self.subresult_offset,
112 })128 })
113 }129 }
114130
199 for (static_offset, part) in self.dynamic_part {215 for (static_offset, part) in self.dynamic_part {
200 let part_offset = self.static_part.len();216 let part_offset = self.static_part.len();
201217
202 let encoded_dynamic_offset = usize::to_be_bytes(part_offset - static_offset);218 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);
203 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()219 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()
204 ..static_offset + ABI_ALIGNMENT]220 ..static_offset + ABI_ALIGNMENT]
205 .copy_from_slice(&encoded_dynamic_offset);221 .copy_from_slice(&encoded_dynamic_offset);
290 }}306 }}
291}307}
308
309#[cfg(test)]
310pub mod test {
311 use super::{AbiReader, AbiWriter};
312 use hex_literal::hex;
313
314 #[test]
315 fn dynamic_after_static() {
316 let mut encoder = AbiWriter::new();
317 encoder.bool(&true);
318 encoder.string("test");
319 let encoded = encoder.finish();
320
321 let mut encoder = AbiWriter::new();
322 encoder.bool(&true);
323 // Offset to subresult
324 encoder.uint32(&(32 * 2));
325 // Len of "test"
326 encoder.uint32(&4);
327 encoder.write_padright(&[b't', b'e', b's', b't']);
328 let alternative_encoded = encoder.finish();
329
330 assert_eq!(encoded, alternative_encoded);
331
332 let mut decoder = AbiReader::new(&encoded);
333 assert_eq!(decoder.bool().unwrap(), true);
334 assert_eq!(decoder.string().unwrap(), "test");
335 }
336
337 #[test]
338 fn mint_sample() {
339 let (call, mut decoder) = AbiReader::new_call(&hex!(
340 "
341 50bb4e7f
342 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374
343 0000000000000000000000000000000000000000000000000000000000000001
344 0000000000000000000000000000000000000000000000000000000000000060
345 0000000000000000000000000000000000000000000000000000000000000008
346 5465737420555249000000000000000000000000000000000000000000000000
347 "
348 ))
349 .unwrap();
350 assert_eq!(call, 0x50bb4e7f);
351 assert_eq!(
352 format!("{:?}", decoder.address().unwrap()),
353 "0xad2c0954693c2b5404b7e50967d3481bea432374"
354 );
355 assert_eq!(decoder.uint32().unwrap(), 1);
356 assert_eq!(decoder.string().unwrap(), "Test URI");
357 }
358}
292359