Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: build

on: [push, pull_request]
on:
push:
pull_request:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:

jobs:
build:
Expand Down Expand Up @@ -113,3 +118,46 @@ jobs:

- name: Upload Code Coverage
uses: codecov/codecov-action@v5

fuzz:
name: Fuzz
runs-on: ubuntu-latest
# Bounded fuzzing is expensive. Only run on schedule or manual dispatch
# to avoid exhausting CI minutes; regular push/PR CI already covers
# fmt, clippy, audit, MSRV, no_std, and coverage.
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'

steps:
- name: Checkout Sources
uses: actions/checkout@v5

- name: Install Rust Toolchain (nightly)
uses: dtolnay/rust-toolchain@nightly

- name: Cache Dependencies & Build Outputs
uses: actions/cache@v4
with:
path: |
~/.cargo
target
fuzz/target
key: ${{ runner.os }}-fuzz-${{ hashFiles('**/Cargo.lock') }}

- name: Install cargo-fuzz
run: cargo install cargo-fuzz
shell: bash

- name: Run fuzz_decode (60s)
run: cargo fuzz run fuzz_decode -- -max_total_time=60
working-directory: fuzz
shell: bash

- name: Run fuzz_encode (60s)
run: cargo fuzz run fuzz_encode -- -max_total_time=60
working-directory: fuzz
shell: bash

- name: Run fuzz_roundtrip (60s)
run: cargo fuzz run fuzz_roundtrip -- -max_total_time=60
working-directory: fuzz
shell: bash
10 changes: 5 additions & 5 deletions CONCURRENCY.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ let handles: Vec<_> = (0..10)
.map(|_| {
let d = data.clone();
thread::spawn(move || {
multibase::encode(Base::Base64, &d)
multi_base::encode(Base::Base64, &d)
})
})
.collect();
Expand All @@ -140,7 +140,7 @@ let handles: Vec<_> = (0..10)
.map(|_| {
let e = Arc::clone(&encoded);
thread::spawn(move || {
multibase::decode(&*e, true)
multi_base::decode(&*e, true)
})
})
.collect();
Expand All @@ -164,8 +164,8 @@ let handles: Vec<_> = (0..10)
let mut decode_buffer = Vec::new();

for _ in 0..100 {
multibase::encode_into(Base::Base64, b"data", &mut encode_buffer);
multibase::decode_into(&encode_buffer, true, &mut decode_buffer).unwrap();
multi_base::encode_into(Base::Base64, b"data", &mut encode_buffer);
multi_base::decode_into(&encode_buffer, true, &mut decode_buffer).unwrap();
}
})
})
Expand Down Expand Up @@ -215,7 +215,7 @@ let handles: Vec<_> = (0..10)
.map(|_| {
thread::spawn(move || {
let mut buf = shared_buffer.lock().unwrap();
multibase::encode_into(Base::Base64, b"data", &mut buf);
multi_base::encode_into(Base::Base64, b"data", &mut buf);
})
})
.collect();
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "multi-base"
version = "1.0.2"
version = "1.0.3"
authors = ["Friedel Ziegelmayer <dignifiedquire@gmail.com>", "Dave Grantham <dwg@linuxprogrammer.org>"]
edition = "2024"
rust-version = "1.85"
Expand Down
12 changes: 6 additions & 6 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn safe_decode(input: &str) -> Result<(Base, Vec<u8>), Error> {
if input.len() > MAX_INPUT_SIZE {
return Err(Error::InvalidBaseString); // or custom error
}
multibase::decode(input, true)
multi_base::decode(input, true)
}
```

Expand All @@ -68,7 +68,7 @@ fn safe_decode(input: &str) -> Result<(Base, Vec<u8>), Error> {
Always handle errors properly and avoid exposing detailed error messages to untrusted parties:

```rust
match multibase::decode(untrusted_input, true) {
match multi_base::decode(untrusted_input, true) {
Ok((base, data)) => {
// Process data
}
Expand All @@ -89,10 +89,10 @@ The Identity encoding (`\0` prefix) uses lossy UTF-8 conversion:

```rust
// For exact binary data preservation, use Base64 or Base58
let encoded = multibase::encode(Base::Base64, binary_data);
let encoded = multi_base::encode(Base::Base64, binary_data);

// Identity is only appropriate for UTF-8 text
let text_encoded = multibase::encode(Base::Identity, "valid utf-8 text".as_bytes());
let text_encoded = multi_base::encode(Base::Identity, "valid utf-8 text".as_bytes());
```

### 4. Strict vs Permissive Decoding
Expand All @@ -101,10 +101,10 @@ Use strict decoding (`true`) for untrusted input to ensure stricter validation:

```rust
// For untrusted input, always use strict mode
let (base, data) = multibase::decode(untrusted, true)?;
let (base, data) = multi_base::decode(untrusted, true)?;

// Permissive mode allows case-insensitive decoding for some bases
let (base, data) = multibase::decode(trusted, false)?;
let (base, data) = multi_base::decode(trusted, false)?;
```

## Security Testing
Expand Down
Loading