8
8
9
9
namespace {
10
10
11
- uint32_t DecodeBits (std::vector<bool >::const_iterator& bitpos, uint8_t minval, const std::vector<uint8_t > &bit_sizes)
11
+ uint32_t DecodeBits (std::vector<bool >::const_iterator& bitpos, const std::vector< bool >::const_iterator& endpos, uint8_t minval, const std::vector<uint8_t > &bit_sizes)
12
12
{
13
13
uint32_t val = minval;
14
14
bool bit;
15
15
for (std::vector<uint8_t >::const_iterator bit_sizes_it = bit_sizes.begin ();
16
16
bit_sizes_it != bit_sizes.end (); ++bit_sizes_it) {
17
17
if (bit_sizes_it + 1 != bit_sizes.end ()) {
18
+ if (bitpos == endpos) break ;
18
19
bit = *bitpos;
19
20
bitpos++;
20
21
} else {
@@ -24,6 +25,7 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, uint8_t minval, c
24
25
val += (1 << *bit_sizes_it);
25
26
} else {
26
27
for (int b = 0 ; b < *bit_sizes_it; b++) {
28
+ if (bitpos == endpos) break ;
27
29
bit = *bitpos;
28
30
bitpos++;
29
31
val += bit << (*bit_sizes_it - 1 - b);
@@ -35,63 +37,67 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, uint8_t minval, c
35
37
}
36
38
37
39
const std::vector<uint8_t > TYPE_BIT_SIZES{0 , 0 , 1 };
38
- uint32_t DecodeType (std::vector<bool >::const_iterator& bitpos)
40
+ uint32_t DecodeType (std::vector<bool >::const_iterator& bitpos, const std::vector< bool >::const_iterator& endpos )
39
41
{
40
- return DecodeBits (bitpos, 0 , TYPE_BIT_SIZES);
42
+ return DecodeBits (bitpos, endpos, 0 , TYPE_BIT_SIZES);
41
43
}
42
44
43
45
const std::vector<uint8_t > ASN_BIT_SIZES{15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 };
44
- uint32_t DecodeASN (std::vector<bool >::const_iterator& bitpos)
46
+ uint32_t DecodeASN (std::vector<bool >::const_iterator& bitpos, const std::vector< bool >::const_iterator& endpos )
45
47
{
46
- return DecodeBits (bitpos, 1 , ASN_BIT_SIZES);
48
+ return DecodeBits (bitpos, endpos, 1 , ASN_BIT_SIZES);
47
49
}
48
50
49
51
50
52
const std::vector<uint8_t > MATCH_BIT_SIZES{1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
51
- uint32_t DecodeMatch (std::vector<bool >::const_iterator& bitpos)
53
+ uint32_t DecodeMatch (std::vector<bool >::const_iterator& bitpos, const std::vector< bool >::const_iterator& endpos )
52
54
{
53
- return DecodeBits (bitpos, 2 , MATCH_BIT_SIZES);
55
+ return DecodeBits (bitpos, endpos, 2 , MATCH_BIT_SIZES);
54
56
}
55
57
56
58
57
59
const std::vector<uint8_t > JUMP_BIT_SIZES{5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 };
58
- uint32_t DecodeJump (std::vector<bool >::const_iterator& bitpos)
60
+ uint32_t DecodeJump (std::vector<bool >::const_iterator& bitpos, const std::vector< bool >::const_iterator& endpos )
59
61
{
60
- return DecodeBits (bitpos, 17 , JUMP_BIT_SIZES);
62
+ return DecodeBits (bitpos, endpos, 17 , JUMP_BIT_SIZES);
61
63
}
62
64
63
65
}
64
66
65
67
uint32_t Interpret (const std::vector<bool > &asmap, const std::vector<bool > &ip)
66
68
{
67
69
std::vector<bool >::const_iterator pos = asmap.begin ();
70
+ const std::vector<bool >::const_iterator endpos = asmap.end ();
68
71
uint8_t bits = ip.size ();
69
- uint8_t default_asn = 0 ;
72
+ uint32_t default_asn = 0 ;
70
73
uint32_t opcode, jump, match, matchlen;
71
- while (1 ) {
72
- assert (pos != asmap.end ());
73
- opcode = DecodeType (pos);
74
+ while (pos != endpos) {
75
+ opcode = DecodeType (pos, endpos);
74
76
if (opcode == 0 ) {
75
- return DecodeASN (pos);
77
+ return DecodeASN (pos, endpos );
76
78
} else if (opcode == 1 ) {
77
- jump = DecodeJump (pos);
79
+ jump = DecodeJump (pos, endpos);
80
+ if (bits == 0 ) break ;
78
81
if (ip[ip.size () - bits]) {
82
+ if (jump >= endpos - pos) break ;
79
83
pos += jump;
80
84
}
81
85
bits--;
82
86
} else if (opcode == 2 ) {
83
- match = DecodeMatch (pos);
87
+ match = DecodeMatch (pos, endpos );
84
88
matchlen = CountBits (match) - 1 ;
85
89
for (uint32_t bit = 0 ; bit < matchlen; bit++) {
90
+ if (bits == 0 ) break ;
86
91
if ((ip[ip.size () - bits]) != ((match >> (matchlen - 1 - bit)) & 1 )) {
87
92
return default_asn;
88
93
}
89
94
bits--;
90
95
}
91
96
} else if (opcode == 3 ) {
92
- default_asn = DecodeASN (pos);
97
+ default_asn = DecodeASN (pos, endpos );
93
98
} else {
94
- assert ( 0 ) ;
99
+ break ;
95
100
}
96
101
}
102
+ return 0 ; // 0 is not a valid ASN
97
103
}
0 commit comments