1
- use crate :: instrumentation_profile:: types:: * ;
1
+ use crate :: instrumentation_profile:: { types:: * , ParseResult } ;
2
2
use indexmap:: IndexMap ;
3
- use nom:: { number:: complete:: * , IResult } ;
3
+ use nom:: {
4
+ error:: { ErrorKind , ParseError , VerboseError , VerboseErrorKind } ,
5
+ number:: complete:: * ,
6
+ } ;
4
7
use std:: borrow:: Cow ;
5
8
6
9
#[ derive( Copy , Clone , Debug ) ]
@@ -12,26 +15,43 @@ struct KeyDataLen {
12
15
#[ derive( Clone , Debug ) ]
13
16
pub ( crate ) struct HashTable ( pub IndexMap < ( u64 , String ) , InstrProfRecord > ) ;
14
17
15
- fn read_key_data_len ( input : & [ u8 ] ) -> IResult < & [ u8 ] , KeyDataLen > {
18
+ fn read_key_data_len ( input : & [ u8 ] ) -> ParseResult < KeyDataLen > {
16
19
let ( bytes, key_len) = le_u64 ( input) ?;
17
20
let ( bytes, data_len) = le_u64 ( bytes) ?;
18
21
let res = KeyDataLen { key_len, data_len } ;
19
22
Ok ( ( bytes, res) )
20
23
}
21
24
22
- fn read_key ( input : & [ u8 ] , key_len : usize ) -> IResult < & [ u8 ] , Cow < ' _ , str > > {
23
- let res = String :: from_utf8_lossy ( & input[ ..key_len] ) ;
24
- Ok ( ( & input[ key_len..] , res) )
25
+ fn read_key ( input : & [ u8 ] , key_len : usize ) -> ParseResult < Cow < ' _ , str > > {
26
+ if key_len > input. len ( ) {
27
+ Err ( nom:: Err :: Failure ( VerboseError :: from_error_kind (
28
+ & input[ input. len ( ) ..] ,
29
+ ErrorKind :: Eof ,
30
+ ) ) )
31
+ } else {
32
+ let res = String :: from_utf8_lossy ( & input[ ..key_len] ) ;
33
+ Ok ( ( & input[ key_len..] , res) )
34
+ }
25
35
}
26
36
27
37
fn read_value (
28
38
version : u64 ,
29
39
mut input : & [ u8 ] ,
30
40
data_len : usize ,
31
- ) -> IResult < & [ u8 ] , ( u64 , InstrProfRecord ) > {
41
+ ) -> ParseResult < ( u64 , InstrProfRecord ) > {
32
42
if data_len % 8 != 0 {
33
43
// Element is corrupted, it should be aligned
34
- todo ! ( ) ;
44
+ let errors = vec ! [ (
45
+ input,
46
+ VerboseErrorKind :: Context ( "table data length is not 8 byte aligned" ) ,
47
+ ) ] ;
48
+ return Err ( nom:: Err :: Failure ( VerboseError { errors } ) ) ;
49
+ }
50
+ if input. len ( ) < data_len {
51
+ return Err ( nom:: Err :: Failure ( VerboseError :: from_error_kind (
52
+ & input[ input. len ( ) ..] ,
53
+ ErrorKind :: Eof ,
54
+ ) ) ) ;
35
55
}
36
56
let mut result = vec ! [ ] ;
37
57
let end_len = input. len ( ) - data_len;
@@ -102,12 +122,12 @@ impl HashTable {
102
122
/// buckets is the data the hash table buckets start at - the start of the `HashTable` in memory.
103
123
/// hash. offset shows the offset from the base address to the start of the `HashTable` as this
104
124
/// will be used to correct any offsets
105
- pub ( crate ) fn parse (
125
+ pub ( crate ) fn parse < ' a > (
106
126
version : u64 ,
107
- input : & [ u8 ] ,
127
+ input : & ' a [ u8 ] ,
108
128
_offset : usize ,
109
129
bucket_start : usize ,
110
- ) -> IResult < & [ u8 ] , Self > {
130
+ ) -> ParseResult < ' a , Self > {
111
131
assert ! ( bucket_start > 0 ) ;
112
132
let ( bytes, _num_buckets) = le_u64 ( & input[ bucket_start..] ) ?;
113
133
let ( _bytes, mut num_entries) = le_u64 ( bytes) ?;
@@ -126,7 +146,7 @@ impl HashTable {
126
146
version : u64 ,
127
147
input : & ' a [ u8 ] ,
128
148
mut num_entries : u64 ,
129
- ) -> IResult < & ' a [ u8 ] , u64 > {
149
+ ) -> ParseResult < ' a , u64 > {
130
150
let ( bytes, num_items_in_bucket) = le_u16 ( input) ?;
131
151
let mut remaining = bytes;
132
152
for _i in 0 ..num_items_in_bucket {
0 commit comments