88
99namespace {
1010
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)
1212{
1313 uint32_t val = minval;
1414 bool bit;
1515 for (std::vector<uint8_t >::const_iterator bit_sizes_it = bit_sizes.begin ();
1616 bit_sizes_it != bit_sizes.end (); ++bit_sizes_it) {
1717 if (bit_sizes_it + 1 != bit_sizes.end ()) {
18+ if (bitpos == endpos) break ;
1819 bit = *bitpos;
1920 bitpos++;
2021 } else {
@@ -24,6 +25,7 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, uint8_t minval, c
2425 val += (1 << *bit_sizes_it);
2526 } else {
2627 for (int b = 0 ; b < *bit_sizes_it; b++) {
28+ if (bitpos == endpos) break ;
2729 bit = *bitpos;
2830 bitpos++;
2931 val += bit << (*bit_sizes_it - 1 - b);
@@ -35,63 +37,67 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, uint8_t minval, c
3537}
3638
3739const 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 )
3941{
40- return DecodeBits (bitpos, 0 , TYPE_BIT_SIZES);
42+ return DecodeBits (bitpos, endpos, 0 , TYPE_BIT_SIZES);
4143}
4244
4345const 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 )
4547{
46- return DecodeBits (bitpos, 1 , ASN_BIT_SIZES);
48+ return DecodeBits (bitpos, endpos, 1 , ASN_BIT_SIZES);
4749}
4850
4951
5052const 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 )
5254{
53- return DecodeBits (bitpos, 2 , MATCH_BIT_SIZES);
55+ return DecodeBits (bitpos, endpos, 2 , MATCH_BIT_SIZES);
5456}
5557
5658
5759const 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 )
5961{
60- return DecodeBits (bitpos, 17 , JUMP_BIT_SIZES);
62+ return DecodeBits (bitpos, endpos, 17 , JUMP_BIT_SIZES);
6163}
6264
6365}
6466
6567uint32_t Interpret (const std::vector<bool > &asmap, const std::vector<bool > &ip)
6668{
6769 std::vector<bool >::const_iterator pos = asmap.begin ();
70+ const std::vector<bool >::const_iterator endpos = asmap.end ();
6871 uint8_t bits = ip.size ();
69- uint8_t default_asn = 0 ;
72+ uint32_t default_asn = 0 ;
7073 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);
7476 if (opcode == 0 ) {
75- return DecodeASN (pos);
77+ return DecodeASN (pos, endpos );
7678 } else if (opcode == 1 ) {
77- jump = DecodeJump (pos);
79+ jump = DecodeJump (pos, endpos);
80+ if (bits == 0 ) break ;
7881 if (ip[ip.size () - bits]) {
82+ if (jump >= endpos - pos) break ;
7983 pos += jump;
8084 }
8185 bits--;
8286 } else if (opcode == 2 ) {
83- match = DecodeMatch (pos);
87+ match = DecodeMatch (pos, endpos );
8488 matchlen = CountBits (match) - 1 ;
8589 for (uint32_t bit = 0 ; bit < matchlen; bit++) {
90+ if (bits == 0 ) break ;
8691 if ((ip[ip.size () - bits]) != ((match >> (matchlen - 1 - bit)) & 1 )) {
8792 return default_asn;
8893 }
8994 bits--;
9095 }
9196 } else if (opcode == 3 ) {
92- default_asn = DecodeASN (pos);
97+ default_asn = DecodeASN (pos, endpos );
9398 } else {
94- assert ( 0 ) ;
99+ break ;
95100 }
96101 }
102+ return 0 ; // 0 is not a valid ASN
97103}
0 commit comments