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
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ restriction = { level = "warn", priority = -2 }

arithmetic_side_effects = "allow" # TODO: consider
as_conversions = "allow" # TODO: tricky
cast_possible_truncation = "allow" # TODO: consider
cast_precision_loss = "allow" # TODO: consider
checked_conversions = "allow"
else_if_without_else = "allow"
Expand Down
31 changes: 18 additions & 13 deletions src/proto/h1/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,18 @@ impl Encoder {
}
Kind::Length(remaining) => {
trace!("sized write, len = {}", len);
if len as u64 > *remaining {
let limit = *remaining as usize;
*remaining = 0;
BufKind::Limited(msg.take(limit))
} else {
*remaining -= len as u64;
BufKind::Exact(msg)
match usize::try_from(*remaining) {
// Holding more than is owed, so write only what is left.
Ok(limit) if limit < len => {
*remaining = 0;
BufKind::Limited(msg.take(limit))
}
// Ok(_) => Owed at least what we hold, write all of it.
// Err(_) => Owed more than `usize` can represent, write all of it.
Ok(_) | Err(_) => {

@Siech0 Siech0 Sep 11, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this can just be folded to -> _, but I felt like keeping the separation makes the clarity of why that is the case more obvious.

*remaining -= len as u64;
BufKind::Exact(msg)
}
}
}
#[cfg(feature = "server")]
Expand Down Expand Up @@ -241,6 +246,7 @@ impl Encoder {
dst.buffer(msg);
!self.is_last
}
#[allow(clippy::cast_possible_truncation, reason="usize::MAX > len > remaining, cast truncation is impossible")]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did an analysis on the assembly using try_from would produce here, and it would be a regression in performance on 32-bit systems. the as cast here does allow the compiler to enforce a more tight invariant and it is completely sound so I allowed it explicitly.

Ordering::Greater => {
dst.buffer(msg.take(remaining as usize));
!self.is_last
Expand Down Expand Up @@ -328,11 +334,7 @@ where
}
}

#[cfg(target_pointer_width = "32")]
const USIZE_BYTES: usize = 4;

#[cfg(target_pointer_width = "64")]
const USIZE_BYTES: usize = 8;
const USIZE_BYTES: usize = std::mem::size_of::<usize>();

// each byte will become 2 hex
const CHUNK_SIZE_MAX_BYTES: usize = USIZE_BYTES * 2;
Expand Down Expand Up @@ -369,6 +371,7 @@ impl Buf for ChunkSize {
}

#[inline]
#[allow(clippy::cast_possible_truncation)]
fn advance(&mut self, cnt: usize) {
assert!(cnt <= self.remaining());
self.pos += cnt as u8; // just asserted cnt fits in u8
Expand All @@ -385,12 +388,14 @@ impl fmt::Debug for ChunkSize {
}

impl fmt::Write for ChunkSize {
#[allow(clippy::cast_possible_truncation, reason="bytes is structurally always less than u8::MAX")]
fn write_str(&mut self, num: &str) -> fmt::Result {
use std::io::Write;
(&mut self.bytes[self.len.into()..])
.write_all(num.as_bytes())
.expect("&mut [u8].write() cannot error");
self.len += num.len() as u8; // safe because bytes is never bigger than 256
debug_assert!(u8::try_from(num.len()).is_ok());
self.len += num.len() as u8; // safe because bytes is never bigger than 255
Ok(())
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/proto/h2/ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,12 @@ impl Shared {
// ===== impl Bdp =====

/// Any higher than this likely will be hitting the TCP flow control.
const BDP_LIMIT: usize = 1024 * 1024 * 16;
const BDP_LIMIT: WindowSize = 1024 * 1024 * 16;

impl Bdp {
fn calculate(&mut self, bytes: usize, rtt: Duration) -> Option<WindowSize> {
// No need to do any math if we're at the limit.
if self.bdp as usize == BDP_LIMIT {
if self.bdp == BDP_LIMIT {
self.stabilize_delay();
return None;
}
Expand Down Expand Up @@ -396,7 +396,8 @@ impl Bdp {
// if the current `bytes` sample is at least 2/3 the previous
// bdp, increase to double the current sample.
if bytes >= self.bdp as usize * 2 / 3 {
self.bdp = (bytes * 2).min(BDP_LIMIT) as WindowSize;
self.bdp = WindowSize::try_from((bytes * 2).min(BDP_LIMIT as usize))
.unwrap_or(BDP_LIMIT);
trace!("BDP increased to {}", self.bdp);

self.stable_count = 0;
Expand Down