1use crate::*;
2
3use ruint_1::Uint;
4
5impl<const BITS: usize, const LBITS: usize> Varint for Uint<BITS, LBITS> {
6 const MIN_ENCODED_LEN: usize = const {
7 if BITS == 0 {
8 0
9 } else {
10 1
11 }
12 };
13 const MAX_ENCODED_LEN: usize = BITS.div_ceil(7);
14
15 fn encoded_len(&self) -> usize {
16 match BITS {
17 0 => 0,
18 1..=8 => encoded_u8_varint_len(self.to()),
19 9..=16 => encoded_u16_varint_len(self.to()),
20 17..=32 => encoded_u32_varint_len(self.to()),
21 33..=64 => encoded_u64_varint_len(self.to()),
22 65..=128 => encoded_u128_varint_len(self.to()),
23 _ => {
24 if self.is_zero() {
27 return 1;
28 }
29
30 let highest_bit = BITS - self.leading_zeros();
32 highest_bit.div_ceil(7)
35 }
36 }
37 }
38
39 fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
40 match BITS {
41 0 => Ok(0),
42 1..=8 => encode_u8_varint_to(self.to(), buf),
43 9..=16 => encode_u16_varint_to(self.to(), buf),
44 17..=32 => encode_u32_varint_to(self.to(), buf),
45 33..=64 => encode_u64_varint_to(self.to(), buf),
46 65..=128 => encode_u128_varint_to(self.to(), buf),
47 _ => {
48 let len = self.encoded_len();
49 let buf_len = buf.len();
50 if buf_len < len {
51 return Err(EncodeError::underflow(len, buf_len));
52 }
53
54 let mut value = *self;
55 let mut bytes_written = 0;
56
57 loop {
58 let mut byte = (value & Uint::from(0x7f)).to::<u8>();
59 value >>= 7;
60
61 if !value.is_zero() {
63 byte |= 0x80;
64 }
65
66 buf[bytes_written] = byte;
67 bytes_written += 1;
68
69 if value.is_zero() {
70 break;
71 }
72 }
73
74 Ok(bytes_written)
75 }
76 }
77 }
78
79 fn decode(buf: &[u8]) -> Result<(usize, Self), DecodeError>
80 where
81 Self: Sized,
82 {
83 if BITS == 0 {
84 return Ok((0, Self::ZERO));
85 }
86
87 if buf.is_empty() {
88 return Err(DecodeError::Underflow);
89 }
90
91 let mut result = Self::ZERO;
92 let mut shift = 0;
93 let mut bytes_read = 0;
94
95 while bytes_read < buf.len() {
96 let byte = buf[bytes_read];
97 let value = Self::from(byte & 0x7f);
99
100 if shift >= BITS {
102 return Err(DecodeError::Overflow);
103 }
104
105 if let Some(shifted) = value.checked_shl(shift) {
108 result |= shifted;
109 } else {
110 return Err(DecodeError::Overflow);
111 }
112
113 bytes_read += 1;
114
115 if byte & 0x80 == 0 {
117 return Ok((bytes_read, result));
118 }
119
120 shift += 7;
121 }
122
123 Err(DecodeError::Underflow)
125 }
126}
127
128#[cfg(test)]
129mod tests_ruint_1 {
130 use super::*;
131
132 use ruint_1::aliases::{
133 U0, U1, U1024, U128, U16, U2048, U256, U32, U320, U384, U4096, U448, U512, U64, U768,
134 };
135
136 use quickcheck_macros::quickcheck;
137
138 macro_rules! fuzzy {
139 ($($ty:ident), +$(,)?) => {
140 $(
141 paste::paste! {
142 #[quickcheck]
143 fn [< fuzzy_ $ty:snake >](value: $ty) -> bool {
144 let mut buf = [0; <$ty>::MAX_ENCODED_LEN];
145 let Ok(encoded_len) = value.encode(&mut buf) else { return false; };
146 if encoded_len != value.encoded_len() || !(value.encoded_len() <= <$ty>::MAX_ENCODED_LEN) {
147 return false;
148 }
149
150 let Ok(consumed) = crate::consume_varint(&buf) else {
151 return false;
152 };
153 if consumed != encoded_len {
154 return false;
155 }
156
157 if let Ok((bytes_read, decoded)) = <$ty>::decode(&buf) {
158 value == decoded && encoded_len == bytes_read
159 } else {
160 false
161 }
162 }
163 }
164 )*
165 };
166 }
167
168 fuzzy!(U0, U1, U16, U32, U64, U128, U256, U320, U384, U448, U512, U768, U1024, U2048, U4096);
169
170 macro_rules! max_encoded_len {
171 ($($ty:ident), +$(,)?) => {
172 $(
173 paste::paste! {
174 #[test]
175 fn [< test_ $ty:snake _min_max_encoded_len>]() {
176 let max = $ty::MAX;
177 let min = $ty::MIN;
178 assert_eq!(max.encoded_len(), $ty::MAX_ENCODED_LEN);
179 assert_eq!(min.encoded_len(), $ty::MIN_ENCODED_LEN);
180 }
181 }
182 )*
183 };
184 }
185
186 max_encoded_len!(
187 U0, U1, U16, U32, U64, U128, U256, U320, U384, U448, U512, U768, U1024, U2048, U4096
188 );
189
190 #[cfg(feature = "std")]
191 mod with_std {
192 extern crate std;
193
194 use super::*;
195
196 use std::{vec, vec::Vec};
197
198 #[derive(Debug, Clone)]
200 struct ByteArray<const N: usize>([u8; N]);
201
202 impl<const N: usize> quickcheck::Arbitrary for ByteArray<N> {
203 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
204 let mut arr = [0u8; N];
205 for b in arr.iter_mut() {
206 *b = u8::arbitrary(g);
207 }
208 ByteArray(arr)
209 }
210 }
211
212 #[quickcheck]
214 fn fuzzy_u256_buffer_underflow(bytes: ByteArray<32>, short_len: usize) -> bool {
215 let uint = Uint::<256, 4>::from_be_bytes(bytes.0);
216 let short_len = short_len % (Uint::<256, 4>::MAX_ENCODED_LEN - 1);
217 if short_len >= uint.encoded_len() {
218 return true;
219 }
220 let mut short_buffer = vec![0u8; short_len];
221 matches!(
222 uint.encode(&mut short_buffer),
223 Err(EncodeError::Underflow { .. })
224 )
225 }
226
227 #[quickcheck]
228 fn fuzzy_u512_buffer_underflow(bytes: ByteArray<64>, short_len: usize) -> bool {
229 let uint = Uint::<512, 8>::from_be_bytes(bytes.0);
230 let short_len = short_len % (Uint::<512, 8>::MAX_ENCODED_LEN - 1);
231 if short_len >= uint.encoded_len() {
232 return true;
233 }
234 let mut short_buffer = vec![0u8; short_len];
235 matches!(
236 uint.encode(&mut short_buffer),
237 Err(EncodeError::Underflow { .. })
238 )
239 }
240
241 #[test]
242 fn t() {
243 std::println!("{} {}", U0::MAX, U0::MAX_ENCODED_LEN);
244 }
245
246 #[quickcheck]
247 fn fuzzy_invalid_sequences(bytes: Vec<u8>) -> bool {
248 if bytes.is_empty() {
249 return matches!(U256::decode(&bytes), Err(DecodeError::Underflow));
250 }
251
252 if bytes.len() > 10 {
254 return true;
255 }
256
257 if bytes.iter().all(|b| b & 0x80 != 0) {
259 return matches!(U256::decode(&bytes), Err(DecodeError::Underflow));
260 }
261
262 match U256::decode(&bytes) {
264 Ok(_) => true,
265 Err(_) => true,
266 }
267 }
268 }
269}