| 83 | } |
| 84 | |
| 85 | uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip) |
| 86 | { |
| 87 | std::vector<bool>::const_iterator pos = asmap.begin(); |
| 88 | const std::vector<bool>::const_iterator endpos = asmap.end(); |
| 89 | uint8_t bits = ip.size(); |
| 90 | uint32_t default_asn = 0; |
| 91 | uint32_t jump, match, matchlen; |
| 92 | Instruction opcode; |
| 93 | while (pos != endpos) { |
| 94 | opcode = DecodeType(pos, endpos); |
| 95 | if (opcode == Instruction::RETURN) { |
| 96 | default_asn = DecodeASN(pos, endpos); |
| 97 | if (default_asn == INVALID) break; // ASN straddles EOF |
| 98 | return default_asn; |
| 99 | } else if (opcode == Instruction::JUMP) { |
| 100 | jump = DecodeJump(pos, endpos); |
| 101 | if (jump == INVALID) break; // Jump offset straddles EOF |
| 102 | if (bits == 0) break; // No input bits left |
| 103 | if (int64_t{jump} >= int64_t{endpos - pos}) break; // Jumping past EOF |
| 104 | if (ip[ip.size() - bits]) { |
| 105 | pos += jump; |
| 106 | } |
| 107 | bits--; |
| 108 | } else if (opcode == Instruction::MATCH) { |
| 109 | match = DecodeMatch(pos, endpos); |
| 110 | if (match == INVALID) break; // Match bits straddle EOF |
| 111 | matchlen = CountBits(match) - 1; |
| 112 | if (bits < matchlen) break; // Not enough input bits |
| 113 | for (uint32_t bit = 0; bit < matchlen; bit++) { |
| 114 | if ((ip[ip.size() - bits]) != ((match >> (matchlen - 1 - bit)) & 1)) { |
| 115 | return default_asn; |
| 116 | } |
| 117 | bits--; |
| 118 | } |
| 119 | } else if (opcode == Instruction::DEFAULT) { |
| 120 | default_asn = DecodeASN(pos, endpos); |
| 121 | if (default_asn == INVALID) break; // ASN straddles EOF |
| 122 | } else { |
| 123 | break; // Instruction straddles EOF |
| 124 | } |
| 125 | } |
| 126 | assert(false); // Reached EOF without RETURN, or aborted (see any of the breaks above) - should have been caught by SanityCheckASMap below |
| 127 | return 0; // 0 is not a valid ASN |
| 128 | } |
| 129 | |
| 130 | bool SanityCheckASMap(const std::vector<bool>& asmap, int bits) |
| 131 | { |