You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/util/asmap.cpp
+11Lines changed: 11 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -126,11 +126,14 @@ bool SanityCheckASMap(const std::vector<bool>& asmap, int bits)
126
126
std::vector<bool>::const_iterator pos = begin;
127
127
std::vector<std::pair<uint32_t, int>> jumps; // All future positions we may jump to (bit offset in asmap -> bits to consume left)
128
128
jumps.reserve(bits);
129
+
Instruction prevopcode = Instruction::JUMP;
130
+
bool had_incomplete_match = false;
129
131
while (pos != endpos) {
130
132
uint32_t offset = pos - begin;
131
133
if (!jumps.empty() && offset >= jumps.back().first) returnfalse; // There was a jump into the middle of the previous instruction
132
134
Instruction opcode = DecodeType(pos, endpos);
133
135
if (opcode == Instruction::RETURN) {
136
+
if (prevopcode == Instruction::DEFAULT) returnfalse; // There should not be any RETURN immediately after a DEFAULT (could be combined into just RETURN)
134
137
uint32_t asn = DecodeASN(pos, endpos);
135
138
if (asn == INVALID) returnfalse; // ASN straddles EOF
136
139
if (jumps.empty()) {
@@ -147,6 +150,7 @@ bool SanityCheckASMap(const std::vector<bool>& asmap, int bits)
147
150
if (offset != jumps.back().first) returnfalse; // Unreachable code
148
151
bits = jumps.back().second; // Restore the number of bits we would have had left after this jump
149
152
jumps.pop_back();
153
+
prevopcode = Instruction::JUMP;
150
154
}
151
155
} elseif (opcode == Instruction::JUMP) {
152
156
uint32_t jump = DecodeJump(pos, endpos);
@@ -157,15 +161,22 @@ bool SanityCheckASMap(const std::vector<bool>& asmap, int bits)
157
161
uint32_t jump_offset = pos - begin + jump;
158
162
if (!jumps.empty() && jump_offset >= jumps.back().first) returnfalse; // Intersecting jumps
159
163
jumps.emplace_back(jump_offset, bits);
164
+
prevopcode = Instruction::JUMP;
160
165
} elseif (opcode == Instruction::MATCH) {
161
166
uint32_t match = DecodeMatch(pos, endpos);
162
167
if (match == INVALID) returnfalse; // Match bits straddle EOF
163
168
int matchlen = CountBits(match) - 1;
169
+
if (prevopcode != Instruction::MATCH) had_incomplete_match = false;
170
+
if (matchlen < 8 && had_incomplete_match) returnfalse; // Within a sequence of matches only at most one should be incomplete
171
+
had_incomplete_match = (matchlen < 8);
164
172
if (bits < matchlen) returnfalse; // Consuming bits past the end of the input
165
173
bits -= matchlen;
174
+
prevopcode = Instruction::MATCH;
166
175
} elseif (opcode == Instruction::DEFAULT) {
176
+
if (prevopcode == Instruction::DEFAULT) returnfalse; // There should not be two successive DEFAULTs (they could be combined into one)
167
177
uint32_t asn = DecodeASN(pos, endpos);
168
178
if (asn == INVALID) returnfalse; // ASN straddles EOF
0 commit comments