diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2020-04-03 10:43:38 -0700 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2020-04-08 16:26:06 -0700 |
commit | 2b3dbfa5a63cb5a6625ec00294ebd933800f0255 (patch) | |
tree | ea49a5820ac02ed8172fc2f36bd000a9dd38e910 | |
parent | 1479007a335ab43af46f527d0543e254fc2a8e86 (diff) |
Deal with decoding failures explicitly in asmap Interpret
-rw-r--r-- | src/util/asmap.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp index 2ffd618203..5b21d01f3a 100644 --- a/src/util/asmap.cpp +++ b/src/util/asmap.cpp @@ -8,6 +8,8 @@ namespace { +constexpr uint32_t INVALID = 0xFFFFFFFF; + 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) { uint32_t val = minval; @@ -25,7 +27,7 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, const std::vector val += (1 << *bit_sizes_it); } else { for (int b = 0; b < *bit_sizes_it; b++) { - if (bitpos == endpos) break; + if (bitpos == endpos) return INVALID; // Reached EOF in mantissa bit = *bitpos; bitpos++; val += bit << (*bit_sizes_it - 1 - b); @@ -33,7 +35,7 @@ uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, const std::vector return val; } } - return -1; + return INVALID; // Reached EOF in exponent } enum class Instruction : uint32_t @@ -83,9 +85,12 @@ uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip) while (pos != endpos) { opcode = DecodeType(pos, endpos); if (opcode == Instruction::RETURN) { - return DecodeASN(pos, endpos); + default_asn = DecodeASN(pos, endpos); + if (default_asn == INVALID) break; // ASN straddles EOF + return default_asn; } else if (opcode == Instruction::JUMP) { jump = DecodeJump(pos, endpos); + if (jump == INVALID) break; // Jump offset straddles EOF if (bits == 0) break; if (ip[ip.size() - bits]) { if (jump >= endpos - pos) break; @@ -94,6 +99,7 @@ uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip) bits--; } else if (opcode == Instruction::MATCH) { match = DecodeMatch(pos, endpos); + if (match == INVALID) break; // Match bits straddle EOF matchlen = CountBits(match) - 1; for (uint32_t bit = 0; bit < matchlen; bit++) { if (bits == 0) break; @@ -104,8 +110,9 @@ uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip) } } else if (opcode == Instruction::DEFAULT) { default_asn = DecodeASN(pos, endpos); + if (default_asn == INVALID) break; // ASN straddles EOF } else { - break; + break; // Instruction straddles EOF } } return 0; // 0 is not a valid ASN |