[ethcore/builtin]: do not panic in blake2pricer on short input (#11180)

* [ethcore/builtin]: do not panic in blake2pricer on short input

* [ethcore/builtin]: add a test for blake2pricer
This commit is contained in:
Andronik Ordian 2019-10-18 15:10:00 +02:00 committed by Marek Kotewicz
parent ff697b64b3
commit 3696f68626

View File

@ -18,7 +18,7 @@
use std::{ use std::{
cmp::{max, min}, cmp::{max, min},
convert::TryFrom, convert::{TryFrom, TryInto},
io::{self, Read, Cursor}, io::{self, Read, Cursor},
mem::size_of, mem::size_of,
}; };
@ -56,11 +56,14 @@ pub type Blake2FPricer = u64;
impl Pricer for Blake2FPricer { impl Pricer for Blake2FPricer {
fn cost(&self, input: &[u8], _at: u64) -> U256 { fn cost(&self, input: &[u8], _at: u64) -> U256 {
use std::convert::TryInto; const FOUR: usize = std::mem::size_of::<u32>();
let (rounds_bytes, _) = input.split_at(std::mem::size_of::<u32>());
// Returning zero if the conversion fails is fine because `execute()` will check the length // Returning zero if the conversion fails is fine because `execute()` will check the length
// and bail with the appropriate error. // and bail with the appropriate error.
let rounds = u32::from_be_bytes(rounds_bytes.try_into().unwrap_or([0u8; 4])); if input.len() < FOUR {
return U256::zero();
}
let (rounds_bytes, _) = input.split_at(FOUR);
let rounds = u32::from_be_bytes(rounds_bytes.try_into().unwrap_or([0u8; FOUR]));
U256::from(*self as u128 * rounds as u128) U256::from(*self as u128 * rounds as u128)
} }
} }
@ -708,6 +711,19 @@ mod tests {
assert_eq!(f.cost(&input[..], 0), U256::from(123*5)); assert_eq!(f.cost(&input[..], 0), U256::from(123*5));
} }
#[test]
fn blake2f_cost_on_invalid_length() {
let f = Builtin {
pricer: Box::new(123),
native: ethereum_builtin("blake2_f").expect("known builtin"),
activate_at: 0,
};
// invalid input (too short)
let input = hex!("00");
assert_eq!(f.cost(&input[..], 0), U256::from(0));
}
#[test] #[test]
fn blake2_f_is_err_on_invalid_length() { fn blake2_f_is_err_on_invalid_length() {
let blake2 = ethereum_builtin("blake2_f").expect("known builtin"); let blake2 = ethereum_builtin("blake2_f").expect("known builtin");