diff --git a/src/hb-cff-interp-dict-common.hh b/src/hb-cff-interp-dict-common.hh index 53226b227..a08b10b5f 100644 --- a/src/hb-cff-interp-dict-common.hh +++ b/src/hb-cff-interp-dict-common.hh @@ -54,8 +54,8 @@ struct top_dict_values_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int charStringsOffset; - unsigned int FDArrayOffset; + int charStringsOffset; + int FDArrayOffset; }; struct dict_opset_t : opset_t @@ -157,11 +157,11 @@ struct top_dict_opset_t : dict_opset_t { switch (op) { case OpCode_CharStrings: - dictval.charStringsOffset = env.argStack.pop_uint (); + dictval.charStringsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDArray: - dictval.FDArrayOffset = env.argStack.pop_uint (); + dictval.FDArrayOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FontMatrix: diff --git a/src/hb-ot-cff-common.hh b/src/hb-ot-cff-common.hh index 4fdba197a..b28177af1 100644 --- a/src/hb-ot-cff-common.hh +++ b/src/hb-ot-cff-common.hh @@ -41,10 +41,11 @@ using namespace OT; using objidx_t = hb_serialize_context_t::objidx_t; using whence_t = hb_serialize_context_t::whence_t; -/* utility macro */ +/* CFF offsets can technically be negative */ template -static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset) -{ return offset ? StructAtOffset (P, offset) : Null (Type); } +static inline const Type& StructAtOffsetOrNull (const void *P, int offset) +{ return offset ? * reinterpret_cast ((const char *) P + offset) : Null (Type); } + struct code_pair_t { diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index c869e9055..7cdb87150 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -763,9 +763,9 @@ struct cff1_top_dict_values_t : top_dict_values_t unsigned int ros_supplement; unsigned int cidCount; - unsigned int EncodingOffset; - unsigned int CharsetOffset; - unsigned int FDSelectOffset; + int EncodingOffset; + int CharsetOffset; + int FDSelectOffset; table_info_t privateDictInfo; }; @@ -821,24 +821,24 @@ struct cff1_top_dict_opset_t : top_dict_opset_t break; case OpCode_Encoding: - dictval.EncodingOffset = env.argStack.pop_uint (); + dictval.EncodingOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.EncodingOffset == 0)) return; break; case OpCode_charset: - dictval.CharsetOffset = env.argStack.pop_uint (); + dictval.CharsetOffset = env.argStack.pop_int (); env.clear_args (); if (unlikely (dictval.CharsetOffset == 0)) return; break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_Private: - dictval.privateDictInfo.offset = env.argStack.pop_uint (); + dictval.privateDictInfo.offset = env.argStack.pop_int (); dictval.privateDictInfo.size = env.argStack.pop_uint (); env.clear_args (); break; @@ -913,7 +913,7 @@ struct cff1_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF1Subrs *localSubrs; }; @@ -948,7 +948,7 @@ struct cff1_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -990,7 +990,7 @@ struct cff1_private_dict_opset_subset_t : dict_opset_t break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -1090,7 +1090,7 @@ struct cff1 goto fail; hb_barrier (); - topDictIndex = &StructAtOffset (nameIndex, nameIndex->get_size ()); + topDictIndex = &StructAtOffsetOrNull (nameIndex, nameIndex->get_size ()); if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0)) goto fail; hb_barrier (); @@ -1146,12 +1146,12 @@ struct cff1 } } - stringIndex = &StructAtOffset (topDictIndex, topDictIndex->get_size ()); + stringIndex = &StructAtOffsetOrNull (topDictIndex, topDictIndex->get_size ()); if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc)) goto fail; hb_barrier (); - globalSubrs = &StructAtOffset (stringIndex, stringIndex->get_size ()); + globalSubrs = &StructAtOffsetOrNull (stringIndex, stringIndex->get_size ()); if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc)) goto fail; hb_barrier (); @@ -1188,7 +1188,7 @@ struct cff1 font->init (); if (unlikely (!font_interp.interpret (*font))) goto fail; PRIVDICTVAL *priv = &privateDicts[i]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; hb_barrier (); num_interp_env_t env2 (privDictStr); @@ -1208,7 +1208,7 @@ struct cff1 cff1_top_dict_values_t *font = &topDict; PRIVDICTVAL *priv = &privateDicts[0]; - const hb_ubytes_t privDictStr = StructAtOffset (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); + const hb_ubytes_t privDictStr = StructAtOffsetOrNull (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size); if (unlikely (!privDictStr.sanitize (&sc))) goto fail; hb_barrier (); num_interp_env_t env (privDictStr); diff --git a/src/hb-ot-cff2-table.hh b/src/hb-ot-cff2-table.hh index 652748b73..e1f59b565 100644 --- a/src/hb-ot-cff2-table.hh +++ b/src/hb-ot-cff2-table.hh @@ -150,8 +150,8 @@ struct cff2_top_dict_values_t : top_dict_values_t<> } void fini () { top_dict_values_t<>::fini (); } - unsigned int vstoreOffset; - unsigned int FDSelectOffset; + int vstoreOffset; + int FDSelectOffset; }; struct cff2_top_dict_opset_t : top_dict_opset_t<> @@ -169,11 +169,11 @@ struct cff2_top_dict_opset_t : top_dict_opset_t<> break; case OpCode_vstore: - dictval.vstoreOffset = env.argStack.pop_uint (); + dictval.vstoreOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_FDSelect: - dictval.FDSelectOffset = env.argStack.pop_uint (); + dictval.FDSelectOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -241,7 +241,7 @@ struct cff2_private_dict_values_base_t : dict_values_t } void fini () { dict_values_t::fini (); } - unsigned int subrsOffset; + int subrsOffset; const CFF2Subrs *localSubrs; unsigned int ivs; }; @@ -295,7 +295,7 @@ struct cff2_private_dict_opset_t : dict_opset_t env.clear_args (); break; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; case OpCode_vsindexdict: @@ -344,7 +344,7 @@ struct cff2_private_dict_opset_subset_t : dict_opset_t return; case OpCode_Subrs: - dictval.subrsOffset = env.argStack.pop_uint (); + dictval.subrsOffset = env.argStack.pop_int (); env.clear_args (); break; @@ -426,7 +426,7 @@ struct cff2 if (unlikely (!top_interp.interpret (topDict))) goto fail; } - globalSubrs = &StructAtOffset (cff2, cff2->topDict + cff2->topDictSize); + globalSubrs = &StructAtOffsetOrNull (cff2, cff2->topDict + cff2->topDictSize); varStore = &StructAtOffsetOrNull (cff2, topDict.vstoreOffset); charStrings = &StructAtOffsetOrNull (cff2, topDict.charStringsOffset); fdArray = &StructAtOffsetOrNull (cff2, topDict.FDArrayOffset);