From da9d2ca71960b0d4a04bf8abd87416c73a771d69 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Wed, 9 Oct 2019 11:06:55 -0400 Subject: [PATCH 1/3] Replace `uninitialized` with `MaybeUninit` `mem::uninitialized` is deprecated and unsafe. This replaces its use with `mem::MaybeUninit` and adds a proof that the use of `mem::MaybeUninit` is correct. Requested by @niklasad1. --- uint/src/uint.rs | 57 ++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/uint/src/uint.rs b/uint/src/uint.rs index cc58ee220..07718ccbf 100644 --- a/uint/src/uint.rs +++ b/uint/src/uint.rs @@ -77,41 +77,36 @@ macro_rules! uint_overflowing_binop { let $name(ref me) = $self_expr; let $name(ref you) = $other; - let mut ret = unsafe { $crate::core_::mem::uninitialized() }; - let ret_ptr = &mut ret as *mut [u64; $n_words] as *mut u64; - let mut carry = 0u64; - - unroll! { - for i in 0..$n_words { - use $crate::core_::ptr; - - if carry != 0 { - let (res1, overflow1) = ($fn)(me[i], you[i]); - let (res2, overflow2) = ($fn)(res1, carry); - - unsafe { - ptr::write( - ret_ptr.offset(i as _), - res2 - ); - } - carry = (overflow1 as u8 + overflow2 as u8) as u64; - } else { - let (res, overflow) = ($fn)(me[i], you[i]); - - unsafe { - ptr::write( - ret_ptr.offset(i as _), - res - ); + use $crate::core_::mem::MaybeUninit; + unsafe { + // SAFETY: MaybeUninit need not be initialized + let mut ret: [MaybeUninit; $n_words] = MaybeUninit::uninit().assume_init(); + let ret_ptr = &mut ret as *mut [MaybeUninit; $n_words] as *mut MaybeUninit; + let mut carry = 0u64; + assert!($n_words < $crate::core_::isize::MAX as usize, "overly excessive $n_words"); + unroll! { + for i in 0..$n_words { + use $crate::core_::ptr; + + if carry != 0 { + let (res1, overflow1) = ($fn)(me[i], you[i]); + let (res2, overflow2) = ($fn)(res1, carry); + // SAFETY: i < isize::MAX and i is within bounds. + *ret_ptr.offset(i as _) = MaybeUninit::new(res2); + carry = (overflow1 as u8 + overflow2 as u8) as u64; + } else { + let (res, overflow) = ($fn)(me[i], you[i]); + // SAFETY: i < isize::MAX and i is within bounds. + *ret_ptr.offset(i as _) = MaybeUninit::new(res); + carry = overflow as u64; } - - carry = overflow as u64; } } - } - ($name(ret), carry > 0) + // SAFETY: MaybeUninit has the same representation as T, and + // `ret` has been fully initialized. + ($name($crate::core_::mem::transmute(ret)), carry > 0) + } }) } From 5582d2f8b06bdb9315f4fe4567751119f24edff8 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Mon, 14 Oct 2019 13:57:37 -0400 Subject: [PATCH 2/3] Replace mem::uninitialized() with zero initialization This generates the same assembly and is safer. --- fixed-hash/Cargo.toml | 2 +- fixed-hash/src/hash.rs | 1 - uint/Cargo.toml | 1 + uint/src/lib.rs | 3 +++ uint/src/uint.rs | 55 ++++++++++++++++++++++-------------------- 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/fixed-hash/Cargo.toml b/fixed-hash/Cargo.toml index 8672c6d31..e494fedd2 100644 --- a/fixed-hash/Cargo.toml +++ b/fixed-hash/Cargo.toml @@ -18,7 +18,7 @@ rand = { version = "0.7", optional = true, default-features = false } rustc-hex = { version = "2.0", optional = true, default-features = false } quickcheck = { version = "0.9", optional = true } byteorder = { version = "1.2", optional = true, default-features = false } -static_assertions = "0.3" +static_assertions = "1.0.0" [dev-dependencies] rand_xorshift = "0.2.0" diff --git a/fixed-hash/src/hash.rs b/fixed-hash/src/hash.rs index f8ffcb426..393b4cc93 100644 --- a/fixed-hash/src/hash.rs +++ b/fixed-hash/src/hash.rs @@ -779,7 +779,6 @@ macro_rules! impl_ops_for_hash { macro_rules! impl_fixed_hash_conversions { ($large_ty:ident, $small_ty:ident) => { $crate::static_assertions::const_assert!( - VALID_SIZES; $crate::core_::mem::size_of::<$small_ty>() < $crate::core_::mem::size_of::<$large_ty>() ); diff --git a/uint/Cargo.toml b/uint/Cargo.toml index e35d809b6..cf6a88d03 100644 --- a/uint/Cargo.toml +++ b/uint/Cargo.toml @@ -14,6 +14,7 @@ byteorder = { version = "1", default-features = false } rustc-hex = { version = "2.0", default-features = false } quickcheck = { version = "0.6", optional = true } crunchy = { version = "0.2", default-features = true } +static_assertions = "1.0.0" [features] default = ["std"] diff --git a/uint/src/lib.rs b/uint/src/lib.rs index 352ccf70d..5427c8064 100644 --- a/uint/src/lib.rs +++ b/uint/src/lib.rs @@ -25,6 +25,9 @@ pub extern crate rustc_hex; #[doc(hidden)] pub extern crate quickcheck; +#[doc(hidden)] +pub extern crate static_assertions; + extern crate crunchy; pub use crunchy::unroll; diff --git a/uint/src/uint.rs b/uint/src/uint.rs index 07718ccbf..3470b9abd 100644 --- a/uint/src/uint.rs +++ b/uint/src/uint.rs @@ -74,39 +74,42 @@ macro_rules! impl_try_from_for_primitive { #[doc(hidden)] macro_rules! uint_overflowing_binop { ($name:ident, $n_words: tt, $self_expr: expr, $other: expr, $fn:expr) => ({ + use $crate::{core_ as core}; let $name(ref me) = $self_expr; let $name(ref you) = $other; - use $crate::core_::mem::MaybeUninit; - unsafe { - // SAFETY: MaybeUninit need not be initialized - let mut ret: [MaybeUninit; $n_words] = MaybeUninit::uninit().assume_init(); - let ret_ptr = &mut ret as *mut [MaybeUninit; $n_words] as *mut MaybeUninit; - let mut carry = 0u64; - assert!($n_words < $crate::core_::isize::MAX as usize, "overly excessive $n_words"); - unroll! { - for i in 0..$n_words { - use $crate::core_::ptr; - - if carry != 0 { - let (res1, overflow1) = ($fn)(me[i], you[i]); - let (res2, overflow2) = ($fn)(res1, carry); - // SAFETY: i < isize::MAX and i is within bounds. - *ret_ptr.offset(i as _) = MaybeUninit::new(res2); - carry = (overflow1 as u8 + overflow2 as u8) as u64; - } else { - let (res, overflow) = ($fn)(me[i], you[i]); - // SAFETY: i < isize::MAX and i is within bounds. - *ret_ptr.offset(i as _) = MaybeUninit::new(res); - carry = overflow as u64; + let mut ret = [0u64; $n_words]; + let ret_ptr = &mut ret as *mut [u64; $n_words] as *mut u64; + let mut carry = 0u64; + $crate::static_assertions::const_assert!(core::isize::MAX as usize / core::mem::size_of::() > $n_words); + + unroll! { + for i in 0..$n_words { + use core::ptr; + + if carry != 0 { + let (res1, overflow1) = ($fn)(me[i], you[i]); + let (res2, overflow2) = ($fn)(res1, carry); + + unsafe { + // SAFETY: `i` is within bounds and `i * size_of::() < isize::MAX` + *ret_ptr.offset(i as _) = res2 + } + carry = (overflow1 as u8 + overflow2 as u8) as u64; + } else { + let (res, overflow) = ($fn)(me[i], you[i]); + + unsafe { + // SAFETY: `i` is within bounds and `i * size_of::() < isize::MAX` + *ret_ptr.offset(i as _) = res } + + carry = overflow as u64; } } - - // SAFETY: MaybeUninit has the same representation as T, and - // `ret` has been fully initialized. - ($name($crate::core_::mem::transmute(ret)), carry > 0) } + + ($name(ret), carry > 0) }) } From f13eabfceb62bde4ab806295d48242efda5e60d8 Mon Sep 17 00:00:00 2001 From: "Demi M. Obenour" Date: Sat, 19 Oct 2019 17:58:44 -0400 Subject: [PATCH 3/3] Improve formatting and force CI retry --- ethbloom/src/lib.rs | 32 ++++++++++++++++---------------- keccak-hash/src/lib.rs | 2 +- parity-crypto/benches/bench.rs | 2 +- parity-crypto/src/aes.rs | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ethbloom/src/lib.rs b/ethbloom/src/lib.rs index 682a0d247..5cc5b8119 100644 --- a/ethbloom/src/lib.rs +++ b/ethbloom/src/lib.rs @@ -8,22 +8,22 @@ //! use std::str::FromStr; //! let bloom = Bloom::from_str( //! "00000000000000000000000000000000\ -//! 00000000100000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000002020000000000000000000000\ -//! 00000000000000000000000800000000\ -//! 10000000000000000000000000000000\ -//! 00000000000000000000001000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000\ -//! 00000000000000000000000000000000" -//! ).unwrap(); +//! 00000000100000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000002020000000000000000000000\ +//! 00000000000000000000000800000000\ +//! 10000000000000000000000000000000\ +//! 00000000000000000000001000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000\ +//! 00000000000000000000000000000000" +//! ).unwrap(); //! let address = hex!("ef2d6d194084c2de36e0dabfce45d046b37d1106"); //! let topic = hex!("02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc"); //! diff --git a/keccak-hash/src/lib.rs b/keccak-hash/src/lib.rs index 1b8926be1..77a3767e0 100644 --- a/keccak-hash/src/lib.rs +++ b/keccak-hash/src/lib.rs @@ -107,7 +107,7 @@ mod tests { keccak([0x41u8; 32]), H256([ 0x59, 0xca, 0xd5, 0x94, 0x86, 0x73, 0x62, 0x2c, - 0x1d, 0x64, 0xe2, 0x32, 0x24, 0x88, 0xbf, 0x01, + 0x1d, 0x64, 0xe2, 0x32, 0x24, 0x88, 0xbf, 0x01, 0x61, 0x9f, 0x7f, 0xf4, 0x57, 0x89, 0x74, 0x1b, 0x15, 0xa9, 0xf7, 0x82, 0xce, 0x92, 0x90, 0xa8 ]), diff --git a/parity-crypto/benches/bench.rs b/parity-crypto/benches/bench.rs index bdc9fd16d..6e739adb6 100644 --- a/parity-crypto/benches/bench.rs +++ b/parity-crypto/benches/bench.rs @@ -40,7 +40,7 @@ fn input_len(c: &mut Criterion) { let mut dest = vec![0; *size]; let k = [0; 16]; let iv = [0; 16]; - + b.iter(||{ parity_crypto::aes::encrypt_128_ctr(&k[..], &iv[..], &data[..], &mut dest[..]).unwrap(); // same as encrypt but add it just in case diff --git a/parity-crypto/src/aes.rs b/parity-crypto/src/aes.rs index dc62674d4..e13300524 100644 --- a/parity-crypto/src/aes.rs +++ b/parity-crypto/src/aes.rs @@ -66,14 +66,14 @@ impl AesCtr256 { )) } - /// In place encrypt a content without padding, the content length must be a multiple + /// In place encrypt a content without padding, the content length must be a multiple /// of the block size. pub fn encrypt(&mut self, content: &mut[u8]) -> Result<(), SymmError> { self.0.try_apply_keystream(content)?; Ok(()) } - /// In place decrypt a content without padding, the content length must be a multiple + /// In place decrypt a content without padding, the content length must be a multiple /// of the block size. pub fn decrypt(&mut self, content: &mut[u8]) -> Result<(), SymmError> { self.0.try_apply_keystream(content)?;