inline bool sanitize (hb_sanitize_context_t *c) const { return str->sanitize (c, len); }
inline const HBUINT8& operator [] (unsigned int i) const {
- assert (str && (i < len));
- return (*str)[i];
+ if (likely (str && (i < len)))
+ return (*str)[i];
+ else
+ return Null(HBUINT8);
}
inline bool serialize (hb_serialize_context_t *c, const ByteStr &src)
{
VAL *val = values.push ();
val->op = op;
- assert (substr.offset >= opStart);
val->str = ByteStr (substr.str, opStart, substr.offset - opStart);
opStart = substr.offset;
}
{
VAL *val = values.push (v);
val->op = op;
- assert (substr.offset >= opStart);
val->str = ByteStr (substr.str, opStart, substr.offset - opStart);
opStart = substr.offset;
}
inline void pop_n_args (unsigned int n)
{
- assert (n <= argStack.get_count ());
argStack.pop (n);
}
}
template <typename ENV>
- inline void set_current_str (ENV &env)
+ inline void set_current_str (ENV &env, bool calling)
{
ParsedCStr *parsed_str = get_parsed_str_for_context (env.context);
if (likely (parsed_str != nullptr))
- current_parsed_str = parsed_str;
+ {
+ /* If the called subroutine is parsed partially but not completely yet,
+ * it must be because we are calling it recursively.
+ * Handle it as an error. */
+ if (unlikely (calling && !parsed_str->is_parsed () && (parsed_str->values.len > 0)))
+ env.set_error ();
+ else
+ current_parsed_str = parsed_str;
+ }
else
env.set_error ();
}
param.current_parsed_str->add_op (op, env.substr);
param.current_parsed_str->set_parsed ();
env.returnFromSubr ();
- param.set_current_str (env);
+ param.set_current_str (env, false);
break;
case OpCode_endchar:
env.callSubr (subrs, type);
param.current_parsed_str->add_call_op (op, substr, env.context.subr_num);
hb_set_add (closure, env.context.subr_num);
- param.set_current_str (env);
+ param.set_current_str (env, true);
}
private:
case OpCode_return:
param.current_parsed_str->set_parsed ();
env.returnFromSubr ();
- param.set_current_str (env);
+ param.set_current_str (env, false);
break;
case OpCode_endchar:
env.callSubr (subrs, type);
param.current_parsed_str->add_call_op (op, substr, env.context.subr_num);
hb_set_add (closure, env.context.subr_num);
- param.set_current_str (env);
+ param.set_current_str (env, true);
}
private: