From 5dde3bc8c73614d0fa93527fa81d31f7daf1890d Mon Sep 17 00:00:00 2001 From: ReadRoberts Date: Tue, 18 Jun 2019 15:50:03 -0700 Subject: [PATCH] [makeotfexe] Fix MarkToBase bug Fix afdko issue Bug in building MarkToBase lookup type 4 #811. In fillMarkToBase(), If a base record does not have anchor for a given mark class, the logic assigns it an offset of 0. Later, in writeMarkToBase(), an offset of 0 for a base anchor record is used as a flag to write a NULL anchor record. There are several parts to how the bug happens. First, the offset to the first mark anchor record is always zero. This is not a problem for the array of offsets to the mark anchor records, as the logic assumes these are never NULL. Second, the the anchor offset array is filled first with the mark anchor records, and then extended with the base anchor records. Third, when the base anchor records are processed, the code tries to find a match for the current base anchor record's coords in the anchor record array; if a match is found, the offset for that anchor record is used. This means that if a base anchor record's coords match the coords of the first mark anchor record, the offset for the baser anchor record will be set to the same as that of the first mark anchor record - which is zero. In writeMarkToBase(), this valid offset is then interpreted as flagging a NULL anchor. I think this bug was added by me on 5/9/2016 commit [20af6dd5], when I changed the handling of empty mark records. --- c/makeotf/makeotf_lib/source/hotconv/GPOS.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/c/makeotf/makeotf_lib/source/hotconv/GPOS.c b/c/makeotf/makeotf_lib/source/hotconv/GPOS.c index 3dbb19593..d32b9f1c9 100644 --- a/c/makeotf/makeotf_lib/source/hotconv/GPOS.c +++ b/c/makeotf/makeotf_lib/source/hotconv/GPOS.c @@ -3929,7 +3929,7 @@ static void fillMarkToBase(hotCtx g, GPOSCtx h) { for (j = 0; j < fmt->ClassCount; j++) { if (baseAnchorArray[j] == 0xFFFFFFFFL) { char msg[1024]; - baseAnchorArray[j] = 0; + baseAnchorArray[j] = 0xFFFFFFFFL; featGlyphDump(g, baseRec->gid, '\0', 0); if (h->new.fileName != NULL) { sprintf(msg, " [%s line %ld]", h->new.fileName, baseRec->lineNum); @@ -4014,8 +4014,7 @@ static void writeMarkToBase(hotCtx g, GPOSCtx h, Subtable *sub) { for (i = 0; i < fmt->BaseArray_.BaseCount; i++) { BaseRecord *baseRec = &fmt->BaseArray_.BaseRecord[i]; for (j = 0; j < markClassCnt; j++) { - LOffset *baseAnchorArray = baseRec->BaseAnchorArray; - if (baseRec->BaseAnchorArray[j] == 0) + if (baseRec->BaseAnchorArray[j] == 0xFFFFFFFFL) OUT2((Offset)0); else OUT2((Offset)(baseRec->BaseAnchorArray[j] + anchorListOffset));