diff options
Diffstat (limited to 'Build/source/libs/graphite2/graphite2-src/src/Code.cpp')
-rw-r--r-- | Build/source/libs/graphite2/graphite2-src/src/Code.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/Build/source/libs/graphite2/graphite2-src/src/Code.cpp b/Build/source/libs/graphite2/graphite2-src/src/Code.cpp index 247a0529cfa..92ba92379cb 100644 --- a/Build/source/libs/graphite2/graphite2-src/src/Code.cpp +++ b/Build/source/libs/graphite2/graphite2-src/src/Code.cpp @@ -97,7 +97,7 @@ private: opcode fetch_opcode(const byte * bc); void analyse_opcode(const opcode, const int8 * const dp) throw(); bool emit_opcode(opcode opc, const byte * & bc); - bool validate_opcode(const opcode opc, const byte * const bc); + bool validate_opcode(const byte opc, const byte * const bc); bool valid_upto(const uint16 limit, const uint16 x) const throw(); bool test_context() const throw(); bool test_ref(int8 index) const throw(); @@ -266,13 +266,13 @@ bool Machine::Code::decoder::load(const byte * bc, const byte * bc_end) opcode Machine::Code::decoder::fetch_opcode(const byte * bc) { - const opcode opc = opcode(*bc++); + const byte opc = *bc++; // Do some basic sanity checks based on what we know about the opcode if (!validate_opcode(opc, bc)) return MAX_OPCODE; // And check it's arguments as far as possible - switch (opc) + switch (opcode(opc)) { case NOP : break; @@ -470,7 +470,7 @@ opcode Machine::Code::decoder::fetch_opcode(const byte * bc) break; } - return bool(_code) ? opc : MAX_OPCODE; + return bool(_code) ? opcode(opc) : MAX_OPCODE; } @@ -572,6 +572,7 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc) assert(_out_index == 0); _in_ctxt_item = true; _out_index = _max.pre_context + int8(_data[-2]); + _slotref = int8(_data[-2]); _out_length = _max.rule_length; const size_t ctxt_start = _code._instr_count; @@ -589,11 +590,13 @@ bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc) _out_length = 1; _out_index = 0; + _slotref = 0; _in_ctxt_item = false; } else { _out_index = 0; + _slotref = 0; return false; } } @@ -626,7 +629,7 @@ void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end inline -bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * const bc) +bool Machine::Code::decoder::validate_opcode(const byte opc, const byte * const bc) { if (opc >= MAX_OPCODE) { @@ -664,7 +667,17 @@ bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) cons inline bool Machine::Code::decoder::test_ref(int8 index) const throw() { - return valid_upto(_max.rule_length, _slotref + _max.pre_context + index); + if (_code._constraint && !_in_ctxt_item) + { + if (index > 0 || -index > _max.pre_context) + { + failure(out_of_range_data); + return false; + } + } + else + return valid_upto(_max.rule_length, _slotref + _max.pre_context + index); + return true; } bool Machine::Code::decoder::test_context() const throw() |