What changed, and why it matters
This is a routine code-maintenance commit. It moves lint (style and warning) settings from an individual sub-crate to the shared workspace configuration, cleans up some import statements, adds documentation comments, and swaps a few style idioms (like `copied()` instead of `cloned()`). There is no change to security-sensitive behavior, no bug fix, and no vulnerability patch.
No security action required. Treat as normal refactoring/maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit migrates the base58 crate’s lint configuration to the workspace-level [workspace.lints] in Cargo.toml, removing per-crate lint overrides. It adds cfg(fuzzing) to the workspace unexpected_cfgs check-cfg list. In base58/src/error.rs it replaces wildcard use ErrorInner::* with explicit imports. In base58/src/lib.rs it removes several crate-level allow attributes now handled by workspace lints, adds # Errors documentation to public functions, and applies minor clippy-suggested cleanups (&mut scratch, .copied()). Two binary .rlib test artifacts are added. No functional logic changes.
Changed components
base58/Cargo.tomlbase58/src/error.rsbase58/src/lib.rsCargo.toml workspace lintsInspect captured patch +24 / −14
diff --git a/Cargo.toml b/Cargo.toml
index f111ab52..0033a4fa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,7 @@ exclude = ["benches"]
resolver = "2"
[workspace.lints.rust]
-unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(kani)'] }
+unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(fuzzing)', 'cfg(kani)'] }
[workspace.lints.clippy]
# Exclude lints we don't think are valuable.
diff --git a/base58/Cargo.toml b/base58/Cargo.toml
index 8480d2e5..6ebce476 100644
--- a/base58/Cargo.toml
+++ b/base58/Cargo.toml
@@ -28,9 +28,5 @@ hex_lit = "0.1.1"
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
-[lints.rust]
-unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(fuzzing)', 'cfg(kani)' ] }
-
-[lints.clippy]
-redundant_clone = "warn"
-use_self = "warn"
+[lints]
+workspace = true
diff --git a/base58/src/error.rs b/base58/src/error.rs
index 1280ac8d..1b6e2892 100644
--- a/base58/src/error.rs
+++ b/base58/src/error.rs
@@ -57,7 +57,7 @@ impl Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use ErrorInner::*;
+ use ErrorInner::{Decode, IncorrectChecksum, TooShort};
match self.0 {
Decode(ref e) => write_err!(f, "decode"; e),
@@ -70,7 +70,7 @@ impl fmt::Display for Error {
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- use ErrorInner::*;
+ use ErrorInner::{Decode, IncorrectChecksum, TooShort};
match self.0 {
Decode(ref e) => Some(e),
diff --git a/base58/src/lib.rs b/base58/src/lib.rs
index 85debd87..0f8e3c9f 100644
--- a/base58/src/lib.rs
+++ b/base58/src/lib.rs
@@ -17,10 +17,7 @@
#![cfg_attr(fuzzing, allow(dead_code, unused_imports))]
#![cfg_attr(bench, allow(dead_code, unused_imports))]
// Exclude lints we don't think are valuable.
-#![allow(clippy::needless_question_mark)] // https://github.com/rust-bitcoin/rust-bitcoin/pull/2134
-#![allow(clippy::manual_range_contains)] // More readable than clippy's format.
#![allow(clippy::incompatible_msrv)] // Has FPs and we're testing it which is more reliable anyway.
-#![allow(clippy::uninlined_format_args)] // Allow `format!("{}", x)` instead of enforcing `format!("{x}")`
extern crate alloc;
@@ -73,6 +70,11 @@ static BASE58_DIGITS: [Option<u8>; 128] = [
];
/// Decodes a base58-encoded string into a byte vector.
+///
+/// # Errors
+///
+/// Returns an error if the input contains an invalid base58 character (not in the base58 alphabet).
+#[allow(clippy::missing_panics_doc)] // Internal assertion, not user-controllable.
pub fn decode(data: &str) -> Result<Vec<u8>, InvalidCharacterError> {
// 11/15 is just over log_256(58)
let mut scratch = Vec::with_capacity(1 + data.len() * 11 / 15);
@@ -94,7 +96,7 @@ pub fn decode(data: &str) -> Result<Vec<u8>, InvalidCharacterError> {
carry /= 256;
}
} else {
- for d256 in scratch.iter_mut() {
+ for d256 in &mut scratch {
carry += u32::from(*d256) * 58;
*d256 = carry as u8; // cast loses data intentionally
carry /= 256;
@@ -111,6 +113,12 @@ pub fn decode(data: &str) -> Result<Vec<u8>, InvalidCharacterError> {
}
/// Decodes a base58check-encoded string into a byte vector verifying the checksum.
+///
+/// # Errors
+///
+/// * The input contains an invalid base58 character.
+/// * The decoded data is less than 4 bytes (too short for checksum verification).
+/// * The checksum does not match the expected value.
pub fn decode_check(data: &str) -> Result<Vec<u8>, Error> {
let mut ret: Vec<u8> = decode(data)?;
let (remaining, &data_check) =
@@ -132,6 +140,7 @@ pub fn decode_check(data: &str) -> Result<Vec<u8>, Error> {
const SHORT_OPT_BUFFER_LEN: usize = 128;
/// Encodes `data` as a base58 string (see also `base58::encode_check()`).
+#[allow(clippy::missing_panics_doc)] // fmt::Write returns Result but String is infallible.
pub fn encode(data: &[u8]) -> String {
let reserve_len = encoded_reserve_len(data.len());
let mut res = String::with_capacity(reserve_len);
@@ -151,6 +160,7 @@ pub fn encode(data: &[u8]) -> String {
/// Encodes `data` as a base58 string including the checksum.
///
/// The checksum is the first four bytes of the sha256d of the data, concatenated onto the end.
+#[allow(clippy::missing_panics_doc)] // fmt::Write returns Result but String is infallible.
pub fn encode_check(data: &[u8]) -> String {
let mut res = String::with_capacity(encoded_check_reserve_len(data.len()));
encode_check_to_writer(&mut res, data).expect("string doesn't fail");
@@ -160,13 +170,17 @@ pub fn encode_check(data: &[u8]) -> String {
/// Encodes a slice as base58, including the checksum, into a formatter.
///
/// The checksum is the first four bytes of the sha256d of the data, concatenated onto the end.
+///
+/// # Errors
+///
+/// Returns an error if the formatter fails to write the encoded string.
pub fn encode_check_to_fmt(fmt: &mut fmt::Formatter, data: &[u8]) -> fmt::Result {
encode_check_to_writer(fmt, data)
}
fn encode_check_to_writer(fmt: &mut impl fmt::Write, data: &[u8]) -> fmt::Result {
let checksum = sha256d::Hash::hash(data);
- let iter = data.iter().cloned().chain(checksum.as_byte_array()[0..4].iter().cloned());
+ let iter = data.iter().copied().chain(checksum.as_byte_array()[0..4].iter().copied());
let reserve_len = encoded_check_reserve_len(data.len());
if reserve_len <= SHORT_OPT_BUFFER_LEN {
format_iter(fmt, iter, &mut ArrayVec::<u8, SHORT_OPT_BUFFER_LEN>::new())
diff --git a/liballow_test.rlib b/liballow_test.rlib
new file mode 100644
index 00000000..115f9227
Binary files /dev/null and b/liballow_test.rlib differ
diff --git a/libinline_allow_test.rlib b/libinline_allow_test.rlib
new file mode 100644
index 00000000..ce435c9e
Binary files /dev/null and b/libinline_allow_test.rlib differ
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.