Skip to content
Open
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
6 changes: 6 additions & 0 deletions bin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.3.8-git

### Patch

- Update `data-encoding` version

## 0.3.7

### Patch
Expand Down
4 changes: 2 additions & 2 deletions bin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "data-encoding-bin"
version = "0.3.7"
version = "0.3.8-git"
authors = ["Julien Cretin <[email protected]>"]
license = "MIT"
edition = "2021"
Expand All @@ -17,5 +17,5 @@ name = "data-encoding"
path = "src/main.rs"

[dependencies]
data-encoding = { version = "2.9.0", path = "../lib" }
data-encoding = { version = "2.10.0-git", path = "../lib" }
getopts = "0.2"
7 changes: 7 additions & 0 deletions lib/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 2.10.0-git

### Minor

- Document maximum input length for `Encoding::{decode,encode}_len()` (fixes #145)
- Add `Encoding::encode_align()` to decide where to split long inputs

## 2.9.0

### Minor
Expand Down
2 changes: 1 addition & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "data-encoding"
version = "2.9.0"
version = "2.10.0-git"
authors = ["Julien Cretin <[email protected]>"]
license = "MIT"
edition = "2018"
Expand Down
8 changes: 8 additions & 0 deletions lib/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ libfuzzer-sys = "0.4.3"
name = "fuzz_any_spec"
path = "fuzz_targets/fuzz_any_spec.rs"

[[bin]]
name = "impl_encode_len"
path = "fuzz_targets/impl_encode_len.rs"

[[bin]]
name = "impl_decode_len"
path = "fuzz_targets/impl_decode_len.rs"

[[bin]]
name = "impl_encode"
path = "fuzz_targets/impl_encode.rs"
Expand Down
1 change: 1 addition & 0 deletions lib/fuzz/fuzz_targets/impl_decode_len.rs
1 change: 1 addition & 0 deletions lib/fuzz/fuzz_targets/impl_encode_len.rs
8 changes: 6 additions & 2 deletions lib/fuzz/run.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/bin/sh

N="$(cargo fuzz list | wc -l)"
LIST="$*"
[ -n "$LIST" ] || LIST=$(echo $(cargo fuzz list))
list() { for x in $LIST; do echo $x; done; }

N="$(list | wc -l)"
i=1
next() { cargo fuzz list | head -n$i | tail -n1; }
next() { list | head -n$i | tail -n1; }
while cargo fuzz run "$(next)" -- -max_total_time=600; do
i=$(( i % N + 1 ))
done
8 changes: 8 additions & 0 deletions lib/fuzz/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ pub fn execute(target: &str, mut input: &[u8]) -> Output {
let input = gen::rev_spec(&spec);
assert_eq!(gen::spec(&mut input.as_slice()).encoding().unwrap(), base);
}
"impl_encode_len" => {
let (_, base) = gen_spec_base(&mut input, &mut output);
let _ = base.encode_len(usize::MAX / 512);
}
"impl_decode_len" => {
let (_, base) = gen_spec_base(&mut input, &mut output);
let _ = base.decode_len(usize::MAX / 8);
}
"impl_encode" => {
let (spec, base) = gen_spec_base(&mut input, &mut output);
assert_eq!(base.encode(input), spec::encode(&spec, input));
Expand Down
6 changes: 3 additions & 3 deletions lib/macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "data-encoding-macro"
version = "0.1.18"
version = "0.1.19-git"
authors = ["Julien Cretin <[email protected]>"]
license = "MIT"
edition = "2018"
Expand All @@ -14,5 +14,5 @@ description = "Macros for data-encoding"
include = ["Cargo.toml", "LICENSE", "README.md", "src/lib.rs"]

[dependencies]
data-encoding = { version = "2.9.0", path = "..", default-features = false }
data-encoding-macro-internal = { version = "0.1.16", path = "internal" }
data-encoding = { version = "2.10.0-git", path = "..", default-features = false }
data-encoding-macro-internal = { version = "0.1.17-git", path = "internal" }
4 changes: 2 additions & 2 deletions lib/macro/internal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "data-encoding-macro-internal"
version = "0.1.16"
version = "0.1.17-git"
authors = ["Julien Cretin <[email protected]>"]
license = "MIT"
edition = "2018"
Expand All @@ -14,7 +14,7 @@ include = ["Cargo.toml", "LICENSE", "README.md", "src/lib.rs"]
proc-macro = true

[dependencies.data-encoding]
version = "2.9.0"
version = "2.10.0-git"
path = "../.."
default-features = false
features = ["alloc"]
Expand Down
53 changes: 53 additions & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,9 +1256,26 @@ impl Encoding {
///
/// See [`encode_mut`] for when to use it.
///
/// # Panics
///
/// May panic if `len` is greater than `usize::MAX / 512`:
/// - `len <= 8_388_607` when `target_pointer_width = "32"`
/// - `len <= 36028_797018_963967` when `target_pointer_width = "64"`
///
/// If you need to encode an input of length greater than this limit (possibly of infinite
/// length), then you must chunk your input, encode each chunk, and concatenate to obtain the
/// output. The length of each input chunk must be a multiple of [`encode_align`].
///
/// Note that this function only _may_ panic in those cases. The function may also return the
/// correct value in some cases depending on the implementation. In other words, those limits
/// are the guarantee below which the function will not panic, and not the guarantee above which
/// the function will panic.
///
/// [`encode_align`]: struct.Encoding.html#method.encode_align
/// [`encode_mut`]: struct.Encoding.html#method.encode_mut
#[must_use]
pub fn encode_len(&self, len: usize) -> usize {
assert!(len <= usize::MAX / 512);
dispatch! {
let bit: usize = self.bit();
let pad: Option<u8> = self.pad();
Expand All @@ -1267,6 +1284,20 @@ impl Encoding {
}
}

/// Returns the minimum alignment when chunking a long input
///
/// See [`encode_len`] for context.
///
/// [`encode_len`]: struct.Encoding.html#method.encode_len
#[must_use]
pub fn encode_align(&self) -> usize {
let bit = self.bit();
match self.wrap() {
None => enc(bit),
Some((col, _)) => col * bit / 8,
}
}

/// Encodes `input` in `output`
///
/// # Panics
Expand Down Expand Up @@ -1433,6 +1464,27 @@ impl Encoding {
/// See [`decode_mut`] for when to use it. In particular, the actual decoded length might be
/// smaller if the actual input contains padding or ignored characters.
///
/// # Panics
///
/// May panic if `len` is greater than `usize::MAX / 8`:
/// - `len <= 536_870_911` when `target_pointer_width = "32"`
/// - `len <= 2_305843_009213_693951` when `target_pointer_width = "64"`
///
/// If you need to decode an input of length greater than this limit (possibly of infinite
/// length), then you must decode your input chunk by chunk with [`decode_mut`], making sure
/// that you take into account how many bytes have been read from the input and how many bytes
/// have been written to the output:
/// - `Ok(written)` means all bytes have been read and `written` bytes have been written
/// - `Err(DecodePartial { error, .. })` means an error occurred if `error.kind !=
/// DecodeKind::Length` or this was the last input chunk
/// - `Err(DecodePartial { read, written, .. })` means that `read` bytes have been read and
/// `written` bytes written (the error can be ignored)
///
/// Note that this function only _may_ panic in those cases. The function may also return the
/// correct value in some cases depending on the implementation. In other words, those limits
/// are the guarantee below which the function will not panic, and not the guarantee above which
/// the function will panic.
///
/// # Errors
///
/// Returns an error if `len` is invalid. The error kind is [`Length`] and the [position] is the
Expand All @@ -1442,6 +1494,7 @@ impl Encoding {
/// [`Length`]: enum.DecodeKind.html#variant.Length
/// [position]: struct.DecodeError.html#structfield.position
pub fn decode_len(&self, len: usize) -> Result<usize, DecodeError> {
assert!(len <= usize::MAX / 8);
let (ilen, olen) = dispatch! {
let bit: usize = self.bit();
let pad: bool = self.pad().is_some();
Expand Down