From 92f0f1fa2c11d12d407d1f2153433c2c4b1cfb4d Mon Sep 17 00:00:00 2001 From: Hinton Date: Tue, 16 Sep 2025 11:25:30 +0200 Subject: [PATCH 1/9] Fix remaining error lints and tweak rule --- .../bitwarden-core/src/auth/access_token.rs | 4 +- crates/bitwarden-core/src/auth/jwt_token.rs | 4 +- .../src/enc_string/symmetric.rs | 4 +- crates/bitwarden-crypto/src/error.rs | 10 ++--- .../bitwarden-crypto/src/keys/master_key.rs | 2 +- crates/bitwarden-crypto/src/rsa.rs | 6 +-- crates/bitwarden-crypto/src/store/context.rs | 6 +-- crates/bitwarden-encoding/src/b64.rs | 12 +++--- crates/bitwarden-encoding/src/b64url.rs | 12 +++--- crates/bitwarden-encoding/src/lib.rs | 4 +- crates/bitwarden-exporters/src/cxf/login.rs | 4 +- crates/bitwarden-fido/src/authenticator.rs | 16 ++++---- crates/bitwarden-fido/src/lib.rs | 37 ++++++++++--------- crates/bitwarden-fido/src/types.rs | 14 +++---- crates/bitwarden-state/src/sdk_managed/mod.rs | 2 +- crates/bitwarden-uniffi/src/error.rs | 6 +-- crates/bitwarden-uniffi/src/lib.rs | 2 +- crates/bitwarden-vault/src/folder/create.rs | 2 +- crates/bitwarden-vault/src/folder/edit.rs | 2 +- crates/bitwarden-vault/src/folder/get_list.rs | 2 +- support/lints/.cargo/config.toml | 6 +++ support/lints/error_enum/src/lib.rs | 14 ++++++- support/lints/error_suffix/src/lib.rs | 1 + 23 files changed, 97 insertions(+), 75 deletions(-) create mode 100644 support/lints/.cargo/config.toml diff --git a/crates/bitwarden-core/src/auth/access_token.rs b/crates/bitwarden-core/src/auth/access_token.rs index 234fafa9c..d2b2f59a7 100644 --- a/crates/bitwarden-core/src/auth/access_token.rs +++ b/crates/bitwarden-core/src/auth/access_token.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, str::FromStr}; use bitwarden_crypto::{derive_shareable_key, SymmetricCryptoKey}; -use bitwarden_encoding::{NotB64Encoded, B64}; +use bitwarden_encoding::{NotB64EncodedError, B64}; use thiserror::Error; use uuid::Uuid; use zeroize::Zeroizing; @@ -19,7 +19,7 @@ pub enum AccessTokenInvalidError { InvalidUuid, #[error("Error decoding base64: {0}")] - InvalidBase64(#[from] NotB64Encoded), + InvalidBase64(#[from] NotB64EncodedError), #[error("Invalid base64 length: expected {expected}, got {got}")] InvalidBase64Length { expected: usize, got: usize }, diff --git a/crates/bitwarden-core/src/auth/jwt_token.rs b/crates/bitwarden-core/src/auth/jwt_token.rs index 953734c5e..803f1942a 100644 --- a/crates/bitwarden-core/src/auth/jwt_token.rs +++ b/crates/bitwarden-core/src/auth/jwt_token.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use bitwarden_encoding::{B64Url, NotB64UrlEncoded}; +use bitwarden_encoding::{B64Url, NotB64UrlEncodedError}; use thiserror::Error; /// A Bitwarden secrets manager JWT Token. @@ -31,7 +31,7 @@ pub enum JwtTokenParseError { #[error("JWT token parse error: {0}")] Parse(#[from] serde_json::Error), #[error("JWT token decode error: {0}")] - Decode(#[from] NotB64UrlEncoded), + Decode(#[from] NotB64UrlEncodedError), #[error("JWT token has an invalid number of parts")] InvalidParts, diff --git a/crates/bitwarden-crypto/src/enc_string/symmetric.rs b/crates/bitwarden-crypto/src/enc_string/symmetric.rs index 3c3f9e003..950c5d868 100644 --- a/crates/bitwarden-crypto/src/enc_string/symmetric.rs +++ b/crates/bitwarden-crypto/src/enc_string/symmetric.rs @@ -6,7 +6,7 @@ use serde::Deserialize; use super::{check_length, from_b64, from_b64_vec, split_enc_string}; use crate::{ - error::{CryptoError, EncStringParseError, Result, UnsupportedOperation}, + error::{CryptoError, EncStringParseError, Result, UnsupportedOperationError}, Aes256CbcHmacKey, ContentFormat, KeyDecryptable, KeyEncryptable, KeyEncryptableWithContentType, SymmetricCryptoKey, Utf8Bytes, XChaCha20Poly1305Key, }; @@ -294,7 +294,7 @@ impl KeyEncryptableWithContentType for &[u8] { EncString::encrypt_xchacha20_poly1305(self, inner_key, content_format) } SymmetricCryptoKey::Aes256CbcKey(_) => Err(CryptoError::OperationNotSupported( - UnsupportedOperation::EncryptionNotImplementedForKey, + UnsupportedOperationError::EncryptionNotImplementedForKey, )), } } diff --git a/crates/bitwarden-crypto/src/error.rs b/crates/bitwarden-crypto/src/error.rs index 34092327a..c59bc1f8a 100644 --- a/crates/bitwarden-crypto/src/error.rs +++ b/crates/bitwarden-crypto/src/error.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use bitwarden_encoding::NotB64Encoded; +use bitwarden_encoding::NotB64EncodedError; use bitwarden_error::bitwarden_error; use thiserror::Error; use uuid::Uuid; @@ -45,13 +45,13 @@ pub enum CryptoError { Fingerprint(#[from] FingerprintError), #[error("Argon2 error, {0}")] - ArgonError(#[from] argon2::Error), + Argon(#[from] argon2::Error), #[error("Number is zero")] ZeroNumber, #[error("Unsupported operation, {0}")] - OperationNotSupported(UnsupportedOperation), + OperationNotSupported(UnsupportedOperationError), #[error("Key algorithm does not match encrypted data type")] WrongKeyType, @@ -73,7 +73,7 @@ pub enum CryptoError { } #[derive(Debug, Error)] -pub enum UnsupportedOperation { +pub enum UnsupportedOperationError { #[error("Encryption is not implemented for key")] EncryptionNotImplementedForKey, } @@ -87,7 +87,7 @@ pub enum EncStringParseError { #[error("Invalid asymmetric type, got type {enc_type} with {parts} parts")] InvalidTypeAsymm { enc_type: String, parts: usize }, #[error("Error decoding base64: {0}")] - InvalidBase64(#[from] NotB64Encoded), + InvalidBase64(#[from] NotB64EncodedError), #[error("Invalid length: expected {expected}, got {got}")] InvalidLength { expected: usize, got: usize }, #[error("Invalid encoding {0}")] diff --git a/crates/bitwarden-crypto/src/keys/master_key.rs b/crates/bitwarden-crypto/src/keys/master_key.rs index 991868e22..74fc0d90d 100644 --- a/crates/bitwarden-crypto/src/keys/master_key.rs +++ b/crates/bitwarden-crypto/src/keys/master_key.rs @@ -155,7 +155,7 @@ pub(super) fn decrypt_user_key( } EncString::Cose_Encrypt0_B64 { .. } => { return Err(CryptoError::OperationNotSupported( - crate::error::UnsupportedOperation::EncryptionNotImplementedForKey, + crate::error::UnsupportedOperationError::EncryptionNotImplementedForKey, )); } }; diff --git a/crates/bitwarden-crypto/src/rsa.rs b/crates/bitwarden-crypto/src/rsa.rs index d0b2f5806..e7a43f06d 100644 --- a/crates/bitwarden-crypto/src/rsa.rs +++ b/crates/bitwarden-crypto/src/rsa.rs @@ -6,7 +6,7 @@ use rsa::{ use sha1::Sha1; use crate::{ - error::{Result, RsaError, UnsupportedOperation}, + error::{Result, RsaError, UnsupportedOperationError}, CryptoError, EncString, SymmetricCryptoKey, }; @@ -41,10 +41,10 @@ pub(crate) fn make_key_pair(key: &SymmetricCryptoKey) -> Result { EncString::encrypt_aes256_hmac(pkcs.as_bytes(), key) } SymmetricCryptoKey::XChaCha20Poly1305Key(_) => Err(CryptoError::OperationNotSupported( - UnsupportedOperation::EncryptionNotImplementedForKey, + UnsupportedOperationError::EncryptionNotImplementedForKey, )), SymmetricCryptoKey::Aes256CbcKey(_) => Err(CryptoError::OperationNotSupported( - UnsupportedOperation::EncryptionNotImplementedForKey, + UnsupportedOperationError::EncryptionNotImplementedForKey, )), }?; diff --git a/crates/bitwarden-crypto/src/store/context.rs b/crates/bitwarden-crypto/src/store/context.rs index 2e11e809a..a40aa1059 100644 --- a/crates/bitwarden-crypto/src/store/context.rs +++ b/crates/bitwarden-crypto/src/store/context.rs @@ -8,7 +8,7 @@ use zeroize::Zeroizing; use super::KeyStoreInner; use crate::{ - derive_shareable_key, error::UnsupportedOperation, signing, store::backend::StoreBackend, + derive_shareable_key, error::UnsupportedOperationError, signing, store::backend::StoreBackend, AsymmetricCryptoKey, BitwardenLegacyKeyBytes, ContentFormat, CryptoError, EncString, KeyId, KeyIds, PublicKeyEncryptionAlgorithm, Result, RotatedUserKeys, Signature, SignatureAlgorithm, SignedObject, SignedPublicKey, SignedPublicKeyMessage, SigningKey, SymmetricCryptoKey, @@ -236,7 +236,7 @@ impl KeyStoreContext<'_, Ids> { ) } _ => Err(CryptoError::OperationNotSupported( - UnsupportedOperation::EncryptionNotImplementedForKey, + UnsupportedOperationError::EncryptionNotImplementedForKey, )), } } @@ -503,7 +503,7 @@ impl KeyStoreContext<'_, Ids> { let key = self.get_symmetric_key(key)?; match key { SymmetricCryptoKey::Aes256CbcKey(_) => Err(CryptoError::OperationNotSupported( - UnsupportedOperation::EncryptionNotImplementedForKey, + UnsupportedOperationError::EncryptionNotImplementedForKey, )), SymmetricCryptoKey::Aes256CbcHmacKey(key) => EncString::encrypt_aes256_hmac(data, key), SymmetricCryptoKey::XChaCha20Poly1305Key(key) => { diff --git a/crates/bitwarden-encoding/src/b64.rs b/crates/bitwarden-encoding/src/b64.rs index 322f820e5..4110bcf59 100644 --- a/crates/bitwarden-encoding/src/b64.rs +++ b/crates/bitwarden-encoding/src/b64.rs @@ -86,7 +86,7 @@ impl std::fmt::Display for B64 { /// An error returned when a string is not base64 decodable. #[derive(Debug, Error)] #[error("Data isn't base64 encoded")] -pub struct NotB64Encoded; +pub struct NotB64EncodedError; const BASE64_PERMISSIVE: data_encoding::Encoding = data_encoding_macro::new_encoding! { symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", @@ -96,7 +96,7 @@ const BASE64_PERMISSIVE: data_encoding::Encoding = data_encoding_macro::new_enco const BASE64_PADDING: &str = "="; impl TryFrom for B64 { - type Error = NotB64Encoded; + type Error = NotB64EncodedError; fn try_from(value: String) -> Result { Self::try_from(value.as_str()) @@ -104,19 +104,19 @@ impl TryFrom for B64 { } impl TryFrom<&str> for B64 { - type Error = NotB64Encoded; + type Error = NotB64EncodedError; fn try_from(value: &str) -> Result { let sane_string = value.trim_end_matches(BASE64_PADDING); BASE64_PERMISSIVE .decode(sane_string.as_bytes()) .map(Self) - .map_err(|_| NotB64Encoded) + .map_err(|_| NotB64EncodedError) } } impl FromStr for B64 { - type Err = NotB64Encoded; + type Err = NotB64EncodedError; fn from_str(s: &str) -> Result { Self::try_from(s) @@ -224,7 +224,7 @@ mod tests { #[test] fn test_not_b64_encoded_error_display() { - let error = NotB64Encoded; + let error = NotB64EncodedError; assert_eq!(error.to_string(), "Data isn't base64 encoded"); } diff --git a/crates/bitwarden-encoding/src/b64url.rs b/crates/bitwarden-encoding/src/b64url.rs index e9981f417..ea213b757 100644 --- a/crates/bitwarden-encoding/src/b64url.rs +++ b/crates/bitwarden-encoding/src/b64url.rs @@ -61,7 +61,7 @@ impl std::fmt::Display for B64Url { /// An error returned when a string is not base64 decodable. #[derive(Debug, Error)] #[error("Data isn't base64url encoded")] -pub struct NotB64UrlEncoded; +pub struct NotB64UrlEncodedError; const BASE64URL_PERMISSIVE: data_encoding::Encoding = data_encoding_macro::new_encoding! { symbols: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", @@ -71,7 +71,7 @@ const BASE64URL_PERMISSIVE: data_encoding::Encoding = data_encoding_macro::new_e const BASE64URL_PADDING: &str = "="; impl TryFrom for B64Url { - type Error = NotB64UrlEncoded; + type Error = NotB64UrlEncodedError; fn try_from(value: String) -> Result { Self::try_from(value.as_str()) @@ -79,19 +79,19 @@ impl TryFrom for B64Url { } impl TryFrom<&str> for B64Url { - type Error = NotB64UrlEncoded; + type Error = NotB64UrlEncodedError; fn try_from(value: &str) -> Result { let sane_string = value.trim_end_matches(BASE64URL_PADDING); BASE64URL_PERMISSIVE .decode(sane_string.as_bytes()) .map(Self) - .map_err(|_| NotB64UrlEncoded) + .map_err(|_| NotB64UrlEncodedError) } } impl FromStr for B64Url { - type Err = NotB64UrlEncoded; + type Err = NotB64UrlEncodedError; fn from_str(s: &str) -> Result { Self::try_from(s) @@ -198,7 +198,7 @@ mod tests { #[test] fn test_not_b64url_encoded_error_display() { - let error = NotB64UrlEncoded; + let error = NotB64UrlEncodedError; assert_eq!(error.to_string(), "Data isn't base64url encoded"); } diff --git a/crates/bitwarden-encoding/src/lib.rs b/crates/bitwarden-encoding/src/lib.rs index 54bfcc669..a589bbc50 100644 --- a/crates/bitwarden-encoding/src/lib.rs +++ b/crates/bitwarden-encoding/src/lib.rs @@ -4,8 +4,8 @@ mod b64; mod b64url; mod serde; -pub use b64::{NotB64Encoded, B64}; -pub use b64url::{B64Url, NotB64UrlEncoded}; +pub use b64::{NotB64EncodedError, B64}; +pub use b64url::{B64Url, NotB64UrlEncodedError}; pub use serde::FromStrVisitor; #[cfg(feature = "uniffi")] diff --git a/crates/bitwarden-exporters/src/cxf/login.rs b/crates/bitwarden-exporters/src/cxf/login.rs index a722527b3..c41746713 100644 --- a/crates/bitwarden-exporters/src/cxf/login.rs +++ b/crates/bitwarden-exporters/src/cxf/login.rs @@ -4,7 +4,7 @@ //! [PasskeyCredential]. use bitwarden_core::MissingFieldError; -use bitwarden_fido::{string_to_guid_bytes, InvalidGuid}; +use bitwarden_fido::{string_to_guid_bytes, InvalidGuidError}; use bitwarden_vault::{FieldType, Totp, TotpAlgorithm}; use chrono::{DateTime, Utc}; use credential_exchange_format::{ @@ -187,7 +187,7 @@ pub enum PasskeyError { #[error("Counter is not zero")] CounterNotZero, #[error(transparent)] - InvalidGuid(InvalidGuid), + InvalidGuid(InvalidGuidError), #[error(transparent)] MissingField(MissingFieldError), #[error("Data isn't base64url encoded")] diff --git a/crates/bitwarden-fido/src/authenticator.rs b/crates/bitwarden-fido/src/authenticator.rs index 82f4371e2..c870f6cf2 100644 --- a/crates/bitwarden-fido/src/authenticator.rs +++ b/crates/bitwarden-fido/src/authenticator.rs @@ -16,11 +16,11 @@ use thiserror::Error; use super::{ try_from_credential_new_view, types::*, CheckUserOptions, CipherViewContainer, - Fido2CredentialStore, Fido2UserInterface, SelectedCredential, UnknownEnum, AAGUID, + Fido2CredentialStore, Fido2UserInterface, SelectedCredential, UnknownEnumError, AAGUID, }; use crate::{ fill_with_credential, string_to_guid_bytes, try_from_credential_full, Fido2CallbackError, - FillCredentialError, InvalidGuid, + FillCredentialError, InvalidGuidError, }; #[derive(Debug, Error)] @@ -40,7 +40,7 @@ pub enum MakeCredentialError { #[error(transparent)] PublicKeyCredentialParameters(#[from] PublicKeyCredentialParametersError), #[error(transparent)] - UnknownEnum(#[from] UnknownEnum), + UnknownEnum(#[from] UnknownEnumError), #[error(transparent)] Serde(#[from] serde_json::Error), #[error("Missing attested_credential_data")] @@ -53,13 +53,13 @@ pub enum MakeCredentialError { #[derive(Debug, Error)] pub enum GetAssertionError { #[error(transparent)] - UnknownEnum(#[from] UnknownEnum), + UnknownEnum(#[from] UnknownEnumError), #[error(transparent)] Serde(#[from] serde_json::Error), #[error(transparent)] GetSelectedCredential(#[from] GetSelectedCredentialError), #[error(transparent)] - InvalidGuid(#[from] InvalidGuid), + InvalidGuid(#[from] InvalidGuidError), #[error("missing user")] MissingUser, #[error("get_assertion error: {0}")] @@ -72,7 +72,7 @@ pub enum SilentlyDiscoverCredentialsError { #[error(transparent)] Cipher(#[from] CipherError), #[error(transparent)] - InvalidGuid(#[from] InvalidGuid), + InvalidGuid(#[from] InvalidGuidError), #[error(transparent)] Fido2Callback(#[from] Fido2CallbackError), #[error(transparent)] @@ -85,7 +85,7 @@ pub enum CredentialsForAutofillError { #[error(transparent)] Cipher(#[from] CipherError), #[error(transparent)] - InvalidGuid(#[from] InvalidGuid), + InvalidGuid(#[from] InvalidGuidError), #[error(transparent)] Fido2Callback(#[from] Fido2CallbackError), #[error(transparent)] @@ -511,7 +511,7 @@ impl passkey::authenticator::CredentialStore for CredentialStoreImpl<'_> { #[error("Client User Id has not been set")] MissingUserId, #[error(transparent)] - InvalidGuid(#[from] InvalidGuid), + InvalidGuid(#[from] InvalidGuidError), #[error("Credential ID does not match selected credential")] CredentialIdMismatch, #[error(transparent)] diff --git a/crates/bitwarden-fido/src/lib.rs b/crates/bitwarden-fido/src/lib.rs index 1f8113eb2..04df63207 100644 --- a/crates/bitwarden-fido/src/lib.rs +++ b/crates/bitwarden-fido/src/lib.rs @@ -2,7 +2,7 @@ use bitwarden_core::key_management::KeyIds; use bitwarden_crypto::KeyStoreContext; -use bitwarden_encoding::{B64Url, NotB64UrlEncoded}; +use bitwarden_encoding::{B64Url, NotB64UrlEncodedError}; use bitwarden_vault::{ CipherError, CipherView, Fido2CredentialFullView, Fido2CredentialNewView, Fido2CredentialView, }; @@ -78,13 +78,13 @@ impl CipherViewContainer { #[derive(Debug, Error)] pub enum Fido2Error { #[error(transparent)] - Decode(#[from] NotB64UrlEncoded), + Decode(#[from] NotB64UrlEncodedError), #[error(transparent)] - UnknownEnum(#[from] UnknownEnum), + UnknownEnum(#[from] UnknownEnumError), #[error(transparent)] - InvalidGuid(#[from] InvalidGuid), + InvalidGuid(#[from] InvalidGuidError), #[error(transparent)] PrivateKeyFromSecretKey(#[from] PrivateKeyFromSecretKeyError), @@ -133,9 +133,9 @@ fn try_from_credential_full_view(value: Fido2CredentialFullView) -> Result Result { +) -> Result { let cred_id: Vec = vec![0; 16]; let user_handle = B64Url::from(user.id.to_vec()).to_string(); @@ -222,12 +222,12 @@ pub(crate) fn try_from_credential_full( #[allow(missing_docs)] #[derive(Debug, Error)] #[error("Input should be a 16 byte array")] -pub struct InvalidInputLength; +pub struct InvalidInputLengthError; #[allow(missing_docs)] -pub fn guid_bytes_to_string(source: &[u8]) -> Result { +pub fn guid_bytes_to_string(source: &[u8]) -> Result { if source.len() != 16 { - return Err(InvalidInputLength); + return Err(InvalidInputLengthError); } Ok(uuid::Uuid::from_bytes(source.try_into().expect("Invalid length")).to_string()) } @@ -235,16 +235,17 @@ pub fn guid_bytes_to_string(source: &[u8]) -> Result #[allow(missing_docs)] #[derive(Debug, Error)] #[error("Invalid GUID")] -pub struct InvalidGuid; +pub struct InvalidGuidError; #[allow(missing_docs)] -pub fn string_to_guid_bytes(source: &str) -> Result, InvalidGuid> { +pub fn string_to_guid_bytes(source: &str) -> Result, InvalidGuidError> { if source.starts_with("b64.") { - let bytes = B64Url::try_from(source.trim_start_matches("b64.")).map_err(|_| InvalidGuid)?; + let bytes = + B64Url::try_from(source.trim_start_matches("b64.")).map_err(|_| InvalidGuidError)?; Ok(bytes.as_bytes().to_vec()) } else { let Ok(uuid) = uuid::Uuid::try_parse(source) else { - return Err(InvalidGuid); + return Err(InvalidGuidError); }; Ok(uuid.as_bytes().to_vec()) } @@ -253,12 +254,14 @@ pub fn string_to_guid_bytes(source: &str) -> Result, InvalidGuid> { #[allow(missing_docs)] #[derive(Debug, Error)] #[error("Unknown enum value")] -pub struct UnknownEnum; +pub struct UnknownEnumError; // Some utilities to convert back and forth between enums and strings -fn get_enum_from_string_name(s: &str) -> Result { +fn get_enum_from_string_name( + s: &str, +) -> Result { let serialized = format!(r#""{s}""#); - let deserialized: T = serde_json::from_str(&serialized).map_err(|_| UnknownEnum)?; + let deserialized: T = serde_json::from_str(&serialized).map_err(|_| UnknownEnumError)?; Ok(deserialized) } diff --git a/crates/bitwarden-fido/src/types.rs b/crates/bitwarden-fido/src/types.rs index 7cf366b36..da74a0450 100644 --- a/crates/bitwarden-fido/src/types.rs +++ b/crates/bitwarden-fido/src/types.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use bitwarden_core::key_management::KeyIds; use bitwarden_crypto::{CryptoError, KeyStoreContext}; -use bitwarden_encoding::{B64Url, NotB64UrlEncoded}; +use bitwarden_encoding::{B64Url, NotB64UrlEncodedError}; use bitwarden_vault::{CipherListView, CipherListViewType, CipherView, LoginListView}; use passkey::types::webauthn::UserVerificationRequirement; use reqwest::Url; @@ -10,8 +10,8 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use super::{ - get_enum_from_string_name, string_to_guid_bytes, InvalidGuid, SelectedCredential, UnknownEnum, - Verification, + get_enum_from_string_name, string_to_guid_bytes, InvalidGuidError, SelectedCredential, + UnknownEnumError, Verification, }; #[allow(missing_docs)] @@ -59,13 +59,13 @@ pub enum Fido2CredentialAutofillViewError { MissingCipherId, #[error(transparent)] - InvalidGuid(#[from] InvalidGuid), + InvalidGuid(#[from] InvalidGuidError), #[error(transparent)] Crypto(#[from] CryptoError), #[error(transparent)] - Base64Decode(#[from] NotB64UrlEncoded), + Base64Decode(#[from] NotB64UrlEncodedError), } impl Fido2CredentialAutofillView { @@ -179,7 +179,7 @@ pub enum PublicKeyCredentialParametersError { InvalidAlgorithm, #[error("Unknown type")] - UnknownEnum(#[from] UnknownEnum), + UnknownEnum(#[from] UnknownEnumError), } impl TryFrom @@ -207,7 +207,7 @@ pub struct PublicKeyCredentialDescriptor { impl TryFrom for passkey::types::webauthn::PublicKeyCredentialDescriptor { - type Error = UnknownEnum; + type Error = UnknownEnumError; fn try_from(value: PublicKeyCredentialDescriptor) -> Result { Ok(Self { diff --git a/crates/bitwarden-state/src/sdk_managed/mod.rs b/crates/bitwarden-state/src/sdk_managed/mod.rs index a5e6b9ddf..2ed9aa6c9 100644 --- a/crates/bitwarden-state/src/sdk_managed/mod.rs +++ b/crates/bitwarden-state/src/sdk_managed/mod.rs @@ -34,7 +34,7 @@ pub enum DatabaseError { Serialization(#[from] serde_json::Error), #[error("JS error: {0}")] - JSError(String), + JS(String), #[error(transparent)] Internal(#[from] InternalError), diff --git a/crates/bitwarden-uniffi/src/error.rs b/crates/bitwarden-uniffi/src/error.rs index b431e6173..edf50c31a 100644 --- a/crates/bitwarden-uniffi/src/error.rs +++ b/crates/bitwarden-uniffi/src/error.rs @@ -9,7 +9,7 @@ use bitwarden_generators::{PassphraseError, PasswordError, UsernameError}; #[uniffi(flat_error)] pub enum BitwardenError { E(Error), - ConversionError(Box), + Conversion(Box), } impl From for BitwardenError { @@ -22,7 +22,7 @@ impl Display for BitwardenError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { Self::E(e) => Display::fmt(e, f), - Self::ConversionError(e) => Display::fmt(e, f), + Self::Conversion(e) => Display::fmt(e, f), } } } @@ -31,7 +31,7 @@ impl std::error::Error for BitwardenError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { BitwardenError::E(e) => Some(e), - BitwardenError::ConversionError(e) => Some(e.as_ref()), + BitwardenError::Conversion(e) => Some(e.as_ref()), } } } diff --git a/crates/bitwarden-uniffi/src/lib.rs b/crates/bitwarden-uniffi/src/lib.rs index 92e61c759..ade28674c 100644 --- a/crates/bitwarden-uniffi/src/lib.rs +++ b/crates/bitwarden-uniffi/src/lib.rs @@ -129,6 +129,6 @@ fn init_logger() { /// Check [`bitwarden_uniffi_error`] for more details fn setup_error_converter() { bitwarden_uniffi_error::set_error_to_uniffi_error(|e| { - crate::error::BitwardenError::ConversionError(e).into() + crate::error::BitwardenError::Conversion(e).into() }); } diff --git a/crates/bitwarden-vault/src/folder/create.rs b/crates/bitwarden-vault/src/folder/create.rs index 3eef975f0..cbd1d3f72 100644 --- a/crates/bitwarden-vault/src/folder/create.rs +++ b/crates/bitwarden-vault/src/folder/create.rs @@ -58,7 +58,7 @@ pub enum CreateFolderError { #[error(transparent)] MissingField(#[from] MissingFieldError), #[error(transparent)] - RepositoryError(#[from] RepositoryError), + Repository(#[from] RepositoryError), } pub(super) async fn create_folder + ?Sized>( diff --git a/crates/bitwarden-vault/src/folder/edit.rs b/crates/bitwarden-vault/src/folder/edit.rs index 361b273fb..eccaf86ff 100644 --- a/crates/bitwarden-vault/src/folder/edit.rs +++ b/crates/bitwarden-vault/src/folder/edit.rs @@ -24,7 +24,7 @@ pub enum EditFolderError { #[error(transparent)] MissingField(#[from] MissingFieldError), #[error(transparent)] - RepositoryError(#[from] RepositoryError), + Repository(#[from] RepositoryError), #[error(transparent)] Uuid(#[from] uuid::Error), } diff --git a/crates/bitwarden-vault/src/folder/get_list.rs b/crates/bitwarden-vault/src/folder/get_list.rs index 65ac6b2fa..385d6065a 100644 --- a/crates/bitwarden-vault/src/folder/get_list.rs +++ b/crates/bitwarden-vault/src/folder/get_list.rs @@ -15,7 +15,7 @@ pub enum GetFolderError { #[error(transparent)] Crypto(#[from] CryptoError), #[error(transparent)] - RepositoryError(#[from] RepositoryError), + Repository(#[from] RepositoryError), } pub(super) async fn get_folder( diff --git a/support/lints/.cargo/config.toml b/support/lints/.cargo/config.toml new file mode 100644 index 000000000..226eca535 --- /dev/null +++ b/support/lints/.cargo/config.toml @@ -0,0 +1,6 @@ +[target.'cfg(all())'] +rustflags = ["-C", "linker=dylint-link"] + +# For Rust versions 1.74.0 and onward, the following alternative can be used +# (see https://github.com/rust-lang/cargo/pull/12535): +# linker = "dylint-link" diff --git a/support/lints/error_enum/src/lib.rs b/support/lints/error_enum/src/lib.rs index 33ddc5807..d1cc1cffd 100644 --- a/support/lints/error_enum/src/lib.rs +++ b/support/lints/error_enum/src/lib.rs @@ -2,10 +2,12 @@ #![warn(unused_extern_crates)] extern crate rustc_hir; +extern crate rustc_span; -use clippy_utils::diagnostics::span_lint; +use clippy_utils::{diagnostics::span_lint, ty::implements_trait}; use rustc_hir::{Item, ItemKind}; use rustc_lint::LateLintPass; +use rustc_span::symbol::sym; dylint_linting::declare_late_lint! { /// ### What it does @@ -43,6 +45,16 @@ dylint_linting::declare_late_lint! { impl<'tcx> LateLintPass<'tcx> for EnumVariantEndsWithError { fn check_item(&mut self, cx: &rustc_lint::LateContext<'tcx>, item: &'tcx Item<'tcx>) { if let ItemKind::Enum(_, _, enum_def) = &item.kind { + let ty = cx.tcx.type_of(item.owner_id.def_id).instantiate_identity(); + let implements_error = cx + .tcx + .get_diagnostic_item(sym::Error) + .map_or(false, |id| implements_trait(cx, ty, id, &[])); + + if !implements_error { + return; + } + for variant in enum_def.variants { let variant_name = variant.ident.name.as_str(); if variant_name.ends_with("Error") { diff --git a/support/lints/error_suffix/src/lib.rs b/support/lints/error_suffix/src/lib.rs index df4bcb513..e4753c402 100644 --- a/support/lints/error_suffix/src/lib.rs +++ b/support/lints/error_suffix/src/lib.rs @@ -3,6 +3,7 @@ extern crate rustc_hir; extern crate rustc_span; + use clippy_utils::{diagnostics::span_lint, ty::implements_trait}; use rustc_hir::{Item, ItemKind}; use rustc_lint::LateLintPass; From 3c706317b5655786f2e2605bfcc5815c469c8d1c Mon Sep 17 00:00:00 2001 From: Hinton Date: Tue, 16 Sep 2025 12:43:33 +0200 Subject: [PATCH 2/9] Add dylint to CI --- .github/workflows/lint.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 42bb8b93a..92953a807 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -92,6 +92,12 @@ jobs: - name: Cargo udeps run: cargo +"${{ steps.nightly-toolchain.outputs.RUST_NIGHTLY_TOOLCHAIN }}" udeps --workspace --all-features + - name: Install cargo-dylint + run: cargo install cargo-dylint --version 4.1.0 --locked + + - name: Cargo dylint + run: cargo dylint --all + - name: Set up Node uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: From 579826528bcc1b9e50396bb19f8004b7c74c421e Mon Sep 17 00:00:00 2001 From: Hinton Date: Tue, 16 Sep 2025 12:44:39 +0200 Subject: [PATCH 3/9] Add to lint staged and readme --- README.md | 2 ++ lint-staged.config.js | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5487c43f9..51b23baab 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ versions. Here are the cli tools we use: - Nightly [cargo fmt](https://github.com/rust-lang/rustfmt) and [cargo udeps](https://github.com/est31/cargo-udeps) - [rust clippy](https://github.com/rust-lang/rust-clippy) +- [cargo dylint](https://github.com/trailofbits/dylint) - [cargo sort](https://github.com/DevinR528/cargo-sort) - [prettier](https://github.com/prettier/prettier) @@ -140,6 +141,7 @@ export RUSTFLAGS="-D warnings" cargo +nightly fmt --check cargo +nightly udeps --workspace --all-features cargo clippy --all-features --all-targets +cargo dylint --all cargo sort --workspace --check npm run lint ``` diff --git a/lint-staged.config.js b/lint-staged.config.js index 394140540..d152acbcd 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,6 +1,10 @@ export default { "*": "prettier --cache --ignore-unknown --write", - "*.rs": (stagedFiles) => ["cargo +nightly fmt", "cargo clippy --all-features --all-targets"], + "*.rs": (stagedFiles) => [ + "cargo +nightly fmt", + "cargo clippy --all-features --all-targets", + "cargo dylint --all", + ], "Cargo.toml": (stagedFiles) => [ "cargo +nightly fmt", "cargo +nightly udeps --workspace --all-features", From fadd305843dea8747394311a218a1e929bc13c69 Mon Sep 17 00:00:00 2001 From: Hinton Date: Tue, 16 Sep 2025 15:48:50 +0200 Subject: [PATCH 4/9] Add dylint-link --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 92953a807..70d73856b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -93,7 +93,7 @@ jobs: run: cargo +"${{ steps.nightly-toolchain.outputs.RUST_NIGHTLY_TOOLCHAIN }}" udeps --workspace --all-features - name: Install cargo-dylint - run: cargo install cargo-dylint --version 4.1.0 --locked + run: cargo install cargo-dylint dylint-link --version 4.1.0 --locked - name: Cargo dylint run: cargo dylint --all From 55db2aa9018b8a88b681e28634ff040bea6eb7ac Mon Sep 17 00:00:00 2001 From: Hinton Date: Thu, 18 Sep 2025 13:37:05 +0200 Subject: [PATCH 5/9] Only run dylint on all targets --- .github/workflows/lint.yml | 17 +++++++---------- lint-staged.config.js | 3 +-- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 70d73856b..0dfad0fed 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -59,8 +59,11 @@ jobs: - name: Install clippy-sarif and sarif-fmt run: cargo install clippy-sarif sarif-fmt --locked --git https://github.com/psastras/sarif-rs.git --rev 11c33a53f6ffeaed736856b86fb6b7b09fabdfd8 - - name: Cargo clippy-sarif - run: cargo clippy --all-features --all-targets --message-format=json | + - name: Install cargo-dylint + run: cargo install cargo-dylint dylint-link --version 4.1.0 --locked + + - name: Cargo dylint-sarif + run: cargo dylint --all -- --all-features --all-targets --message-format=json | clippy-sarif | tee clippy_result.sarif | sarif-fmt env: RUSTFLAGS: "-D warnings" @@ -75,8 +78,8 @@ jobs: # Run it again but this time without the sarif output so that the # status code of the command is caught and reported as failed in GitHub. # This should be cached from the previous step and should be fast. - - name: Cargo clippy - run: cargo clippy --all-features --all-targets + - name: Cargo dylint + run: cargo dylint --all -- --all-features --all-targets env: RUSTFLAGS: "-D warnings" @@ -92,12 +95,6 @@ jobs: - name: Cargo udeps run: cargo +"${{ steps.nightly-toolchain.outputs.RUST_NIGHTLY_TOOLCHAIN }}" udeps --workspace --all-features - - name: Install cargo-dylint - run: cargo install cargo-dylint dylint-link --version 4.1.0 --locked - - - name: Cargo dylint - run: cargo dylint --all - - name: Set up Node uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: diff --git a/lint-staged.config.js b/lint-staged.config.js index d152acbcd..796e8c1fb 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -2,8 +2,7 @@ export default { "*": "prettier --cache --ignore-unknown --write", "*.rs": (stagedFiles) => [ "cargo +nightly fmt", - "cargo clippy --all-features --all-targets", - "cargo dylint --all", + "cargo dylint --all -- --all-features --all-targets", ], "Cargo.toml": (stagedFiles) => [ "cargo +nightly fmt", From a881d9fc7275e7a22cadc25506fb1f5a0078a988 Mon Sep 17 00:00:00 2001 From: Hinton Date: Thu, 18 Sep 2025 13:37:44 +0200 Subject: [PATCH 6/9] Remove clippy from readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 51b23baab..35ac344af 100644 --- a/README.md +++ b/README.md @@ -140,8 +140,7 @@ export RUSTFLAGS="-D warnings" cargo +nightly fmt --check cargo +nightly udeps --workspace --all-features -cargo clippy --all-features --all-targets -cargo dylint --all +cargo dylint --all -- --all-features --all-targets cargo sort --workspace --check npm run lint ``` From c043774a1b2e46d26f666cad98e6c24520514884 Mon Sep 17 00:00:00 2001 From: Hinton Date: Thu, 18 Sep 2025 17:40:09 +0200 Subject: [PATCH 7/9] Revert "Remove clippy from readme" This reverts commit a881d9fc7275e7a22cadc25506fb1f5a0078a988. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 35ac344af..51b23baab 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,8 @@ export RUSTFLAGS="-D warnings" cargo +nightly fmt --check cargo +nightly udeps --workspace --all-features -cargo dylint --all -- --all-features --all-targets +cargo clippy --all-features --all-targets +cargo dylint --all cargo sort --workspace --check npm run lint ``` From af9771d3851ddf96f29ac4604c661e9b783f0c07 Mon Sep 17 00:00:00 2001 From: Hinton Date: Thu, 18 Sep 2025 17:40:21 +0200 Subject: [PATCH 8/9] Revert "Only run dylint on all targets" This reverts commit 55db2aa9018b8a88b681e28634ff040bea6eb7ac. --- .github/workflows/lint.yml | 17 ++++++++++------- lint-staged.config.js | 3 ++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0dfad0fed..70d73856b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -59,11 +59,8 @@ jobs: - name: Install clippy-sarif and sarif-fmt run: cargo install clippy-sarif sarif-fmt --locked --git https://github.com/psastras/sarif-rs.git --rev 11c33a53f6ffeaed736856b86fb6b7b09fabdfd8 - - name: Install cargo-dylint - run: cargo install cargo-dylint dylint-link --version 4.1.0 --locked - - - name: Cargo dylint-sarif - run: cargo dylint --all -- --all-features --all-targets --message-format=json | + - name: Cargo clippy-sarif + run: cargo clippy --all-features --all-targets --message-format=json | clippy-sarif | tee clippy_result.sarif | sarif-fmt env: RUSTFLAGS: "-D warnings" @@ -78,8 +75,8 @@ jobs: # Run it again but this time without the sarif output so that the # status code of the command is caught and reported as failed in GitHub. # This should be cached from the previous step and should be fast. - - name: Cargo dylint - run: cargo dylint --all -- --all-features --all-targets + - name: Cargo clippy + run: cargo clippy --all-features --all-targets env: RUSTFLAGS: "-D warnings" @@ -95,6 +92,12 @@ jobs: - name: Cargo udeps run: cargo +"${{ steps.nightly-toolchain.outputs.RUST_NIGHTLY_TOOLCHAIN }}" udeps --workspace --all-features + - name: Install cargo-dylint + run: cargo install cargo-dylint dylint-link --version 4.1.0 --locked + + - name: Cargo dylint + run: cargo dylint --all + - name: Set up Node uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 with: diff --git a/lint-staged.config.js b/lint-staged.config.js index 796e8c1fb..d152acbcd 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -2,7 +2,8 @@ export default { "*": "prettier --cache --ignore-unknown --write", "*.rs": (stagedFiles) => [ "cargo +nightly fmt", - "cargo dylint --all -- --all-features --all-targets", + "cargo clippy --all-features --all-targets", + "cargo dylint --all", ], "Cargo.toml": (stagedFiles) => [ "cargo +nightly fmt", From a57ffed11aa6b1d1068d62db6119f702175c0049 Mon Sep 17 00:00:00 2001 From: Hinton Date: Thu, 18 Sep 2025 17:41:13 +0200 Subject: [PATCH 9/9] Add --all-features --all-targets --- .github/workflows/lint.yml | 2 +- README.md | 2 +- lint-staged.config.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 70d73856b..d371b2a5b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -96,7 +96,7 @@ jobs: run: cargo install cargo-dylint dylint-link --version 4.1.0 --locked - name: Cargo dylint - run: cargo dylint --all + run: cargo dylint --all -- --all-features --all-targets - name: Set up Node uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0 diff --git a/README.md b/README.md index 51b23baab..7ecfcf9ab 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ export RUSTFLAGS="-D warnings" cargo +nightly fmt --check cargo +nightly udeps --workspace --all-features cargo clippy --all-features --all-targets -cargo dylint --all +cargo dylint --all -- --all-features --all-targets cargo sort --workspace --check npm run lint ``` diff --git a/lint-staged.config.js b/lint-staged.config.js index d152acbcd..ac1d8c898 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -3,7 +3,7 @@ export default { "*.rs": (stagedFiles) => [ "cargo +nightly fmt", "cargo clippy --all-features --all-targets", - "cargo dylint --all", + "cargo dylint --all -- --all-features --all-targets", ], "Cargo.toml": (stagedFiles) => [ "cargo +nightly fmt",