ICU-6011 Handle bad values in the scriptCount field in the ScriptList Table.
X-SVN-Rev: 23611
This commit is contained in:
parent
3b646b385c
commit
e0b48bc938
@ -1,7 +1,5 @@
|
||||
/*
|
||||
* %W% %E%
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
|
||||
* (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
|
||||
*
|
||||
*/
|
||||
|
||||
@ -31,20 +29,45 @@ const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMa
|
||||
return (const LangSysTable *) ((char *)this + langSysTableOffset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const
|
||||
{
|
||||
/*
|
||||
* There are some fonts that have a large, bogus value for scriptCount. To try
|
||||
* and protect against this, we use the offset in the first scriptRecord,
|
||||
* which we know has to be past the end of the scriptRecordArray, to compute
|
||||
* a value which is greater than or equal to the actual script count.
|
||||
*
|
||||
* Note: normally, the first offset will point to just after the scriptRecordArray,
|
||||
* but there's no guarantee of this, only that it's *after* the scriptRecordArray.
|
||||
* Because of this, a binary serach isn't safe, because the new count may include
|
||||
* data that's not actually in the scriptRecordArray and hence the array will appear
|
||||
* to be unsorted.
|
||||
*/
|
||||
le_uint16 count = SWAPW(scriptCount);
|
||||
Offset scriptTableOffset =
|
||||
OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count);
|
||||
le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof sizeof(scriptRecordArray)) + ANY_NUMBER;
|
||||
Offset scriptTableOffset = 0;
|
||||
|
||||
if (count > limit) {
|
||||
// the scriptCount value is bogus; do a linear search
|
||||
// because limit may still be too large.
|
||||
for(le_int32 s = 0; s < limit; s += 1) {
|
||||
if (SWAPT(scriptRecordArray[s].tag) == scriptTag) {
|
||||
scriptTableOffset = SWAPW(scriptRecordArray[s].offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count);
|
||||
}
|
||||
|
||||
if (scriptTableOffset != 0) {
|
||||
return (const ScriptTable *) ((char *)this + scriptTableOffset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const
|
||||
@ -52,7 +75,7 @@ const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languag
|
||||
const ScriptTable *scriptTable = findScript(scriptTag);
|
||||
|
||||
if (scriptTable == 0) {
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return scriptTable->findLanguage(languageTag, exactMatch);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Copyright (C) 1999-2008, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -276,7 +276,7 @@ const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 plat
|
||||
for(le_int32 i = 0; i < fNameCount; i += 1) {
|
||||
const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
|
||||
|
||||
if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID == encodingID) &&
|
||||
if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
|
||||
SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
|
||||
char *name = ((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset);
|
||||
le_uint16 length = SWAPW(nameRecord->length);
|
||||
@ -292,11 +292,52 @@ const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 plat
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
|
||||
{
|
||||
if (fNAMETable == NULL) {
|
||||
LETag nameTag = LE_NAME_TABLE_TAG;
|
||||
PortableFontInstance *realThis = (PortableFontInstance *) this;
|
||||
|
||||
realThis->fNAMETable = (const NAMETable *) readFontTable(nameTag);
|
||||
|
||||
if (realThis->fNAMETable != NULL) {
|
||||
realThis->fNameCount = SWAPW(realThis->fNAMETable->count);
|
||||
realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
|
||||
}
|
||||
}
|
||||
|
||||
for(le_int32 i = 0; i < fNameCount; i += 1) {
|
||||
const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
|
||||
|
||||
if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
|
||||
SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
|
||||
LEUnicode16 *name = (LEUnicode16 *) (((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset));
|
||||
le_uint16 length = SWAPW(nameRecord->length) / 2;
|
||||
LEUnicode16 *result = NEW_ARRAY(LEUnicode16, length + 2);
|
||||
|
||||
for (le_int32 c = 0; c < length; c += 1) {
|
||||
result[c] = SWAPW(name[c]);
|
||||
}
|
||||
|
||||
result[length] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PortableFontInstance::deleteNameString(const char *name) const
|
||||
{
|
||||
DELETE_ARRAY(name);
|
||||
}
|
||||
|
||||
void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const
|
||||
{
|
||||
DELETE_ARRAY(name);
|
||||
}
|
||||
|
||||
void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
|
||||
{
|
||||
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Copyright (C) 1999-2008, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -75,8 +75,12 @@ public:
|
||||
|
||||
virtual const char *getNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const;
|
||||
|
||||
virtual const LEUnicode16 *getUnicodeNameString(le_uint16 nameID, le_uint16 platform, le_uint16 encoding, le_uint16 language) const;
|
||||
|
||||
virtual void deleteNameString(const char *name) const;
|
||||
|
||||
virtual void deleteNameString(const LEUnicode16 *name) const;
|
||||
|
||||
virtual le_int32 getUnitsPerEM() const;
|
||||
|
||||
virtual le_uint32 getFontChecksum() const;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2006, International Business Machines
|
||||
* Copyright (C) 1999-2008, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -201,6 +201,19 @@ int main(int /*argc*/, char *argv[])
|
||||
|
||||
version = pfi->getNameString(NAME_VERSION_STRING, PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
|
||||
|
||||
// The standard recommends that the Macintosh Roman/English name string be present, but
|
||||
// if it's not, try the Microsoft Unicode/English string.
|
||||
if (version == NULL) {
|
||||
const LEUnicode16 *uversion = pfi->getUnicodeNameString(NAME_VERSION_STRING, PLATFORM_MICROSOFT, MICROSOFT_UNICODE_BMP, MICROSOFT_ENGLISH);
|
||||
|
||||
if (uversion != NULL) {
|
||||
const UnicodeString usversion((const UChar *)uversion);
|
||||
|
||||
version = getCString(&usversion);
|
||||
pfi->deleteNameString(uversion);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(outputFile, " <test-font name=\"%s\" version=\"%s\" checksum=\"0x%8.8X\"/>\n\n",
|
||||
fontName, version, pfi->getFontChecksum());
|
||||
|
||||
|
@ -108,4 +108,9 @@
|
||||
<test-font name="lohit_ml.ttf"/>
|
||||
<test-text>ണു്</test-text>
|
||||
</test-case>
|
||||
|
||||
<test-case id="Broken Font Test" script="hani" lang="ZHT">
|
||||
<test-font name="BMIN00M.TTF"/>
|
||||
<test-text>中華人民共和國 臺灣</test-text>
|
||||
</test-case>
|
||||
</layout-tests>
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2007, International Business Machines
|
||||
* Copyright (C) 1999-2008, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
@ -386,6 +386,19 @@ static void checkFontVersion(PortableFontInstance *fontInstance, const char *tes
|
||||
const char *fontVersionString = fontInstance->getNameString(NAME_VERSION_STRING,
|
||||
PLATFORM_MACINTOSH, MACINTOSH_ROMAN, MACINTOSH_ENGLISH);
|
||||
|
||||
// The standard recommends that the Macintosh Roman/English name string be present, but
|
||||
// if it's not, try the Microsoft Unicode/English string.
|
||||
if (fontVersionString == NULL) {
|
||||
const LEUnicode16 *uversion = fontInstance->getUnicodeNameString(NAME_VERSION_STRING, PLATFORM_MICROSOFT, MICROSOFT_UNICODE_BMP, MICROSOFT_ENGLISH);
|
||||
|
||||
if (uversion != NULL) {
|
||||
const UnicodeString usversion((const UChar *)uversion);
|
||||
|
||||
fontVersionString = getCString(&usversion);
|
||||
fontInstance->deleteNameString(uversion);
|
||||
}
|
||||
}
|
||||
|
||||
log_info("Test %s: this may not be the same font used to generate the test data.\n", testID);
|
||||
log_info("Your font's version string is \"%s\"\n", fontVersionString);
|
||||
log_info("The expected version string is \"%s\"\n", testVersionString);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2007, International Business Machines
|
||||
* Copyright (C) 1998-2008, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
************************************************************************/
|
||||
@ -383,6 +383,17 @@ enum MacintoshLanguageID
|
||||
MACINTOSH_ENGLISH = 0
|
||||
};
|
||||
|
||||
enum MicrosoftEncodingID
|
||||
{
|
||||
MICROSOFT_UNICODE_BMP = 1,
|
||||
MICROSOFT_UNICODE_FULL = 10
|
||||
};
|
||||
|
||||
enum MicrosoftLanguageID
|
||||
{
|
||||
MICROSOFT_ENGLISH = 0x409
|
||||
};
|
||||
|
||||
enum NameID
|
||||
{
|
||||
NAME_COPYRIGHT_NOTICE = 0,
|
||||
|
24
icu4c/source/test/testdata/letest.xml
vendored
24
icu4c/source/test/testdata/letest.xml
vendored
@ -8,7 +8,7 @@
|
||||
UNLESS YOU REALLY KNOW WHAT YOU'RE DOING.
|
||||
|
||||
file name: letest.xml
|
||||
generated on: 03/14/2008 01:04:15 PM Hawaiian Standard Time
|
||||
generated on: 03/18/2008 10:01:39 AM Hawaiian Standard Time
|
||||
generated by: gendata.cpp
|
||||
-->
|
||||
|
||||
@ -1265,4 +1265,26 @@
|
||||
</result-positions>
|
||||
</test-case>
|
||||
|
||||
<test-case id="Broken Font Test" script="hani" lang="ZHT">
|
||||
<test-font name="BMIN00M.TTF" version="Version 2.00" checksum="0xF16BE0C6"/>
|
||||
|
||||
<test-text>中華人民共和國 臺灣</test-text>
|
||||
|
||||
<result-glyphs>
|
||||
0x00000292, 0x000024E8, 0x000002D1, 0x00001582, 0x000004A1, 0x00000650, 0x000007E2, 0x00000021,
|
||||
0x00002395, 0x00001896
|
||||
</result-glyphs>
|
||||
|
||||
<result-indices>
|
||||
0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007,
|
||||
0x00000008, 0x00000009
|
||||
</result-indices>
|
||||
|
||||
<result-positions>
|
||||
0.000000, 0.000000, 12.000000, 0.000000, 24.000000, 0.000000, 36.000000, 0.000000,
|
||||
48.000000, 0.000000, 60.000000, 0.000000, 72.000000, 0.000000, 84.000000, 0.000000,
|
||||
90.000000, 0.000000, 102.000000, 0.000000, 114.000000, 0.000000
|
||||
</result-positions>
|
||||
</test-case>
|
||||
|
||||
</layout-tests>
|
||||
|
Loading…
Reference in New Issue
Block a user