diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh index e90207a5b..496762903 100644 --- a/src/hb-cff-interp-common.hh +++ b/src/hb-cff-interp-common.hh @@ -480,7 +480,11 @@ struct arg_stack_t : cff_stack_t /* an operator prefixed by its operands in a byte string */ struct op_str_t { - hb_ubytes_t str; + /* This used to be a hb_ubytes_t. Using a pointer and length + * saves 8 bytes in the struct. */ + const unsigned char *ptr = nullptr; + unsigned length = 0; + op_code_t op; }; @@ -492,9 +496,9 @@ struct op_serializer_t { TRACE_SERIALIZE (this); - HBUINT8 *d = c->allocate_size (opstr.str.length); + HBUINT8 *d = c->allocate_size (opstr.length); if (unlikely (!d)) return_trace (false); - memcpy (d, &opstr.str[0], opstr.str.length); + memcpy (d, opstr.ptr, opstr.length); return_trace (true); } }; @@ -518,7 +522,9 @@ struct parsed_values_t { VAL *val = values.push (); val->op = op; - val->str = str_ref.sub_array (opStart, str_ref.get_offset () - opStart); + auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart); + val->ptr = arr.arrayZ; + val->length = arr.length; opStart = str_ref.get_offset (); } @@ -526,7 +532,9 @@ struct parsed_values_t { VAL *val = values.push (v); val->op = op; - val->str = str_ref.sub_array (opStart, str_ref.get_offset () - opStart); + auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart); + val->ptr = arr.arrayZ; + val->length = arr.length; opStart = str_ref.get_offset (); } diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh index 152898524..69c9eb65d 100644 --- a/src/hb-subset-cff-common.hh +++ b/src/hb-subset-cff-common.hh @@ -104,20 +104,20 @@ struct str_encoder_t encode_byte (op); } - void copy_str (const hb_ubytes_t &str) + void copy_str (const unsigned char *str, unsigned length) { unsigned int offset = buff.length; /* Manually resize buffer since faster. */ - if (likely ((signed) (buff.length + str.length) <= buff.allocated)) - buff.length += str.length; - else if (unlikely (!buff.resize (offset + str.length))) + if (likely ((signed) (buff.length + length) <= buff.allocated)) + buff.length += length; + else if (unlikely (!buff.resize (offset + length))) return; /* Since our strings are one or two bytes typically, * this is faster than memcpy. */ - for (unsigned i = 0; i < str.length; i++) - buff.arrayZ[i + offset] = str.arrayZ[i]; - // memcpy (buff.arrayZ + offset, &str[0], str.length); + for (unsigned i = 0; i < length; i++) + buff.arrayZ[i + offset] = str[i]; + // memcpy (buff.arrayZ + offset, str, length); } bool is_error () const { return buff.in_error (); } @@ -183,9 +183,9 @@ struct cff_font_dict_op_serializer_t : op_serializer_t } else { - HBUINT8 *d = c->allocate_size (opstr.str.length); + HBUINT8 *d = c->allocate_size (opstr.length); if (unlikely (!d)) return_trace (false); - memcpy (d, &opstr.str[0], opstr.str.length); + memcpy (d, opstr.ptr, opstr.length); } return_trace (true); } @@ -883,7 +883,7 @@ struct subr_subsetter_t break; default: - encoder.copy_str (opstr.str); + encoder.copy_str (opstr.ptr, opstr.length); break; } } diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index fbf1894cf..53b0ed281 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -167,9 +167,10 @@ struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t= opstr.last_arg_offset + 3))) + if ( unlikely (!(opstr.length >= opstr.last_arg_offset + 3))) return_trace (false); - supp_op.str = hb_ubytes_t (&opstr.str + opstr.last_arg_offset, opstr.str.length - opstr.last_arg_offset); + supp_op.ptr = opstr.ptr + opstr.last_arg_offset; + supp_op.length = opstr.length - opstr.last_arg_offset; return_trace (UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::registry]) && UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) && copy_opstr (c, supp_op));