Skip to content

Commit ef5bf15

Browse files
committed
First try for checked version of tls_serialized_len.
1 parent 4dad457 commit ef5bf15

File tree

10 files changed

+195
-36
lines changed

10 files changed

+195
-36
lines changed

tls_codec/derive/src/lib.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@
9090
//! TlsByteSliceU32(v).tls_serialized_len()
9191
//! }
9292
//!
93+
//! pub fn tls_serialized_len_checked(v: &[u8]) -> Option<usize> {
94+
//! TlsByteSliceU32(v).tls_serialized_len_checked()
95+
//! }
96+
//!
9397
//! pub fn tls_serialize<W: Write>(v: &[u8], writer: &mut W) -> Result<usize, tls_codec::Error> {
9498
//! TlsByteSliceU32(v).tls_serialize(writer)
9599
//! }
@@ -787,13 +791,21 @@ fn impl_tls_size(parsed_ast: TlsStruct) -> TokenStream2 {
787791
#(#prefixes::tls_serialized_len(&self.#members) + )*
788792
0
789793
}
794+
#[inline]
795+
fn tls_serialized_len_checked(&self) -> Option<usize> {
796+
Some(0usize#(.checked_add(#prefixes::tls_serialized_len_checked(&self.#members)?)?)*)
797+
}
790798
}
791799

792800
impl #impl_generics tls_codec::Size for &#ident #ty_generics #where_clause {
793801
#[inline]
794802
fn tls_serialized_len(&self) -> usize {
795803
tls_codec::Size::tls_serialized_len(*self)
796804
}
805+
#[inline]
806+
fn tls_serialized_len_checked(&self) -> Option<usize> {
807+
tls_codec::Size::tls_serialized_len_checked(*self)
808+
}
797809
}
798810
}
799811
}
@@ -827,13 +839,24 @@ fn impl_tls_size(parsed_ast: TlsStruct) -> TokenStream2 {
827839
};
828840
core::mem::size_of::<#repr>() + field_len
829841
}
842+
#[inline]
843+
fn tls_serialized_len_checked(&self) -> Option<usize> {
844+
let field_len = match self {
845+
#(#field_arms)*
846+
};
847+
core::mem::size_of::<#repr>().checked_add(field_len)
848+
}
830849
}
831850

832851
impl #impl_generics tls_codec::Size for &#ident #ty_generics #where_clause {
833852
#[inline]
834853
fn tls_serialized_len(&self) -> usize {
835854
tls_codec::Size::tls_serialized_len(*self)
836855
}
856+
#[inline]
857+
fn tls_serialized_len_checked(&self) -> Option<usize> {
858+
tls_codec::Size::tls_serialized_len_checked(*self)
859+
}
837860
}
838861
}
839862
}

tls_codec/derive/tests/decode.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ mod custom {
273273
TlsByteSliceU32(v).tls_serialized_len()
274274
}
275275

276+
pub fn tls_serialized_len_checked(v: &[u8]) -> Option<usize> {
277+
TlsByteSliceU32(v).tls_serialized_len_checked()
278+
}
279+
276280
pub fn tls_serialize<W: Write>(v: &[u8], writer: &mut W) -> Result<usize, tls_codec::Error> {
277281
TlsByteSliceU32(v).tls_serialize(writer)
278282
}
@@ -297,6 +301,10 @@ mod custom_bytes {
297301
TlsByteSliceU32(v).tls_serialized_len()
298302
}
299303

304+
pub fn tls_serialized_len_checked(v: &[u8]) -> Option<usize> {
305+
TlsByteSliceU32(v).tls_serialized_len_checked()
306+
}
307+
300308
pub fn tls_serialize<W: Write>(v: &[u8], writer: &mut W) -> Result<usize, tls_codec::Error> {
301309
TlsByteSliceU32(v).tls_serialize(writer)
302310
}

tls_codec/derive/tests/decode_bytes.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ mod custom {
9090
v.tls_serialized_len()
9191
}
9292

93+
pub fn tls_serialized_len_checked(v: &[u8]) -> Option<usize> {
94+
v.tls_serialized_len_checked()
95+
}
96+
9397
pub fn tls_serialize(v: &[u8]) -> Result<Vec<u8>, tls_codec::Error> {
9498
v.tls_serialize()
9599
}

tls_codec/derive/tests/encode.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ mod custom {
131131
TlsByteSliceU32(v).tls_serialized_len()
132132
}
133133

134+
pub fn tls_serialized_len_checked(v: &[u8]) -> Option<usize> {
135+
TlsByteSliceU32(v).tls_serialized_len_checked()
136+
}
137+
134138
pub fn tls_serialize<W: Write>(v: &[u8], writer: &mut W) -> Result<usize, tls_codec::Error> {
135139
TlsByteSliceU32(v).tls_serialize(writer)
136140
}

tls_codec/derive/tests/encode_bytes.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ mod custom {
107107
v.tls_serialized_len()
108108
}
109109

110+
pub fn tls_serialized_len_checked(v: &[u8]) -> Option<usize> {
111+
v.tls_serialized_len_checked()
112+
}
113+
110114
pub fn tls_serialize(v: &[u8]) -> Result<Vec<u8>, tls_codec::Error> {
111115
v.tls_serialize()
112116
}

tls_codec/src/arrays.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,8 @@ impl<const LEN: usize> Size for [u8; LEN] {
5151
fn tls_serialized_len(&self) -> usize {
5252
LEN
5353
}
54+
#[inline]
55+
fn tls_serialized_len_checked(&self) -> Option<usize> {
56+
Some(LEN)
57+
}
5458
}

tls_codec/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ mod serialize_bytes {
109109
/// memory.
110110
#[hax_lib::attributes]
111111
pub trait Size {
112+
#[hax_lib::requires(true)]
113+
fn tls_serialized_len_checked(&self) -> Option<usize>;
112114
#[hax_lib::requires(true)]
113115
fn tls_serialized_len(&self) -> usize;
114116
}

tls_codec/src/primitives.rs

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,20 @@ use std::io::{Read, Write};
1212

1313
impl<T: Size> Size for Option<T> {
1414
#[inline]
15-
fn tls_serialized_len(&self) -> usize {
16-
hax_lib::fstar!("admit ()"); // overflow
17-
1 + match self {
18-
Some(v) => v.tls_serialized_len(),
15+
fn tls_serialized_len_checked(&self) -> Option<usize> {
16+
1usize.checked_add(match self {
17+
Some(v) => v.tls_serialized_len_checked()?,
1918
None => 0,
20-
}
19+
})
20+
}
21+
#[inline]
22+
fn tls_serialized_len(&self) -> usize {
23+
1usize
24+
.checked_add(match self {
25+
Some(v) => v.tls_serialized_len(),
26+
None => 0,
27+
})
28+
.unwrap_or(0)
2129
}
2230
}
2331

@@ -26,6 +34,10 @@ impl<T: Size> Size for &Option<T> {
2634
fn tls_serialized_len(&self) -> usize {
2735
(*self).tls_serialized_len()
2836
}
37+
#[inline]
38+
fn tls_serialized_len_checked(&self) -> Option<usize> {
39+
(*self).tls_serialized_len_checked()
40+
}
2941
}
3042

3143
impl<T: Serialize> Serialize for Option<T> {
@@ -187,13 +199,21 @@ macro_rules! impl_unsigned {
187199
fn tls_serialized_len(&self) -> usize {
188200
$bytes
189201
}
202+
#[inline]
203+
fn tls_serialized_len_checked(&self) -> Option<usize> {
204+
Some($bytes)
205+
}
190206
}
191207

192208
impl Size for &$t {
193209
#[inline]
194210
fn tls_serialized_len(&self) -> usize {
195211
(*self).tls_serialized_len()
196212
}
213+
#[inline]
214+
fn tls_serialized_len_checked(&self) -> Option<usize> {
215+
(*self).tls_serialized_len_checked()
216+
}
197217
}
198218
};
199219
}
@@ -257,10 +277,18 @@ where
257277
T: Size,
258278
U: Size,
259279
{
280+
#[inline(always)]
281+
fn tls_serialized_len_checked(&self) -> Option<usize> {
282+
self.0
283+
.tls_serialized_len_checked()?
284+
.checked_add(self.1.tls_serialized_len_checked()?)
285+
}
260286
#[inline(always)]
261287
fn tls_serialized_len(&self) -> usize {
262-
hax_lib::fstar!("admit ()"); // overflow
263-
self.0.tls_serialized_len() + self.1.tls_serialized_len()
288+
self.0
289+
.tls_serialized_len()
290+
.checked_add(self.1.tls_serialized_len())
291+
.unwrap_or(0)
264292
}
265293
}
266294

@@ -322,10 +350,21 @@ where
322350
U: Size,
323351
V: Size,
324352
{
353+
#[inline(always)]
354+
fn tls_serialized_len_checked(&self) -> Option<usize> {
355+
self.0
356+
.tls_serialized_len_checked()?
357+
.checked_add(self.1.tls_serialized_len_checked()?)?
358+
.checked_add(self.2.tls_serialized_len_checked()?)
359+
}
325360
#[inline(always)]
326361
fn tls_serialized_len(&self) -> usize {
327-
hax_lib::fstar!("admit ()"); // overflow
328-
self.0.tls_serialized_len() + self.1.tls_serialized_len() + self.2.tls_serialized_len()
362+
self.0
363+
.tls_serialized_len()
364+
.checked_add(self.1.tls_serialized_len())
365+
.unwrap_or(0)
366+
.checked_add(self.2.tls_serialized_len())
367+
.unwrap_or(0)
329368
}
330369
}
331370

@@ -334,6 +373,10 @@ impl Size for () {
334373
fn tls_serialized_len(&self) -> usize {
335374
0
336375
}
376+
#[inline(always)]
377+
fn tls_serialized_len_checked(&self) -> Option<usize> {
378+
Some(0)
379+
}
337380
}
338381

339382
impl Deserialize for () {
@@ -363,6 +406,10 @@ impl<T> Size for PhantomData<T> {
363406
fn tls_serialized_len(&self) -> usize {
364407
0
365408
}
409+
#[inline(always)]
410+
fn tls_serialized_len_checked(&self) -> Option<usize> {
411+
Some(0)
412+
}
366413
}
367414

368415
impl<T> Deserialize for PhantomData<T> {
@@ -400,6 +447,10 @@ impl<T: Size> Size for Box<T> {
400447
fn tls_serialized_len(&self) -> usize {
401448
self.as_ref().tls_serialized_len()
402449
}
450+
#[inline(always)]
451+
fn tls_serialized_len_checked(&self) -> Option<usize> {
452+
self.as_ref().tls_serialized_len_checked()
453+
}
403454
}
404455

405456
impl<T: Serialize> Serialize for Box<T> {

tls_codec/src/quic_vec.rs

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,21 @@ impl<T: Size> Size for Vec<T> {
147147
fn tls_serialized_len(&self) -> usize {
148148
self.as_slice().tls_serialized_len()
149149
}
150+
#[inline(always)]
151+
fn tls_serialized_len_checked(&self) -> Option<usize> {
152+
self.as_slice().tls_serialized_len_checked()
153+
}
150154
}
151155

152156
impl<T: Size> Size for &Vec<T> {
153157
#[inline(always)]
154158
fn tls_serialized_len(&self) -> usize {
155159
(*self).tls_serialized_len()
156160
}
161+
#[inline(always)]
162+
fn tls_serialized_len_checked(&self) -> Option<usize> {
163+
(*self).tls_serialized_len_checked()
164+
}
157165
}
158166

159167
impl<T: DeserializeBytes> DeserializeBytes for Vec<T> {
@@ -225,17 +233,23 @@ impl<T: SerializeBytes> SerializeBytes for Vec<T> {
225233
}
226234
}
227235

236+
fn serialized_len_checked_slice<T: Size>(s: &[T]) -> Option<usize> {
237+
hax_lib::fstar!("admit ()"); // https://github.com/cryspen/hax/issues/1700
238+
let content_length = s.iter().fold(Some(0usize), |acc, e| {
239+
acc?.checked_add(e.tls_serialized_len_checked()?)
240+
})?;
241+
let len_len = length_encoding_bytes(content_length as u64).ok()?;
242+
content_length.checked_add(len_len)
243+
}
244+
228245
impl<T: Size> Size for &[T] {
246+
#[inline(always)]
247+
fn tls_serialized_len_checked(&self) -> Option<usize> {
248+
serialized_len_checked_slice(self)
249+
}
229250
#[inline(always)]
230251
fn tls_serialized_len(&self) -> usize {
231-
hax_lib::fstar!("admit ()"); // https://github.com/cryspen/hax/issues/1700
232-
let content_length = self.iter().fold(0, |acc, e| acc + e.tls_serialized_len());
233-
let len_len = length_encoding_bytes(content_length as u64).unwrap_or({
234-
// We can't do anything about the error unless we change the trait.
235-
// Let's say there's no content for now.
236-
0
237-
});
238-
content_length + len_len
252+
serialized_len_checked_slice(self).unwrap_or(0)
239253
}
240254
}
241255

@@ -338,19 +352,19 @@ impl From<VLBytes> for Vec<u8> {
338352
}
339353

340354
#[inline(always)]
341-
fn tls_serialize_bytes_len(bytes: &[u8]) -> usize {
355+
fn tls_serialize_bytes_len(bytes: &[u8]) -> Option<usize> {
342356
let content_length = bytes.len();
343-
let len_len = length_encoding_bytes(content_length as u64).unwrap_or({
344-
// We can't do anything about the error. Let's say there's no content.
345-
0
346-
});
347-
hax_lib::fstar!("admit ()"); // overflow
348-
content_length + len_len
357+
let len_len = length_encoding_bytes(content_length as u64).ok()?;
358+
content_length.checked_add(len_len)
349359
}
350360

351361
impl Size for VLBytes {
352362
#[inline(always)]
353363
fn tls_serialized_len(&self) -> usize {
364+
tls_serialize_bytes_len(self.as_slice()).unwrap_or(0)
365+
}
366+
#[inline(always)]
367+
fn tls_serialized_len_checked(&self) -> Option<usize> {
354368
tls_serialize_bytes_len(self.as_slice())
355369
}
356370
}
@@ -399,6 +413,10 @@ impl Size for &VLBytes {
399413
fn tls_serialized_len(&self) -> usize {
400414
(*self).tls_serialized_len()
401415
}
416+
#[inline(always)]
417+
fn tls_serialized_len_checked(&self) -> Option<usize> {
418+
(*self).tls_serialized_len_checked()
419+
}
402420
}
403421

404422
pub struct VLByteSlice<'a>(pub &'a [u8]);
@@ -423,15 +441,23 @@ impl VLByteSlice<'_> {
423441
impl Size for &VLByteSlice<'_> {
424442
#[inline]
425443
fn tls_serialized_len(&self) -> usize {
444+
tls_serialize_bytes_len(self.0).unwrap_or(0)
445+
}
446+
#[inline]
447+
fn tls_serialized_len_checked(&self) -> Option<usize> {
426448
tls_serialize_bytes_len(self.0)
427449
}
428450
}
429451

430452
impl Size for VLByteSlice<'_> {
431453
#[inline]
432-
fn tls_serialized_len(&self) -> usize {
454+
fn tls_serialized_len_checked(&self) -> Option<usize> {
433455
tls_serialize_bytes_len(self.0)
434456
}
457+
#[inline]
458+
fn tls_serialized_len(&self) -> usize {
459+
tls_serialize_bytes_len(self.0).unwrap_or(0)
460+
}
435461
}
436462

437463
#[cfg(feature = "std")]
@@ -679,6 +705,9 @@ mod secret_bytes {
679705
fn tls_serialized_len(&self) -> usize {
680706
self.0.tls_serialized_len()
681707
}
708+
fn tls_serialized_len_checked(&self) -> Option<usize> {
709+
self.0.tls_serialized_len_checked()
710+
}
682711
}
683712

684713
impl DeserializeBytes for SecretVLBytes {

0 commit comments

Comments
 (0)