Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,35 @@ jobs:
- name: Spell Check
uses: crate-ci/typos@master

# Run 32-bit support check separately.
bit-32-support:
runs-on: ubuntu-latest

strategy:
matrix:
# The list of crates to check for 32 bit support
# TODO: check features.
crate: [
cuprate-epee-encoding,
cuprate-rpc-types,
cuprate-fixed-bytes,
]

steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
targets: wasm32-unknown-unknown

- name: Build 32 bit
run: cargo build --target wasm32-unknown-unknown -p ${{ matrix.crate }}

# All other CI.
ci:
runs-on: ${{ matrix.os }}
Expand Down
1 change: 0 additions & 1 deletion Cargo.lock

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

1 change: 0 additions & 1 deletion net/epee-encoding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ default = ["std"]
std = ["dep:thiserror", "bytes/std", "cuprate-fixed-bytes/std"]

[dependencies]
cuprate-helper = { workspace = true, default-features = false, features = ["cast"] }
cuprate-fixed-bytes = { workspace = true, default-features = false }

paste = "1.0.15"
Expand Down
12 changes: 5 additions & 7 deletions net/epee-encoding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ use core::str::from_utf8 as str_from_utf8;

use bytes::{Buf, BufMut, Bytes, BytesMut};

use cuprate_helper::cast::{u64_to_usize, usize_to_u64};

pub mod container_as_blob;
pub mod error;
mod io;
Expand All @@ -89,7 +87,7 @@ pub use varint::{read_varint, write_varint};
/// this binary serialization format.
const HEADER: &[u8] = b"\x01\x11\x01\x01\x01\x01\x02\x01\x01";
/// The maximum length a byte array (marked as a string) can be.
const MAX_STRING_LEN_POSSIBLE: u64 = 2000000000;
const MAX_STRING_LEN_POSSIBLE: usize = 2000000000;
/// The maximum depth of skipped objects.
const MAX_DEPTH_OF_SKIPPED_OBJECTS: u8 = 20;
/// The maximum number of fields in an object.
Expand Down Expand Up @@ -248,7 +246,7 @@ pub fn write_bytes<T: AsRef<[u8]>, B: BufMut>(t: T, w: &mut B) -> Result<()> {
let bytes = t.as_ref();
let len = bytes.len();

write_varint(usize_to_u64(len), w)?;
write_varint(len, w)?;

if w.remaining_mut() < len {
return Err(Error::IO("Not enough capacity to write bytes"));
Expand Down Expand Up @@ -292,7 +290,7 @@ where
I: Iterator<Item = T> + ExactSizeIterator,
B: BufMut,
{
write_varint(usize_to_u64(iterator.len()), w)?;
write_varint(iterator.len(), w)?;
for item in iterator {
item.write(w)?;
}
Expand Down Expand Up @@ -337,7 +335,7 @@ fn skip_epee_value<B: Buf>(r: &mut B, skipped_objects: &mut u8) -> Result<()> {

if let Some(size) = marker.inner_marker.size() {
let bytes_to_skip = size
.checked_mul(u64_to_usize(len))
.checked_mul(len.try_into()?)
.ok_or(Error::Value("List is too big".to_string()))?;
return advance(bytes_to_skip, r);
};
Expand All @@ -355,7 +353,7 @@ fn skip_epee_value<B: Buf>(r: &mut B, skipped_objects: &mut u8) -> Result<()> {
| InnerMarker::U8
| InnerMarker::Bool => unreachable!("These types are constant size."),
InnerMarker::String => {
let len = u64_to_usize(read_varint(r)?);
let len = read_varint(r)?;
advance(len, r)?;
}
InnerMarker::Object => {
Expand Down
19 changes: 5 additions & 14 deletions net/epee-encoding/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use core::fmt::Debug;
use bytes::{Buf, BufMut, Bytes, BytesMut};

use cuprate_fixed_bytes::{ByteArray, ByteArrayVec};
use cuprate_helper::cast::u64_to_usize;

use crate::{
io::{checked_read_primitive, checked_write_primitive},
Expand Down Expand Up @@ -67,7 +66,7 @@ impl<T: EpeeObject> EpeeValue for Vec<T> {
"Marker is not sequence when a sequence was expected",
));
}
let len = u64_to_usize(read_varint(r)?);
let len = read_varint(r)?;

let individual_marker = Marker::new(marker.inner_marker);

Expand Down Expand Up @@ -168,8 +167,6 @@ impl EpeeValue for Vec<u8> {
return Err(Error::Format("Byte array exceeded max length"));
}

let len = u64_to_usize(len);

if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object"));
}
Expand Down Expand Up @@ -206,8 +203,6 @@ impl EpeeValue for Bytes {
return Err(Error::Format("Byte array exceeded max length"));
}

let len = u64_to_usize(len);

if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object"));
}
Expand Down Expand Up @@ -241,8 +236,6 @@ impl EpeeValue for BytesMut {
return Err(Error::Format("Byte array exceeded max length"));
}

let len = u64_to_usize(len);

if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object"));
}
Expand Down Expand Up @@ -274,13 +267,11 @@ impl<const N: usize> EpeeValue for ByteArrayVec<N> {
return Err(Error::Format("Marker does not match expected Marker"));
}

let len = read_varint(r)?;
let len = read_varint::<_, usize>(r)?;
if len > MAX_STRING_LEN_POSSIBLE {
return Err(Error::Format("Byte array exceeded max length"));
}

let len = u64_to_usize(len);

if r.remaining() < len {
return Err(Error::IO("Not enough bytes to fill object"));
}
Expand Down Expand Up @@ -310,7 +301,7 @@ impl<const N: usize> EpeeValue for ByteArray<N> {
return Err(Error::Format("Marker does not match expected Marker"));
}

let len = u64_to_usize(read_varint(r)?);
let len = read_varint::<_, usize>(r)?;
if len != N {
return Err(Error::Format("Byte array has incorrect length"));
}
Expand Down Expand Up @@ -377,7 +368,7 @@ impl<const N: usize> EpeeValue for Vec<[u8; N]> {
));
}

let len = u64_to_usize(read_varint(r)?);
let len = read_varint(r)?;

let individual_marker = Marker::new(marker.inner_marker);

Expand Down Expand Up @@ -413,7 +404,7 @@ macro_rules! epee_seq {
));
}

let len = u64_to_usize(read_varint(r)?);
let len = read_varint(r)?;

let individual_marker = Marker::new(marker.inner_marker.clone());

Expand Down
26 changes: 16 additions & 10 deletions net/epee-encoding/src/varint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ const FITS_IN_FOUR_BYTES: u64 = 2_u64.pow(32 - SIZE_OF_SIZE_MARKER) - 1;
/// ```rust
/// use cuprate_epee_encoding::read_varint;
///
/// assert_eq!(read_varint(&mut [252].as_slice()).unwrap(), 63);
/// assert_eq!(read_varint(&mut [1, 1].as_slice()).unwrap(), 64);
/// assert_eq!(read_varint(&mut [253, 255].as_slice()).unwrap(), 16_383);
/// assert_eq!(read_varint(&mut [2, 0, 1, 0].as_slice()).unwrap(), 16_384);
/// assert_eq!(read_varint(&mut [254, 255, 255, 255].as_slice()).unwrap(), 1_073_741_823);
/// assert_eq!(read_varint(&mut [3, 0, 0, 0, 1, 0, 0, 0].as_slice()).unwrap(), 1_073_741_824);
/// assert_eq!(read_varint::<_, u64>(&mut [252].as_slice()).unwrap(), 63);
/// assert_eq!(read_varint::<_, u64>(&mut [1, 1].as_slice()).unwrap(), 64);
/// assert_eq!(read_varint::<_, u64>(&mut [253, 255].as_slice()).unwrap(), 16_383);
/// assert_eq!(read_varint::<_, u64>(&mut [2, 0, 1, 0].as_slice()).unwrap(), 16_384);
/// assert_eq!(read_varint::<_, u64>(&mut [254, 255, 255, 255].as_slice()).unwrap(), 1_073_741_823);
/// assert_eq!(read_varint::<_, u64>(&mut [3, 0, 0, 0, 1, 0, 0, 0].as_slice()).unwrap(), 1_073_741_824);
/// ```
pub fn read_varint<B: Buf>(r: &mut B) -> Result<u64> {
pub fn read_varint<B: Buf, T: TryFrom<u64>>(r: &mut B) -> Result<T> {
if !r.has_remaining() {
return Err(Error::IO("Not enough bytes to build VarInt"));
}
Expand All @@ -35,7 +35,8 @@ pub fn read_varint<B: Buf>(r: &mut B) -> Result<u64> {
for i in 1..len {
vi |= u64::from(r.get_u8()) << (((i - 1) * 8) + 6);
}
Ok(vi)

vi.try_into().map_err(|_| Error::IO("VarInt is too big"))
}

/// Write an epee variable sized number into `w`.
Expand All @@ -58,7 +59,12 @@ pub fn read_varint<B: Buf>(r: &mut B) -> Result<u64> {
/// assert_eq!(buf.as_slice(), expected_bytes);
/// }
/// ```
pub fn write_varint<B: BufMut>(number: u64, w: &mut B) -> Result<()> {
pub fn write_varint<B: BufMut, T: TryInto<u64>>(number: T, w: &mut B) -> Result<()> {
let number = number
.try_into()
.map_err(|_| "Tried to write a varint bigger than 64-bits")
.unwrap();

let size_marker = match number {
0..=FITS_IN_ONE_BYTE => 0,
64..=FITS_IN_TWO_BYTES => 1,
Expand Down Expand Up @@ -101,7 +107,7 @@ mod tests {
}

fn assert_varint_val(mut varint: &[u8], val: u64) {
assert_eq!(read_varint(&mut varint).unwrap(), val);
assert_eq!(read_varint::<_, u64>(&mut varint).unwrap(), val);
}

#[test]
Expand Down
Loading