@@ -101,18 +101,17 @@ impl Pricer for ModexpPricer {
101
101
let exp_len = read_len ( ) ;
102
102
let mod_len = read_len ( ) ;
103
103
104
+ if mod_len. is_zero ( ) && base_len. is_zero ( ) {
105
+ return U256 :: zero ( )
106
+ }
107
+
104
108
let max_len = U256 :: from ( u32:: max_value ( ) / 2 ) ;
105
- if base_len > max_len || mod_len > max_len {
109
+ if base_len > max_len || mod_len > max_len || exp_len > max_len {
106
110
return U256 :: max_value ( ) ;
107
111
}
112
+ let ( base_len, exp_len, mod_len) = ( base_len. low_u64 ( ) , exp_len. low_u64 ( ) , mod_len. low_u64 ( ) ) ;
108
113
109
- let base_len = base_len. low_u64 ( ) ;
110
- let exp_len = exp_len. low_u64 ( ) ;
111
- let mod_len = mod_len. low_u64 ( ) ;
112
114
let m = max ( mod_len, base_len) ;
113
- if m == 0 {
114
- return U256 :: zero ( ) ;
115
- }
116
115
// read fist 32-byte word of the exponent.
117
116
let exp_low = if base_len + 96 >= input. len ( ) as u64 { U256 :: zero ( ) } else {
118
117
let mut buf = [ 0 ; 32 ] ;
@@ -133,8 +132,7 @@ impl ModexpPricer {
133
132
let bit_index = if exp_low. is_zero ( ) { 0 } else { ( 255 - exp_low. leading_zeros ( ) ) as u64 } ;
134
133
if len <= 32 {
135
134
bit_index
136
- }
137
- else {
135
+ } else {
138
136
8 * ( len - 32 ) + bit_index
139
137
}
140
138
}
@@ -707,6 +705,24 @@ mod tests {
707
705
native : ethereum_builtin ( "modexp" ) ,
708
706
activate_at : 0 ,
709
707
} ;
708
+
709
+ // test for potential exp len overflow
710
+ {
711
+ let input = FromHex :: from_hex ( "\
712
+ 00000000000000000000000000000000000000000000000000000000000000ff\
713
+ 2a1e530000000000000000000000000000000000000000000000000000000000\
714
+ 0000000000000000000000000000000000000000000000000000000000000000"
715
+ ) . unwrap ( ) ;
716
+
717
+ let mut output = vec ! [ 0u8 ; 32 ] ;
718
+ let expected = FromHex :: from_hex ( "0000000000000000000000000000000000000000000000000000000000000000" ) . unwrap ( ) ;
719
+ let expected_cost = U256 :: max_value ( ) ;
720
+
721
+ f. execute ( & input[ ..] , & mut BytesRef :: Fixed ( & mut output[ ..] ) ) . expect ( "Builtin should fail" ) ;
722
+ assert_eq ! ( output, expected) ;
723
+ assert_eq ! ( f. cost( & input[ ..] ) , expected_cost. into( ) ) ;
724
+ }
725
+
710
726
// fermat's little theorem example.
711
727
{
712
728
let input = FromHex :: from_hex ( "\
0 commit comments