diff --git a/.clippy.toml b/.clippy.toml index 2c7730055..46ef272ea 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -7,5 +7,5 @@ disallowed-methods = [ { path = "jni::JNIEnv::call_static_method_unchecked", reason = "use helper method instead" }, { path = "jni::JNIEnv::new_object", reason = "use helper method instead" }, { path = "jni::JNIEnv::new_object_unchecked", reason = "use helper method instead" }, - ".." # keep any defaults -] \ No newline at end of file +] +allow-unwrap-in-tests = true diff --git a/rust/account-keys/src/lib.rs b/rust/account-keys/src/lib.rs index 0c8e494eb..9a516100a 100644 --- a/rust/account-keys/src/lib.rs +++ b/rust/account-keys/src/lib.rs @@ -3,6 +3,8 @@ // SPDX-License-Identifier: AGPL-3.0-only // +#![warn(clippy::unwrap_used)] + mod backup; mod error; mod hash; @@ -31,7 +33,7 @@ impl AccountEntropyPool { const ALPHABET: &'static [u8] = b"0123456789abcdefghijklmnopqrstuvwxyz"; pub fn generate(rng: &mut impl Rng) -> AccountEntropyPool { - let alphabet_dist = slice::Choose::new(Self::ALPHABET).unwrap(); + let alphabet_dist = slice::Choose::new(Self::ALPHABET).expect("non-empty"); let entropy_pool: [u8; Self::LENGTH] = std::array::from_fn(|_| *rng.sample(alphabet_dist)); Self { entropy_pool } } diff --git a/rust/core/src/address.rs b/rust/core/src/address.rs index 7c7f1e46d..85d2e08d7 100644 --- a/rust/core/src/address.rs +++ b/rust/core/src/address.rs @@ -757,7 +757,10 @@ impl fmt::Display for DeviceId { impl rand::distr::Distribution for rand::distr::StandardUniform { fn sample(&self, rng: &mut R) -> DeviceId { - DeviceId(NonZeroU8::new(rng.random_range(1..=MAX_VALID_DEVICE_ID)).unwrap()) + DeviceId( + NonZeroU8::new(rng.random_range(1..=MAX_VALID_DEVICE_ID)) + .expect("guaranteed by random_range"), + ) } } diff --git a/rust/core/src/lib.rs b/rust/core/src/lib.rs index 6a3602cb1..4b8aec413 100644 --- a/rust/core/src/lib.rs +++ b/rust/core/src/lib.rs @@ -3,6 +3,8 @@ // SPDX-License-Identifier: AGPL-3.0-only // +#![warn(clippy::unwrap_used)] + mod address; // Not exporting the members because they have overly-generic names. pub mod curve; diff --git a/rust/device-transfer/src/lib.rs b/rust/device-transfer/src/lib.rs index 099d17fe1..43734d457 100644 --- a/rust/device-transfer/src/lib.rs +++ b/rust/device-transfer/src/lib.rs @@ -6,7 +6,7 @@ //! Support logic for Signal's device-to-device transfer feature. #![deny(unsafe_code)] -#![warn(missing_docs)] +#![warn(missing_docs, clippy::unwrap_used)] use std::fmt; use std::time::{Duration, SystemTime}; diff --git a/rust/keytrans/src/lib.rs b/rust/keytrans/src/lib.rs index c4e90e21e..9eeaac0e6 100644 --- a/rust/keytrans/src/lib.rs +++ b/rust/keytrans/src/lib.rs @@ -3,7 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0-only // -#![cfg_attr(not(test), warn(clippy::unwrap_used))] +#![warn(clippy::unwrap_used)] mod commitments; mod guide; diff --git a/rust/media/src/lib.rs b/rust/media/src/lib.rs index 7d080cfe3..2499e48c7 100644 --- a/rust/media/src/lib.rs +++ b/rust/media/src/lib.rs @@ -3,4 +3,6 @@ // SPDX-License-Identifier: AGPL-3.0-only // +#![warn(clippy::unwrap_used)] + pub mod sanitize; diff --git a/rust/message-backup/src/lib.rs b/rust/message-backup/src/lib.rs index 0da196d0a..215b14452 100644 --- a/rust/message-backup/src/lib.rs +++ b/rust/message-backup/src/lib.rs @@ -7,6 +7,8 @@ //! //! Contains code to read and validate message backup files. +#![warn(clippy::unwrap_used)] + use std::time::Duration; use futures::AsyncRead; diff --git a/rust/message-backup/src/proto.rs b/rust/message-backup/src/proto.rs index 090ca3482..6eceab458 100644 --- a/rust/message-backup/src/proto.rs +++ b/rust/message-backup/src/proto.rs @@ -7,6 +7,7 @@ // self.special_fields.cached_size().set(my_size as u32) // which isn't obviously correct! But protobuf doesn't support messages that big anyway. #![expect(clippy::cast_possible_truncation)] +#![expect(clippy::unwrap_used)] include!(concat!(env!("OUT_DIR"), "/protos/mod.rs")); diff --git a/rust/poksho/src/sign.rs b/rust/poksho/src/sign.rs index 0c27a9a47..4a3fac12b 100644 --- a/rust/poksho/src/sign.rs +++ b/rust/poksho/src/sign.rs @@ -52,11 +52,7 @@ mod tests { use super::*; #[test] - #[expect( - clippy::cast_possible_truncation, - clippy::needless_range_loop, - clippy::unwrap_used - )] + #[expect(clippy::cast_possible_truncation, clippy::needless_range_loop)] fn test_signature() { let mut block64 = [0u8; 64]; let mut block32 = [0u8; 32]; diff --git a/rust/svrb/src/lib.rs b/rust/svrb/src/lib.rs index b61ffea89..e1f89f14a 100644 --- a/rust/svrb/src/lib.rs +++ b/rust/svrb/src/lib.rs @@ -2,6 +2,9 @@ // Copyright 2023 Signal Messenger, LLC. // SPDX-License-Identifier: AGPL-3.0-only // + +#![warn(clippy::unwrap_used)] + use std::collections::BTreeMap; use std::io::Write; use std::iter::repeat_with; diff --git a/rust/usernames/src/lib.rs b/rust/usernames/src/lib.rs index 0c49add4e..8131dbdc8 100644 --- a/rust/usernames/src/lib.rs +++ b/rust/usernames/src/lib.rs @@ -3,6 +3,8 @@ // SPDX-License-Identifier: AGPL-3.0-only // +#![warn(clippy::unwrap_used)] + pub use error::{ProofVerificationFailure, UsernameError}; pub use username::*; diff --git a/rust/usernames/src/username.rs b/rust/usernames/src/username.rs index 42c2003db..1e891e470 100644 --- a/rust/usernames/src/username.rs +++ b/rust/usernames/src/username.rs @@ -4,12 +4,13 @@ // use std::fmt::{Debug, Display, Formatter}; -use std::ops::{Add, Range, RangeInclusive}; +use std::ops::{Range, RangeInclusive}; use std::str::FromStr; use std::sync::LazyLock; use curve25519_dalek::ristretto::{CompressedRistretto, RistrettoPoint}; use curve25519_dalek::scalar::Scalar; +use curve25519_dalek::traits::MultiscalarMul; use poksho::args::{PointArgs, ScalarArgs}; use poksho::{PokshoError, Statement}; use rand::Rng; @@ -161,7 +162,6 @@ impl Username { ) -> Result, UsernameError> { validate_nickname(nickname, &limits)?; let candidates = random_discriminators(rng, &CANDIDATES_PER_RANGE, &DISCRIMINATOR_RANGES) - .unwrap() .iter() .map(|d| Self::format_parts(nickname, d)) .collect(); @@ -173,12 +173,10 @@ impl Username { } fn hash_from_scalars(scalars: &[Scalar]) -> RistrettoPoint { - BASE_POINTS - .iter() - .zip(scalars) - .map(|(point, scalar)| point * scalar) - .reduce(RistrettoPoint::add) - .unwrap() + // Will panic if the number of scalars doesn't match the number of base points. + // If we ever change the encoding to not use a fixed number of scalars, this will need to be + // updated. + RistrettoPoint::multiscalar_mul(scalars, BASE_POINTS.iter()) } fn make_scalar_args(scalars: &[Scalar]) -> ScalarArgs { @@ -330,14 +328,14 @@ fn random_discriminators( rng: &mut R, count_per_range: &[usize], ranges: &[Range], -) -> Result, UsernameError> { +) -> Vec { assert!(count_per_range.len() <= ranges.len(), "Not enough ranges"); let total_count: usize = count_per_range.iter().sum(); let mut results = Vec::with_capacity(total_count); for (n, range) in count_per_range.iter().zip(ranges) { results.extend(gen_range(rng, range, *n)); } - Ok(results) + results } fn gen_range<'a, R: Rng>( @@ -520,7 +518,7 @@ mod test { #[test] fn generate_discriminators() { let mut rng = rand::rng(); - let ds = random_discriminators(&mut rng, &[4, 3, 2, 1], &DISCRIMINATOR_RANGES).unwrap(); + let ds = random_discriminators(&mut rng, &[4, 3, 2, 1], &DISCRIMINATOR_RANGES); assert!(DISCRIMINATOR_RANGES[0].contains(&ds[0])); assert!(DISCRIMINATOR_RANGES[0].contains(&ds[1])); assert!(DISCRIMINATOR_RANGES[0].contains(&ds[2])); diff --git a/rust/zkcredential/src/endorsements.rs b/rust/zkcredential/src/endorsements.rs index a7cd30910..fb6b32a8b 100644 --- a/rust/zkcredential/src/endorsements.rs +++ b/rust/zkcredential/src/endorsements.rs @@ -374,7 +374,7 @@ impl EndorsementResponse { scalar_args.add("sk_prime", private_key.sk_prime); let proof = statement .prove(&scalar_args, &point_args, b"", &randomness) - .unwrap(); + .expect("valid proof"); EndorsementResponse { R, proof } } diff --git a/rust/zkcredential/src/issuance.rs b/rust/zkcredential/src/issuance.rs index 2b661cc06..6c8412b9e 100644 --- a/rust/zkcredential/src/issuance.rs +++ b/rust/zkcredential/src/issuance.rs @@ -252,7 +252,7 @@ impl<'a> IssuanceProofBuilder<'a> { self.authenticated_message, &sho.squeeze_and_ratchet_as_array::(), ) - .unwrap(); + .expect("valid proof"); IssuanceProof { poksho_proof, credential, diff --git a/rust/zkcredential/src/issuance/blind.rs b/rust/zkcredential/src/issuance/blind.rs index 6de92e2a2..044d5f4e0 100644 --- a/rust/zkcredential/src/issuance/blind.rs +++ b/rust/zkcredential/src/issuance/blind.rs @@ -491,7 +491,7 @@ impl BlindedIssuanceProofBuilder<'_> { self.inner.authenticated_message, &sho.squeeze_and_ratchet_as_array::(), ) - .unwrap(); + .expect("valid proof"); BlindedIssuanceProof { poksho_proof, credential, diff --git a/rust/zkcredential/src/lib.rs b/rust/zkcredential/src/lib.rs index 3316e8e77..8f1e36b26 100644 --- a/rust/zkcredential/src/lib.rs +++ b/rust/zkcredential/src/lib.rs @@ -36,7 +36,7 @@ //! [paper]: https://eprint.iacr.org/2019/1416 #![allow(non_snake_case)] -#![warn(missing_docs)] +#![warn(missing_docs, clippy::unwrap_used)] /// A zkcredential operation failed to verify. #[derive(Debug, thiserror::Error, displaydoc::Display)] diff --git a/rust/zkcredential/src/presentation.rs b/rust/zkcredential/src/presentation.rs index 8c331265a..aae9ba120 100644 --- a/rust/zkcredential/src/presentation.rs +++ b/rust/zkcredential/src/presentation.rs @@ -547,7 +547,7 @@ impl<'a> PresentationProofBuilder<'a> { self.core.authenticated_message, &sho.squeeze_and_ratchet_as_array::(), ) - .unwrap(); + .expect("valid proof"); PresentationProof { commitments, diff --git a/rust/zkgroup/src/api/profiles/profile_key_version.rs b/rust/zkgroup/src/api/profiles/profile_key_version.rs index 94648bc98..cb37b868b 100644 --- a/rust/zkgroup/src/api/profiles/profile_key_version.rs +++ b/rust/zkgroup/src/api/profiles/profile_key_version.rs @@ -37,7 +37,7 @@ impl Serialize for ProfileKeyVersion { where S: Serializer, { - let mut seq = serializer.serialize_tuple(self.ascii.len()).unwrap(); + let mut seq = serializer.serialize_tuple(self.ascii.len())?; for b in self.ascii.iter() { seq.serialize_element(b)?; } diff --git a/rust/zkgroup/src/crypto/credentials.rs b/rust/zkgroup/src/crypto/credentials.rs index 012813502..d6c7a6f6a 100644 --- a/rust/zkgroup/src/crypto/credentials.rs +++ b/rust/zkgroup/src/crypto/credentials.rs @@ -27,8 +27,9 @@ use crate::{ NUM_AUTH_CRED_ATTRIBUTES, NUM_PROFILE_KEY_CRED_ATTRIBUTES, NUM_RECEIPT_CRED_ATTRIBUTES, }; -static SYSTEM_PARAMS: LazyLock = - LazyLock::new(|| crate::deserialize::(SystemParams::SYSTEM_HARDCODED).unwrap()); +static SYSTEM_PARAMS: LazyLock = LazyLock::new(|| { + crate::deserialize(SystemParams::SYSTEM_HARDCODED).expect("valid hardcoded params") +}); const NUM_SUPPORTED_ATTRS: usize = 6; #[derive(Copy, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] diff --git a/rust/zkgroup/src/crypto/profile_key_commitment.rs b/rust/zkgroup/src/crypto/profile_key_commitment.rs index 5234b4469..fd71069b7 100644 --- a/rust/zkgroup/src/crypto/profile_key_commitment.rs +++ b/rust/zkgroup/src/crypto/profile_key_commitment.rs @@ -17,8 +17,9 @@ use crate::common::sho::*; use crate::common::simple_types::*; use crate::crypto::profile_key_struct; -static SYSTEM_PARAMS: LazyLock = - LazyLock::new(|| crate::deserialize::(&SystemParams::SYSTEM_HARDCODED).unwrap()); +static SYSTEM_PARAMS: LazyLock = LazyLock::new(|| { + crate::deserialize(&SystemParams::SYSTEM_HARDCODED).expect("valid hardcoded params") +}); #[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, PartialDefault)] pub struct SystemParams { diff --git a/rust/zkgroup/src/crypto/profile_key_encryption.rs b/rust/zkgroup/src/crypto/profile_key_encryption.rs index 847ffd475..52b075008 100644 --- a/rust/zkgroup/src/crypto/profile_key_encryption.rs +++ b/rust/zkgroup/src/crypto/profile_key_encryption.rs @@ -18,8 +18,9 @@ use crate::common::sho::*; use crate::common::simple_types::*; use crate::crypto::profile_key_struct; -static SYSTEM_PARAMS: LazyLock = - LazyLock::new(|| crate::deserialize::(&SystemParams::SYSTEM_HARDCODED).unwrap()); +static SYSTEM_PARAMS: LazyLock = LazyLock::new(|| { + crate::deserialize(&SystemParams::SYSTEM_HARDCODED).expect("valid hardcoded params") +}); #[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, PartialDefault)] pub struct SystemParams { diff --git a/rust/zkgroup/src/crypto/proofs.rs b/rust/zkgroup/src/crypto/proofs.rs index 6e911b68c..e7051e6b3 100644 --- a/rust/zkgroup/src/crypto/proofs.rs +++ b/rust/zkgroup/src/crypto/proofs.rs @@ -140,7 +140,7 @@ impl ProfileKeyCredentialRequestProof { &[], &sho.squeeze_as_array::(), ) - .unwrap(); + .expect("valid proof"); ProfileKeyCredentialRequestProof { poksho_proof } } @@ -262,7 +262,7 @@ impl ExpiringProfileKeyCredentialIssuanceProof { &[], &sho.squeeze_as_array::(), ) - .unwrap(); + .expect("valid proof"); ExpiringProfileKeyCredentialIssuanceProof { poksho_proof } } @@ -390,7 +390,7 @@ impl ReceiptCredentialIssuanceProof { &[], &sho.squeeze_as_array::(), ) - .unwrap(); + .expect("valid proof"); Self { poksho_proof } } @@ -564,7 +564,7 @@ impl ExpiringProfileKeyCredentialPresentationProof { &[], &sho.squeeze_as_array::(), ) - .unwrap(); + .expect("valid proof"); ExpiringProfileKeyCredentialPresentationProof { C_y1, @@ -723,7 +723,7 @@ impl ReceiptCredentialPresentationProof { &[], &sho.squeeze_as_array::(), ) - .unwrap(); + .expect("valid proof"); Self { C_x0, diff --git a/rust/zkgroup/src/crypto/uid_encryption.rs b/rust/zkgroup/src/crypto/uid_encryption.rs index cd40a18b8..db604d074 100644 --- a/rust/zkgroup/src/crypto/uid_encryption.rs +++ b/rust/zkgroup/src/crypto/uid_encryption.rs @@ -17,8 +17,9 @@ use crate::common::errors::*; use crate::common::sho::*; use crate::crypto::uid_struct; -static SYSTEM_PARAMS: LazyLock = - LazyLock::new(|| crate::deserialize::(&SystemParams::SYSTEM_HARDCODED).unwrap()); +static SYSTEM_PARAMS: LazyLock = LazyLock::new(|| { + crate::deserialize(&SystemParams::SYSTEM_HARDCODED).expect("valid hardcoded params") +}); #[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, PartialDefault)] pub struct SystemParams { diff --git a/rust/zkgroup/src/lib.rs b/rust/zkgroup/src/lib.rs index 6c5f5c72a..5b120d511 100644 --- a/rust/zkgroup/src/lib.rs +++ b/rust/zkgroup/src/lib.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0-only // +#![warn(clippy::unwrap_used)] #![deny(unsafe_code)] pub mod api;