/__w/smoldot/smoldot/repo/lib/src/util/leb128.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Smoldot |
2 | | // Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. |
3 | | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 |
4 | | |
5 | | // This program is free software: you can redistribute it and/or modify |
6 | | // it under the terms of the GNU General Public License as published by |
7 | | // the Free Software Foundation, either version 3 of the License, or |
8 | | // (at your option) any later version. |
9 | | |
10 | | // This program is distributed in the hope that it will be useful, |
11 | | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | // GNU General Public License for more details. |
14 | | |
15 | | // You should have received a copy of the GNU General Public License |
16 | | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | | |
18 | | //! Little Endian Base 128 |
19 | | //! |
20 | | //! The LEB128 encoding is used throughout the networking code. This module provides utilities for |
21 | | //! encoding/decoding this format. |
22 | | //! |
23 | | //! See <https://en.wikipedia.org/wiki/LEB128>. |
24 | | |
25 | | /// Returns an LEB128-encoded integer as a list of bytes. |
26 | | /// |
27 | | /// This function accepts as parameter an `Into<u64>`. As such, one can also pass a `u8`, `u16`, |
28 | | /// or `u32` for example. Use [`encode_usize`] for the `usize` equivalent. |
29 | 1.85k | pub fn encode(value: impl Into<u64>) -> impl ExactSizeIterator<Item = u8> + Clone { |
30 | 1.85k | #[derive(Clone)] |
31 | 1.85k | struct EncodeIter { |
32 | 1.85k | value: u64, |
33 | 1.85k | finished: bool, |
34 | 1.85k | } |
35 | 1.85k | |
36 | 1.85k | impl Iterator for EncodeIter { |
37 | 1.85k | type Item = u8; |
38 | 1.85k | |
39 | 6.37k | fn next(&mut self) -> Option<Self::Item> { |
40 | 6.37k | if self.finished { |
41 | 2.19k | return None; |
42 | 4.18k | } |
43 | 4.18k | |
44 | 4.18k | if self.value < (1 << 7) { |
45 | 1.97k | self.finished = true; |
46 | 1.97k | return Some(u8::try_from(self.value).unwrap()); |
47 | 2.20k | } |
48 | 2.20k | |
49 | 2.20k | let ret = (1 << 7) | u8::try_from(self.value & 0b111_1111).unwrap(); |
50 | 2.20k | self.value >>= 7; |
51 | 2.20k | Some(ret) |
52 | 6.37k | } _RNvXNvNtNtCsN16ciHI6Qf_7smoldot4util6leb1286encodeNtB2_10EncodeIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next Line | Count | Source | 39 | 4.28k | fn next(&mut self) -> Option<Self::Item> { | 40 | 4.28k | if self.finished { | 41 | 1.15k | return None; | 42 | 3.13k | } | 43 | 3.13k | | 44 | 3.13k | if self.value < (1 << 7) { | 45 | 935 | self.finished = true; | 46 | 935 | return Some(u8::try_from(self.value).unwrap()); | 47 | 2.20k | } | 48 | 2.20k | | 49 | 2.20k | let ret = (1 << 7) | u8::try_from(self.value & 0b111_1111).unwrap(); | 50 | 2.20k | self.value >>= 7; | 51 | 2.20k | Some(ret) | 52 | 4.28k | } |
_RNvXNvNtNtCseuYC0Zibziv_7smoldot4util6leb1286encodeNtB2_10EncodeIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next Line | Count | Source | 39 | 2.08k | fn next(&mut self) -> Option<Self::Item> { | 40 | 2.08k | if self.finished { | 41 | 1.04k | return None; | 42 | 1.04k | } | 43 | 1.04k | | 44 | 1.04k | if self.value < (1 << 7) { | 45 | 1.04k | self.finished = true; | 46 | 1.04k | return Some(u8::try_from(self.value).unwrap()); | 47 | 0 | } | 48 | 0 |
| 49 | 0 | let ret = (1 << 7) | u8::try_from(self.value & 0b111_1111).unwrap(); | 50 | 0 | self.value >>= 7; | 51 | 0 | Some(ret) | 52 | 2.08k | } |
|
53 | 1.85k | |
54 | 1.85k | fn size_hint(&self) -> (usize, Option<usize>) { |
55 | 345 | let len = self.clone().count(); |
56 | 345 | (len, Some(len)) |
57 | 345 | } _RNvXNvNtNtCsN16ciHI6Qf_7smoldot4util6leb1286encodeNtB2_10EncodeIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint Line | Count | Source | 54 | 345 | fn size_hint(&self) -> (usize, Option<usize>) { | 55 | 345 | let len = self.clone().count(); | 56 | 345 | (len, Some(len)) | 57 | 345 | } |
Unexecuted instantiation: _RNvXNvNtNtCseuYC0Zibziv_7smoldot4util6leb1286encodeNtB2_10EncodeIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint |
58 | 1.85k | } |
59 | 1.85k | |
60 | 1.85k | impl ExactSizeIterator for EncodeIter {} |
61 | 1.85k | |
62 | 1.85k | EncodeIter { |
63 | 1.85k | value: value.into(), |
64 | 1.85k | finished: false, |
65 | 1.85k | } |
66 | 1.85k | } _RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb1286encodeyEB6_ Line | Count | Source | 29 | 778 | pub fn encode(value: impl Into<u64>) -> impl ExactSizeIterator<Item = u8> + Clone { | 30 | 778 | #[derive(Clone)] | 31 | 778 | struct EncodeIter { | 32 | 778 | value: u64, | 33 | 778 | finished: bool, | 34 | 778 | } | 35 | 778 | | 36 | 778 | impl Iterator for EncodeIter { | 37 | 778 | type Item = u8; | 38 | 778 | | 39 | 778 | fn next(&mut self) -> Option<Self::Item> { | 40 | 778 | if self.finished { | 41 | 778 | return None; | 42 | 778 | } | 43 | 778 | | 44 | 778 | if self.value < (1 << 7) { | 45 | 778 | self.finished = true; | 46 | 778 | return Some(u8::try_from(self.value).unwrap()); | 47 | 778 | } | 48 | 778 | | 49 | 778 | let ret = (1 << 7) | u8::try_from(self.value & 0b111_1111).unwrap(); | 50 | 778 | self.value >>= 7; | 51 | 778 | Some(ret) | 52 | 778 | } | 53 | 778 | | 54 | 778 | fn size_hint(&self) -> (usize, Option<usize>) { | 55 | 778 | let len = self.clone().count(); | 56 | 778 | (len, Some(len)) | 57 | 778 | } | 58 | 778 | } | 59 | 778 | | 60 | 778 | impl ExactSizeIterator for EncodeIter {} | 61 | 778 | | 62 | 778 | EncodeIter { | 63 | 778 | value: value.into(), | 64 | 778 | finished: false, | 65 | 778 | } | 66 | 778 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb1286encodemEB6_ Line | Count | Source | 29 | 28 | pub fn encode(value: impl Into<u64>) -> impl ExactSizeIterator<Item = u8> + Clone { | 30 | 28 | #[derive(Clone)] | 31 | 28 | struct EncodeIter { | 32 | 28 | value: u64, | 33 | 28 | finished: bool, | 34 | 28 | } | 35 | 28 | | 36 | 28 | impl Iterator for EncodeIter { | 37 | 28 | type Item = u8; | 38 | 28 | | 39 | 28 | fn next(&mut self) -> Option<Self::Item> { | 40 | 28 | if self.finished { | 41 | 28 | return None; | 42 | 28 | } | 43 | 28 | | 44 | 28 | if self.value < (1 << 7) { | 45 | 28 | self.finished = true; | 46 | 28 | return Some(u8::try_from(self.value).unwrap()); | 47 | 28 | } | 48 | 28 | | 49 | 28 | let ret = (1 << 7) | u8::try_from(self.value & 0b111_1111).unwrap(); | 50 | 28 | self.value >>= 7; | 51 | 28 | Some(ret) | 52 | 28 | } | 53 | 28 | | 54 | 28 | fn size_hint(&self) -> (usize, Option<usize>) { | 55 | 28 | let len = self.clone().count(); | 56 | 28 | (len, Some(len)) | 57 | 28 | } | 58 | 28 | } | 59 | 28 | | 60 | 28 | impl ExactSizeIterator for EncodeIter {} | 61 | 28 | | 62 | 28 | EncodeIter { | 63 | 28 | value: value.into(), | 64 | 28 | finished: false, | 65 | 28 | } | 66 | 28 | } |
Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb1286encodeyECsDDUKWWCHAU_18smoldot_light_wasm _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb1286encodeyEB6_ Line | Count | Source | 29 | 898 | pub fn encode(value: impl Into<u64>) -> impl ExactSizeIterator<Item = u8> + Clone { | 30 | 898 | #[derive(Clone)] | 31 | 898 | struct EncodeIter { | 32 | 898 | value: u64, | 33 | 898 | finished: bool, | 34 | 898 | } | 35 | 898 | | 36 | 898 | impl Iterator for EncodeIter { | 37 | 898 | type Item = u8; | 38 | 898 | | 39 | 898 | fn next(&mut self) -> Option<Self::Item> { | 40 | 898 | if self.finished { | 41 | 898 | return None; | 42 | 898 | } | 43 | 898 | | 44 | 898 | if self.value < (1 << 7) { | 45 | 898 | self.finished = true; | 46 | 898 | return Some(u8::try_from(self.value).unwrap()); | 47 | 898 | } | 48 | 898 | | 49 | 898 | let ret = (1 << 7) | u8::try_from(self.value & 0b111_1111).unwrap(); | 50 | 898 | self.value >>= 7; | 51 | 898 | Some(ret) | 52 | 898 | } | 53 | 898 | | 54 | 898 | fn size_hint(&self) -> (usize, Option<usize>) { | 55 | 898 | let len = self.clone().count(); | 56 | 898 | (len, Some(len)) | 57 | 898 | } | 58 | 898 | } | 59 | 898 | | 60 | 898 | impl ExactSizeIterator for EncodeIter {} | 61 | 898 | | 62 | 898 | EncodeIter { | 63 | 898 | value: value.into(), | 64 | 898 | finished: false, | 65 | 898 | } | 66 | 898 | } |
_RINvNtNtCseuYC0Zibziv_7smoldot4util6leb1286encodemEB6_ Line | Count | Source | 29 | 146 | pub fn encode(value: impl Into<u64>) -> impl ExactSizeIterator<Item = u8> + Clone { | 30 | 146 | #[derive(Clone)] | 31 | 146 | struct EncodeIter { | 32 | 146 | value: u64, | 33 | 146 | finished: bool, | 34 | 146 | } | 35 | 146 | | 36 | 146 | impl Iterator for EncodeIter { | 37 | 146 | type Item = u8; | 38 | 146 | | 39 | 146 | fn next(&mut self) -> Option<Self::Item> { | 40 | 146 | if self.finished { | 41 | 146 | return None; | 42 | 146 | } | 43 | 146 | | 44 | 146 | if self.value < (1 << 7) { | 45 | 146 | self.finished = true; | 46 | 146 | return Some(u8::try_from(self.value).unwrap()); | 47 | 146 | } | 48 | 146 | | 49 | 146 | let ret = (1 << 7) | u8::try_from(self.value & 0b111_1111).unwrap(); | 50 | 146 | self.value >>= 7; | 51 | 146 | Some(ret) | 52 | 146 | } | 53 | 146 | | 54 | 146 | fn size_hint(&self) -> (usize, Option<usize>) { | 55 | 146 | let len = self.clone().count(); | 56 | 146 | (len, Some(len)) | 57 | 146 | } | 58 | 146 | } | 59 | 146 | | 60 | 146 | impl ExactSizeIterator for EncodeIter {} | 61 | 146 | | 62 | 146 | EncodeIter { | 63 | 146 | value: value.into(), | 64 | 146 | finished: false, | 65 | 146 | } | 66 | 146 | } |
Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb1286encodeyECsiUjFBJteJ7x_17smoldot_full_node |
67 | | |
68 | | /// Returns an LEB128-encoded `usize` as a list of bytes. |
69 | | /// |
70 | | /// See also [`encode`]. |
71 | 788 | pub fn encode_usize(value: usize) -> impl ExactSizeIterator<Item = u8> + Clone { |
72 | 788 | // `encode_usize` can leverage `encode` thanks to the property checked in this debug_assert. |
73 | 788 | #[cfg(not(any( |
74 | 788 | target_pointer_width = "16", |
75 | 788 | target_pointer_width = "32", |
76 | 788 | target_pointer_width = "64" |
77 | 788 | )))] |
78 | 788 | compile_error!("usize must be <= u64"); |
79 | 788 | encode(u64::try_from(value).unwrap()) |
80 | 788 | } _RNvNtNtCsN16ciHI6Qf_7smoldot4util6leb12812encode_usize Line | Count | Source | 71 | 433 | pub fn encode_usize(value: usize) -> impl ExactSizeIterator<Item = u8> + Clone { | 72 | 433 | // `encode_usize` can leverage `encode` thanks to the property checked in this debug_assert. | 73 | 433 | #[cfg(not(any( | 74 | 433 | target_pointer_width = "16", | 75 | 433 | target_pointer_width = "32", | 76 | 433 | target_pointer_width = "64" | 77 | 433 | )))] | 78 | 433 | compile_error!("usize must be <= u64"); | 79 | 433 | encode(u64::try_from(value).unwrap()) | 80 | 433 | } |
_RNvNtNtCseuYC0Zibziv_7smoldot4util6leb12812encode_usize Line | Count | Source | 71 | 355 | pub fn encode_usize(value: usize) -> impl ExactSizeIterator<Item = u8> + Clone { | 72 | 355 | // `encode_usize` can leverage `encode` thanks to the property checked in this debug_assert. | 73 | 355 | #[cfg(not(any( | 74 | 355 | target_pointer_width = "16", | 75 | 355 | target_pointer_width = "32", | 76 | 355 | target_pointer_width = "64" | 77 | 355 | )))] | 78 | 355 | compile_error!("usize must be <= u64"); | 79 | 355 | encode(u64::try_from(value).unwrap()) | 80 | 355 | } |
|
81 | | |
82 | | /// Decodes a LEB128-encoded `usize`. |
83 | | /// |
84 | | /// > **Note**: When using this function outside of a `nom` "context", you might have to explicit |
85 | | /// > the type of `E`. Use `nom::error::Error<&[u8]>`. |
86 | 582 | pub(crate) fn nom_leb128_usize<'a, E: nom::error::ParseError<&'a [u8]>>( |
87 | 582 | bytes: &'a [u8], |
88 | 582 | ) -> nom::IResult<&'a [u8], usize, E> { |
89 | | // `nom_leb128_usize` can leverage `nom_leb128_u64` thanks to the property checked in this |
90 | | // debug_assert. |
91 | | #[cfg(not(any( |
92 | | target_pointer_width = "16", |
93 | | target_pointer_width = "32", |
94 | | target_pointer_width = "64" |
95 | | )))] |
96 | | compile_error!("usize must be <= u64"); |
97 | 582 | let (rest, value370 ) = nom_leb128_u64(bytes)?212 ; |
98 | | |
99 | 370 | let value = match usize::try_from(value) { |
100 | 370 | Ok(v) => v, |
101 | | Err(_) => { |
102 | 0 | return Err(nom::Err::Error(nom::error::make_error( |
103 | 0 | bytes, |
104 | 0 | nom::error::ErrorKind::LengthValue, |
105 | 0 | ))); |
106 | | } |
107 | | }; |
108 | | |
109 | 370 | Ok((rest, value)) |
110 | 582 | } _RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB6_ Line | Count | Source | 86 | 507 | pub(crate) fn nom_leb128_usize<'a, E: nom::error::ParseError<&'a [u8]>>( | 87 | 507 | bytes: &'a [u8], | 88 | 507 | ) -> nom::IResult<&'a [u8], usize, E> { | 89 | | // `nom_leb128_usize` can leverage `nom_leb128_u64` thanks to the property checked in this | 90 | | // debug_assert. | 91 | | #[cfg(not(any( | 92 | | target_pointer_width = "16", | 93 | | target_pointer_width = "32", | 94 | | target_pointer_width = "64" | 95 | | )))] | 96 | | compile_error!("usize must be <= u64"); | 97 | 507 | let (rest, value295 ) = nom_leb128_u64(bytes)?212 ; | 98 | | | 99 | 295 | let value = match usize::try_from(value) { | 100 | 295 | Ok(v) => v, | 101 | | Err(_) => { | 102 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 103 | 0 | bytes, | 104 | 0 | nom::error::ErrorKind::LengthValue, | 105 | 0 | ))); | 106 | | } | 107 | | }; | 108 | | | 109 | 295 | Ok((rest, value)) | 110 | 507 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb12816nom_leb128_usizeNtNvMNtNtB6_6libp2p7peer_idNtB10_9PublicKey22from_protobuf_encoding12ErrorWrapperEB6_ Line | Count | Source | 86 | 27 | pub(crate) fn nom_leb128_usize<'a, E: nom::error::ParseError<&'a [u8]>>( | 87 | 27 | bytes: &'a [u8], | 88 | 27 | ) -> nom::IResult<&'a [u8], usize, E> { | 89 | | // `nom_leb128_usize` can leverage `nom_leb128_u64` thanks to the property checked in this | 90 | | // debug_assert. | 91 | | #[cfg(not(any( | 92 | | target_pointer_width = "16", | 93 | | target_pointer_width = "32", | 94 | | target_pointer_width = "64" | 95 | | )))] | 96 | | compile_error!("usize must be <= u64"); | 97 | 27 | let (rest, value) = nom_leb128_u64(bytes)?0 ; | 98 | | | 99 | 27 | let value = match usize::try_from(value) { | 100 | 27 | Ok(v) => v, | 101 | | Err(_) => { | 102 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 103 | 0 | bytes, | 104 | 0 | nom::error::ErrorKind::LengthValue, | 105 | 0 | ))); | 106 | | } | 107 | | }; | 108 | | | 109 | 27 | Ok((rest, value)) | 110 | 27 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb12816nom_leb128_usizeTRShNtNtCs6ga8gEqbpRc_3nom5error9ErrorKindEEB6_ Line | Count | Source | 86 | 48 | pub(crate) fn nom_leb128_usize<'a, E: nom::error::ParseError<&'a [u8]>>( | 87 | 48 | bytes: &'a [u8], | 88 | 48 | ) -> nom::IResult<&'a [u8], usize, E> { | 89 | | // `nom_leb128_usize` can leverage `nom_leb128_u64` thanks to the property checked in this | 90 | | // debug_assert. | 91 | | #[cfg(not(any( | 92 | | target_pointer_width = "16", | 93 | | target_pointer_width = "32", | 94 | | target_pointer_width = "64" | 95 | | )))] | 96 | | compile_error!("usize must be <= u64"); | 97 | 48 | let (rest, value) = nom_leb128_u64(bytes)?0 ; | 98 | | | 99 | 48 | let value = match usize::try_from(value) { | 100 | 48 | Ok(v) => v, | 101 | | Err(_) => { | 102 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 103 | 0 | bytes, | 104 | 0 | nom::error::ErrorKind::LengthValue, | 105 | 0 | ))); | 106 | | } | 107 | | }; | 108 | | | 109 | 48 | Ok((rest, value)) | 110 | 48 | } |
Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeTRShNtNtCs6ga8gEqbpRc_3nom5error9ErrorKindEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsih6EgvAwZF2_13smoldot_light Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB6_ Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeNtNvMNtNtB6_6libp2p7peer_idNtB11_9PublicKey22from_protobuf_encoding12ErrorWrapperEB6_ Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsiUjFBJteJ7x_17smoldot_full_node Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeTRShNtNtCs6ga8gEqbpRc_3nom5error9ErrorKindEECsiUjFBJteJ7x_17smoldot_full_node Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12816nom_leb128_usizeINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsibGXYHQB8Ea_25json_rpc_general_requests |
111 | | |
112 | | /// Decodes a LEB128-encoded `u64`. |
113 | | /// |
114 | | /// > **Note**: When using this function outside of a `nom` "context", you might have to explicit |
115 | | /// > the type of `E`. Use `nom::error::Error<&[u8]>`. |
116 | 3.08k | pub(crate) fn nom_leb128_u64<'a, E: nom::error::ParseError<&'a [u8]>>( |
117 | 3.08k | bytes: &'a [u8], |
118 | 3.08k | ) -> nom::IResult<&'a [u8], u64, E> { |
119 | 3.08k | let mut out = 0u64; |
120 | | |
121 | 4.11k | for (n, byte) in bytes.iter().enumerate()3.08k { |
122 | 4.11k | if (7 * n) >= usize::try_from(u64::BITS).unwrap() { |
123 | 2 | return Err(nom::Err::Error(nom::error::make_error( |
124 | 2 | bytes, |
125 | 2 | nom::error::ErrorKind::LengthValue, |
126 | 2 | ))); |
127 | 4.11k | } |
128 | 4.11k | |
129 | 4.11k | match u64::from(*byte & 0b111_1111).checked_mul(1 << (7 * n)) { |
130 | 4.11k | Some(o) => out |= o, |
131 | | None => { |
132 | 0 | return Err(nom::Err::Error(nom::error::make_error( |
133 | 0 | bytes, |
134 | 0 | nom::error::ErrorKind::LengthValue, |
135 | 0 | ))) |
136 | | } |
137 | | }; |
138 | | |
139 | 4.11k | if (*byte & 0x80) == 0 { |
140 | | // We want to avoid LEB128 numbers such as `[0x81, 0x0]`. |
141 | 2.86k | if n >= 1 && *byte == 0x0919 { |
142 | 0 | return Err(nom::Err::Error(nom::error::make_error( |
143 | 0 | bytes, |
144 | 0 | nom::error::ErrorKind::Verify, |
145 | 0 | ))); |
146 | 2.86k | } |
147 | 2.86k | |
148 | 2.86k | return Ok((&bytes[(n + 1)..], out)); |
149 | 1.24k | } |
150 | | } |
151 | | |
152 | 211 | Err(nom::Err::Incomplete(nom::Needed::Unknown)) |
153 | 3.08k | } _RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB6_ Line | Count | Source | 116 | 1.31k | pub(crate) fn nom_leb128_u64<'a, E: nom::error::ParseError<&'a [u8]>>( | 117 | 1.31k | bytes: &'a [u8], | 118 | 1.31k | ) -> nom::IResult<&'a [u8], u64, E> { | 119 | 1.31k | let mut out = 0u64; | 120 | | | 121 | 1.31k | for (n, byte) in bytes.iter().enumerate()1.31k { | 122 | 1.31k | if (7 * n) >= usize::try_from(u64::BITS).unwrap() { | 123 | 2 | return Err(nom::Err::Error(nom::error::make_error( | 124 | 2 | bytes, | 125 | 2 | nom::error::ErrorKind::LengthValue, | 126 | 2 | ))); | 127 | 1.31k | } | 128 | 1.31k | | 129 | 1.31k | match u64::from(*byte & 0b111_1111).checked_mul(1 << (7 * n)) { | 130 | 1.31k | Some(o) => out |= o, | 131 | | None => { | 132 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 133 | 0 | bytes, | 134 | 0 | nom::error::ErrorKind::LengthValue, | 135 | 0 | ))) | 136 | | } | 137 | | }; | 138 | | | 139 | 1.31k | if (*byte & 0x80) == 0 { | 140 | | // We want to avoid LEB128 numbers such as `[0x81, 0x0]`. | 141 | 1.10k | if n >= 1 && *byte == 0x0145 { | 142 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 143 | 0 | bytes, | 144 | 0 | nom::error::ErrorKind::Verify, | 145 | 0 | ))); | 146 | 1.10k | } | 147 | 1.10k | | 148 | 1.10k | return Ok((&bytes[(n + 1)..], out)); | 149 | 217 | } | 150 | | } | 151 | | | 152 | 211 | Err(nom::Err::Incomplete(nom::Needed::Unknown)) | 153 | 1.31k | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb12814nom_leb128_u64NtNvMNtNtB6_6libp2p7peer_idNtBY_9PublicKey22from_protobuf_encoding12ErrorWrapperEB6_ Line | Count | Source | 116 | 162 | pub(crate) fn nom_leb128_u64<'a, E: nom::error::ParseError<&'a [u8]>>( | 117 | 162 | bytes: &'a [u8], | 118 | 162 | ) -> nom::IResult<&'a [u8], u64, E> { | 119 | 162 | let mut out = 0u64; | 120 | | | 121 | 162 | for (n, byte) in bytes.iter().enumerate() { | 122 | 162 | if (7 * n) >= usize::try_from(u64::BITS).unwrap() { | 123 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 124 | 0 | bytes, | 125 | 0 | nom::error::ErrorKind::LengthValue, | 126 | 0 | ))); | 127 | 162 | } | 128 | 162 | | 129 | 162 | match u64::from(*byte & 0b111_1111).checked_mul(1 << (7 * n)) { | 130 | 162 | Some(o) => out |= o, | 131 | | None => { | 132 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 133 | 0 | bytes, | 134 | 0 | nom::error::ErrorKind::LengthValue, | 135 | 0 | ))) | 136 | | } | 137 | | }; | 138 | | | 139 | 162 | if (*byte & 0x80) == 0 { | 140 | | // We want to avoid LEB128 numbers such as `[0x81, 0x0]`. | 141 | 162 | if n >= 1 && *byte == 0x00 { | 142 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 143 | 0 | bytes, | 144 | 0 | nom::error::ErrorKind::Verify, | 145 | 0 | ))); | 146 | 162 | } | 147 | 162 | | 148 | 162 | return Ok((&bytes[(n + 1)..], out)); | 149 | 0 | } | 150 | | } | 151 | | | 152 | 0 | Err(nom::Err::Incomplete(nom::Needed::Unknown)) | 153 | 162 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4util6leb12814nom_leb128_u64TRShNtNtCs6ga8gEqbpRc_3nom5error9ErrorKindEEB6_ Line | Count | Source | 116 | 144 | pub(crate) fn nom_leb128_u64<'a, E: nom::error::ParseError<&'a [u8]>>( | 117 | 144 | bytes: &'a [u8], | 118 | 144 | ) -> nom::IResult<&'a [u8], u64, E> { | 119 | 144 | let mut out = 0u64; | 120 | | | 121 | 144 | for (n, byte) in bytes.iter().enumerate() { | 122 | 144 | if (7 * n) >= usize::try_from(u64::BITS).unwrap() { | 123 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 124 | 0 | bytes, | 125 | 0 | nom::error::ErrorKind::LengthValue, | 126 | 0 | ))); | 127 | 144 | } | 128 | 144 | | 129 | 144 | match u64::from(*byte & 0b111_1111).checked_mul(1 << (7 * n)) { | 130 | 144 | Some(o) => out |= o, | 131 | | None => { | 132 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 133 | 0 | bytes, | 134 | 0 | nom::error::ErrorKind::LengthValue, | 135 | 0 | ))) | 136 | | } | 137 | | }; | 138 | | | 139 | 144 | if (*byte & 0x80) == 0 { | 140 | | // We want to avoid LEB128 numbers such as `[0x81, 0x0]`. | 141 | 144 | if n >= 1 && *byte == 0x00 { | 142 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 143 | 0 | bytes, | 144 | 0 | nom::error::ErrorKind::Verify, | 145 | 0 | ))); | 146 | 144 | } | 147 | 144 | | 148 | 144 | return Ok((&bytes[(n + 1)..], out)); | 149 | 0 | } | 150 | | } | 151 | | | 152 | 0 | Err(nom::Err::Incomplete(nom::Needed::Unknown)) | 153 | 144 | } |
Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64TRShNtNtCs6ga8gEqbpRc_3nom5error9ErrorKindEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsih6EgvAwZF2_13smoldot_light _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB6_ Line | Count | Source | 116 | 1.46k | pub(crate) fn nom_leb128_u64<'a, E: nom::error::ParseError<&'a [u8]>>( | 117 | 1.46k | bytes: &'a [u8], | 118 | 1.46k | ) -> nom::IResult<&'a [u8], u64, E> { | 119 | 1.46k | let mut out = 0u64; | 120 | | | 121 | 2.49k | for (n, byte) in bytes.iter().enumerate()1.46k { | 122 | 2.49k | if (7 * n) >= usize::try_from(u64::BITS).unwrap() { | 123 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 124 | 0 | bytes, | 125 | 0 | nom::error::ErrorKind::LengthValue, | 126 | 0 | ))); | 127 | 2.49k | } | 128 | 2.49k | | 129 | 2.49k | match u64::from(*byte & 0b111_1111).checked_mul(1 << (7 * n)) { | 130 | 2.49k | Some(o) => out |= o, | 131 | | None => { | 132 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 133 | 0 | bytes, | 134 | 0 | nom::error::ErrorKind::LengthValue, | 135 | 0 | ))) | 136 | | } | 137 | | }; | 138 | | | 139 | 2.49k | if (*byte & 0x80) == 0 { | 140 | | // We want to avoid LEB128 numbers such as `[0x81, 0x0]`. | 141 | 1.46k | if n >= 1 && *byte == 0x0774 { | 142 | 0 | return Err(nom::Err::Error(nom::error::make_error( | 143 | 0 | bytes, | 144 | 0 | nom::error::ErrorKind::Verify, | 145 | 0 | ))); | 146 | 1.46k | } | 147 | 1.46k | | 148 | 1.46k | return Ok((&bytes[(n + 1)..], out)); | 149 | 1.03k | } | 150 | | } | 151 | | | 152 | 0 | Err(nom::Err::Incomplete(nom::Needed::Unknown)) | 153 | 1.46k | } |
Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64NtNvMNtNtB6_6libp2p7peer_idNtBZ_9PublicKey22from_protobuf_encoding12ErrorWrapperEB6_ Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsiUjFBJteJ7x_17smoldot_full_node Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64TRShNtNtCs6ga8gEqbpRc_3nom5error9ErrorKindEECsiUjFBJteJ7x_17smoldot_full_node Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4util6leb12814nom_leb128_u64INtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEECsibGXYHQB8Ea_25json_rpc_general_requests |
154 | | |
155 | | #[cfg(test)] |
156 | | mod tests { |
157 | | #[test] |
158 | 1 | fn basic_encode() { |
159 | 1 | let obtained = super::encode(0x123_4567_89ab_cdef_u64).collect::<Vec<_>>(); |
160 | 1 | assert_eq!(obtained, &[239, 155, 175, 205, 248, 172, 209, 145, 1]); |
161 | 1 | } |
162 | | |
163 | | #[test] |
164 | 1 | fn encode_zero() { |
165 | 1 | let obtained = super::encode(0u64).collect::<Vec<_>>(); |
166 | 1 | assert_eq!(obtained, &[0x0u8]); |
167 | 1 | } |
168 | | |
169 | | #[test] |
170 | 1 | fn exact_size_iterator() { |
171 | 129 | for _ in 0..128 { |
172 | 128 | let iter = super::encode(rand::random::<u64>()); |
173 | 128 | let expected = iter.len(); |
174 | 128 | let obtained = iter.count(); |
175 | 128 | assert_eq!(expected, obtained); |
176 | | } |
177 | 1 | } |
178 | | |
179 | | #[test] |
180 | 1 | fn decode_large_value() { |
181 | 1 | // Carefully crafted LEB128 that overflows the left shift before overflowing the |
182 | 1 | // encoded size. |
183 | 256 | let encoded = (0..256).map(|_| 129).collect::<Vec<_>>(); |
184 | 1 | assert!(super::nom_leb128_usize::<nom::error::Error<&[u8]>>(&encoded).is_err()); |
185 | 1 | } |
186 | | |
187 | | // TODO: more tests |
188 | | } |