diff --git a/Cargo.lock b/Cargo.lock index e5df7a02c..6ccbcac6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1207,8 +1207,8 @@ dependencies = [ name = "hash" version = "0.1.0" dependencies = [ + "cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore-bigint 0.1.3", - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/ethcore/src/builtin.rs b/ethcore/src/builtin.rs index 3a63930aa..ab3144ce4 100644 --- a/ethcore/src/builtin.rs +++ b/ethcore/src/builtin.rs @@ -123,7 +123,11 @@ impl Pricer for ModexpPricer { let adjusted_exp_len = Self::adjusted_exp_len(exp_len, exp_low); - (Self::mult_complexity(m) * max(adjusted_exp_len, 1) / self.divisor as u64).into() + let (gas, overflow) = Self::mult_complexity(m).overflowing_mul(max(adjusted_exp_len, 1)); + if overflow { + return U256::max_value(); + } + (gas / self.divisor as u64).into() } } @@ -706,6 +710,14 @@ mod tests { activate_at: 0, }; + // test for potential gas cost multiplication overflow + { + let input = FromHex::from_hex("0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b27bafd00000000000000000000000000000000000000000000000000000000503c8ac3").unwrap(); + let expected_cost = U256::max_value(); + assert_eq!(f.cost(&input[..]), expected_cost.into()); + } + + // test for potential exp len overflow { let input = FromHex::from_hex("\ diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 18d800546..774256d02 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -1203,6 +1203,16 @@ mod tests { use toml; use clap::{ErrorKind as ClapErrorKind}; + + #[test] + fn should_reject_invalid_values() { + let args = Args::parse(&["parity", "--cache=20"]); + assert!(args.is_ok()); + + let args = Args::parse(&["parity", "--cache=asd"]); + assert!(args.is_err()); + } + #[test] fn should_parse_args_and_flags() { let args = Args::parse(&["parity", "--no-warp"]).unwrap(); diff --git a/parity/cli/usage.rs b/parity/cli/usage.rs index dd370bdbc..83b878ee1 100644 --- a/parity/cli/usage.rs +++ b/parity/cli/usage.rs @@ -32,6 +32,20 @@ macro_rules! otry { ) } +macro_rules! return_if_parse_error { + ($e:expr) => ( + match $e { + Err(clap_error @ ClapError { kind: ClapErrorKind::ValueValidation, .. }) => { + return Err(clap_error); + }, + + // Otherwise, if $e is ClapErrorKind::ArgumentNotFound or Ok(), + // then convert to Option + _ => $e.ok() + } + ) +} + macro_rules! if_option { (Option<$type:ty>, THEN {$($then:tt)*} ELSE {$($otherwise:tt)*}) => ( $($then)* @@ -139,7 +153,7 @@ macro_rules! usage { use std::{fs, io, process}; use std::io::{Read, Write}; use util::version; - use clap::{Arg, App, SubCommand, AppSettings, Error as ClapError}; + use clap::{Arg, App, SubCommand, AppSettings, Error as ClapError, ErrorKind as ClapErrorKind}; use helpers::replace_home; use std::ffi::OsStr; use std::collections::HashMap; @@ -563,23 +577,23 @@ macro_rules! usage { raw_args.$flag = matches.is_present(stringify!($flag)); )* $( - raw_args.$arg = if_option!( + raw_args.$arg = return_if_parse_error!(if_option!( $($arg_type_tt)+, THEN { if_option_vec!( $($arg_type_tt)+, - THEN { values_t!(matches, stringify!($arg), inner_option_vec_type!($($arg_type_tt)+)).ok() } - ELSE { value_t!(matches, stringify!($arg), inner_option_type!($($arg_type_tt)+)).ok() } + THEN { values_t!(matches, stringify!($arg), inner_option_vec_type!($($arg_type_tt)+)) } + ELSE { value_t!(matches, stringify!($arg), inner_option_type!($($arg_type_tt)+)) } ) } ELSE { if_vec!( $($arg_type_tt)+, - THEN { values_t!(matches, stringify!($arg), inner_vec_type!($($arg_type_tt)+)).ok() } - ELSE { value_t!(matches, stringify!($arg), $($arg_type_tt)+).ok() } + THEN { values_t!(matches, stringify!($arg), inner_vec_type!($($arg_type_tt)+)) } + ELSE { value_t!(matches, stringify!($arg), $($arg_type_tt)+) } ) } - ); + )); )* )* @@ -594,23 +608,23 @@ macro_rules! usage { )* // Subcommand arguments $( - raw_args.$subc_arg = if_option!( + raw_args.$subc_arg = return_if_parse_error!(if_option!( $($subc_arg_type_tt)+, THEN { if_option_vec!( $($subc_arg_type_tt)+, - THEN { values_t!(submatches, stringify!($subc_arg), inner_option_vec_type!($($subc_arg_type_tt)+)).ok() } - ELSE { value_t!(submatches, stringify!($subc_arg), inner_option_type!($($subc_arg_type_tt)+)).ok() } + THEN { values_t!(submatches, stringify!($subc_arg), inner_option_vec_type!($($subc_arg_type_tt)+)) } + ELSE { value_t!(submatches, stringify!($subc_arg), inner_option_type!($($subc_arg_type_tt)+)) } ) } ELSE { if_vec!( $($subc_arg_type_tt)+, - THEN { values_t!(submatches, stringify!($subc_arg), inner_vec_type!($($subc_arg_type_tt)+)).ok() } - ELSE { value_t!(submatches, stringify!($subc_arg), $($subc_arg_type_tt)+).ok() } + THEN { values_t!(submatches, stringify!($subc_arg), inner_vec_type!($($subc_arg_type_tt)+)) } + ELSE { value_t!(submatches, stringify!($subc_arg), $($subc_arg_type_tt)+) } ) } - ); + )); )* // Sub-subcommands @@ -624,23 +638,23 @@ macro_rules! usage { )* // Sub-subcommand arguments $( - raw_args.$subc_subc_arg = if_option!( + raw_args.$subc_subc_arg = return_if_parse_error!(if_option!( $($subc_subc_arg_type_tt)+, THEN { if_option_vec!( $($subc_subc_arg_type_tt)+, - THEN { values_t!(subsubmatches, stringify!($subc_subc_arg), inner_option_vec_type!($($subc_subc_arg_type_tt)+)).ok() } - ELSE { value_t!(subsubmatches, stringify!($subc_subc_arg), inner_option_type!($($subc_subc_arg_type_tt)+)).ok() } + THEN { values_t!(subsubmatches, stringify!($subc_subc_arg), inner_option_vec_type!($($subc_subc_arg_type_tt)+)) } + ELSE { value_t!(subsubmatches, stringify!($subc_subc_arg), inner_option_type!($($subc_subc_arg_type_tt)+)) } ) } ELSE { if_vec!( $($subc_subc_arg_type_tt)+, - THEN { values_t!(subsubmatches, stringify!($subc_subc_arg), inner_vec_type!($($subc_subc_arg_type_tt)+)).ok() } - ELSE { value_t!(subsubmatches, stringify!($subc_subc_arg), $($subc_subc_arg_type_tt)+).ok() } + THEN { values_t!(subsubmatches, stringify!($subc_subc_arg), inner_vec_type!($($subc_subc_arg_type_tt)+)) } + ELSE { value_t!(subsubmatches, stringify!($subc_subc_arg), $($subc_subc_arg_type_tt)+) } ) } - ); + )); )* } else { diff --git a/util/hash/Cargo.toml b/util/hash/Cargo.toml index 91a195468..0b0502721 100644 --- a/util/hash/Cargo.toml +++ b/util/hash/Cargo.toml @@ -12,7 +12,7 @@ ethcore-bigint = { path = "../bigint" } tiny-keccak = "1.3" [build-dependencies] -gcc = "0.3" +cc = "1.0" [dev-dependencies] tempdir = "0.3" diff --git a/util/hash/build.rs b/util/hash/build.rs index fe7965a61..eecb804f9 100644 --- a/util/hash/build.rs +++ b/util/hash/build.rs @@ -16,11 +16,11 @@ // build.rs -// Bring in a dependency on an externally maintained `gcc` package which manages +// Bring in a dependency on an externally maintained `cc` package which manages // invoking the C compiler. -extern crate gcc; +extern crate cc; fn main() { - gcc::Build::new().file("src/tinykeccak.c").compile("libtinykeccak.a"); + cc::Build::new().file("src/tinykeccak.c").compile("libtinykeccak.a"); }