diff -r 36b30720a997 -r 91e99bed64ae jdk/src/share/native/sun/font/layout/ScriptAndLanguage.cpp --- a/jdk/src/share/native/sun/font/layout/ScriptAndLanguage.cpp Tue Feb 26 10:07:26 2013 -0800 +++ b/jdk/src/share/native/sun/font/layout/ScriptAndLanguage.cpp Thu Mar 07 10:02:20 2013 -0800 @@ -38,29 +38,33 @@ U_NAMESPACE_BEGIN -const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMatch) const +LEReferenceTo ScriptTable::findLanguage(const LETableReference& base, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const { le_uint16 count = SWAPW(langSysCount); Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset); if (count > 0) { - Offset foundOffset = - OpenTypeUtilities::getTagOffset(languageTag, langSysRecordArray, count); + LEReferenceToArrayOf langSysRecords(base, success, langSysRecordArray, count); + Offset foundOffset = + OpenTypeUtilities::getTagOffset(languageTag, langSysRecords, success); - if (foundOffset != 0) { - langSysTableOffset = foundOffset; - } + if (foundOffset != 0 && LE_SUCCESS(success)) { + langSysTableOffset = foundOffset; + } } if (langSysTableOffset != 0) { - return (const LangSysTable *) ((char *)this + langSysTableOffset); + return LEReferenceTo(base, success, langSysTableOffset); } - return NULL; + return LEReferenceTo(); } -const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const +LEReferenceTo ScriptListTable::findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const { + if (LE_FAILURE(success) ) { + return LEReferenceTo(); // get out + } /* * 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, @@ -74,38 +78,53 @@ * to be unsorted. */ le_uint16 count = SWAPW(scriptCount); + + if (count == 0) { + return LEReferenceTo(); // no items, no search + } + + // attempt to construct a ref with at least one element + LEReferenceToArrayOf oneElementTable(base, success, &scriptRecordArray[0], 1); + + if( LE_FAILURE(success) ) { + return LEReferenceTo(); // couldn't even read the first record - bad font. + } + le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / 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; - } + LEReferenceToArrayOf scriptRecordArrayRef(base, success, &scriptRecordArray[0], limit); + for(le_int32 s = 0; (s < limit)&&LE_SUCCESS(success); s += 1) { + if (SWAPT(scriptRecordArrayRef(s,success).tag) == scriptTag) { + scriptTableOffset = SWAPW(scriptRecordArrayRef(s,success).offset); + break; + } } } else { - scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count); + LEReferenceToArrayOf scriptRecordArrayRef(base, success, &scriptRecordArray[0], count); + scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO } if (scriptTableOffset != 0) { - return (const ScriptTable *) ((char *)this + scriptTableOffset); + return LEReferenceTo(base, success, scriptTableOffset); } - return NULL; + return LEReferenceTo(); } -const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const +LEReferenceTo ScriptListTable::findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const { - const ScriptTable *scriptTable = findScript(scriptTag); + const LEReferenceTo scriptTable = findScript(base, scriptTag, success); - if (scriptTable == 0) { - return NULL; - } + if (scriptTable.isEmpty()) { + return LEReferenceTo(); + } - return scriptTable->findLanguage(languageTag, exactMatch); + return scriptTable->findLanguage(scriptTable, languageTag, success, exactMatch).reparent(base); } U_NAMESPACE_END