diff --git a/icu4c/source/common/unicode/uobject.h b/icu4c/source/common/unicode/uobject.h index 045d130c14..a81c2822f5 100644 --- a/icu4c/source/common/unicode/uobject.h +++ b/icu4c/source/common/unicode/uobject.h @@ -92,6 +92,13 @@ U_NAMESPACE_BEGIN class U_COMMON_API UMemory { public: +/* test versions for debugging shaper heap memory problems */ +#ifdef SHAPER_MEMORY_DEBUG + static void * NewArray(int size, int count); + static void * GrowArray(void * array, int newSize ); + static void FreeArray(void * array ); +#endif + #if U_OVERRIDE_CXX_ALLOCATION /** * Override for ICU4C C++ memory management. diff --git a/icu4c/source/layout/ContextualSubstSubtables.cpp b/icu4c/source/layout/ContextualSubstSubtables.cpp index 1d8f28c8c1..b75e388807 100644 --- a/icu4c/source/layout/ContextualSubstSubtables.cpp +++ b/icu4c/source/layout/ContextualSubstSubtables.cpp @@ -1,5 +1,5 @@ /* - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -27,18 +27,23 @@ void ContextualSubstitutionBase::applySubstitutionLookups( le_uint16 substCount, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, - le_int32 position) + le_int32 position, + LEErrorCode& success) { + if (LE_FAILURE(success)) { + return; + } + GlyphIterator tempIterator(*glyphIterator); - for (le_int16 subst = 0; subst < substCount; subst += 1) { + for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) { le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex); le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex); tempIterator.setCurrStreamPosition(position); tempIterator.next(sequenceIndex); - lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance); + lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance, success); } } @@ -140,9 +145,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa return TRUE; } -le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + switch(SWAPW(subtableFormat)) { case 0: @@ -151,22 +162,19 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP case 1: { const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 2: { const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 3: { const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } default: @@ -174,9 +182,15 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP } } -le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); le_int32 coverageIndex = getGlyphCoverage(glyph); @@ -202,7 +216,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return matchCount + 1; } @@ -217,9 +231,15 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor * return 0; } -le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); le_int32 coverageIndex = getGlyphCoverage(glyph); @@ -248,7 +268,7 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return matchCount + 1; } @@ -263,9 +283,15 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor * return 0; } -le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance)const +le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success)const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint16 gCount = SWAPW(glyphCount); le_uint16 subCount = SWAPW(substCount); le_int32 position = glyphIterator->getCurrStreamPosition(); @@ -280,7 +306,7 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount]; - ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position); + ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success); return gCount + 1; } @@ -290,9 +316,15 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor * return 0; } -le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + switch(SWAPW(subtableFormat)) { case 0: @@ -301,22 +333,19 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor case 1: { const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 2: { const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } case 3: { const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this; - - return subtable->process(lookupProcessor, glyphIterator, fontInstance); + return subtable->process(lookupProcessor, glyphIterator, fontInstance, success); } default: @@ -330,9 +359,15 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor // emptyFeatureList matches an le_uint32 or an le_uint16... static const FeatureMask emptyFeatureList = 0x00000000UL; -le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); le_int32 coverageIndex = getGlyphCoverage(glyph); @@ -380,7 +415,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount + 1; } @@ -395,9 +430,15 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro return 0; } -le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); le_int32 coverageIndex = getGlyphCoverage(glyph); @@ -454,7 +495,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1]; - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount + 1; } @@ -469,9 +510,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro return 0; } -le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const +le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor, + GlyphIterator *glyphIterator, + const LEFontInstance *fontInstance, + LEErrorCode & success) const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount); le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]); const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1]; @@ -509,7 +556,7 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro const SubstitutionLookupRecord *substLookupRecordArray = (const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1]; - ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position); + ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); return inputGlyphCount; } diff --git a/icu4c/source/layout/ContextualSubstSubtables.h b/icu4c/source/layout/ContextualSubstSubtables.h index a77a196d1f..2ca1c1a053 100644 --- a/icu4c/source/layout/ContextualSubstSubtables.h +++ b/icu4c/source/layout/ContextualSubstSubtables.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -47,12 +47,13 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable le_uint16 substCount, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, - le_int32 position); + le_int32 position, + LEErrorCode& success); }; struct ContextualSubstitutionSubtable : ContextualSubstitutionBase { - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable @@ -60,7 +61,7 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable le_uint16 subRuleSetCount; Offset subRuleSetTableOffsetArray[ANY_NUMBER]; - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct SubRuleSetTable @@ -85,7 +86,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable le_uint16 subClassSetCount; Offset subClassSetTableOffsetArray[ANY_NUMBER]; - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct SubClassSetTable @@ -115,12 +116,12 @@ struct ContextualSubstitutionFormat3Subtable Offset coverageTableOffsetArray[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecord[ANY_NUMBER]; - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase { - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable @@ -128,7 +129,7 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit le_uint16 chainSubRuleSetCount; Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER]; - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct ChainSubRuleSetTable @@ -159,7 +160,7 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit le_uint16 chainSubClassSetCount; Offset chainSubClassSetTableOffsetArray[ANY_NUMBER]; - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; struct ChainSubClassSetTable @@ -197,7 +198,7 @@ struct ChainingContextualSubstitutionFormat3Subtable //le_uint16 substCount; //SubstitutionLookupRecord substLookupRecord[ANY_NUMBER]; - le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; U_NAMESPACE_END diff --git a/icu4c/source/layout/ExtensionSubtables.cpp b/icu4c/source/layout/ExtensionSubtables.cpp index 3453743e40..411f565e2a 100644 --- a/icu4c/source/layout/ExtensionSubtables.cpp +++ b/icu4c/source/layout/ExtensionSubtables.cpp @@ -1,7 +1,7 @@ /* * %W% %E% * - * (C) Copyright IBM Corp. 2002 - All Rights Reserved + * (C) Copyright IBM Corp. 2008 - All Rights Reserved * */ @@ -18,15 +18,19 @@ U_NAMESPACE_BEGIN // FIXME: should look at the format too... maybe have a sub-class for it? le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType, - GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const + GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint16 elt = SWAPW(extensionLookupType); if (elt != lookupType) { le_uint32 extOffset = SWAPL(extensionOffset); LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset); - return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance); + return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success); } return 0; diff --git a/icu4c/source/layout/ExtensionSubtables.h b/icu4c/source/layout/ExtensionSubtables.h index f522b9ebf3..7d214af5ec 100644 --- a/icu4c/source/layout/ExtensionSubtables.h +++ b/icu4c/source/layout/ExtensionSubtables.h @@ -1,7 +1,7 @@ /* * %W% %E% * - * (C) Copyright IBM Corp. 2002-2003 - All Rights Reserved + * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved * */ @@ -28,7 +28,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable le_uint32 extensionOffset; le_uint32 process(const LookupProcessor *lookupProcessor, le_uint16 lookupType, - GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; U_NAMESPACE_END diff --git a/icu4c/source/layout/GlyphIterator.cpp b/icu4c/source/layout/GlyphIterator.cpp index d859c57cbf..231743407c 100644 --- a/icu4c/source/layout/GlyphIterator.cpp +++ b/icu4c/source/layout/GlyphIterator.cpp @@ -107,9 +107,9 @@ void GlyphIterator::reset(le_uint16 newLookupFlags, FeatureMask newFeatureMask) lookupFlags = newLookupFlags; } -LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count) +LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success) { - return glyphStorage.insertGlyphs(position, count); + return glyphStorage.insertGlyphs(position, count, success); } le_int32 GlyphIterator::applyInsertions() diff --git a/icu4c/source/layout/GlyphIterator.h b/icu4c/source/layout/GlyphIterator.h index 473c0143aa..2aef815489 100644 --- a/icu4c/source/layout/GlyphIterator.h +++ b/icu4c/source/layout/GlyphIterator.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -69,7 +69,7 @@ public: void setCursiveExitPoint(LEPoint &exitPoint); void setCursiveGlyph(); - LEGlyphID *insertGlyphs(le_int32 count); + LEGlyphID *insertGlyphs(le_int32 count, LEErrorCode& success); le_int32 applyInsertions(); private: diff --git a/icu4c/source/layout/GlyphPositioningTables.cpp b/icu4c/source/layout/GlyphPositioningTables.cpp index b9187b4a29..e2a83b0ec1 100644 --- a/icu4c/source/layout/GlyphPositioningTables.cpp +++ b/icu4c/source/layout/GlyphPositioningTables.cpp @@ -1,5 +1,5 @@ /* - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -18,12 +18,20 @@ U_NAMESPACE_BEGIN void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, + const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success, const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const { - GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder); + if (LE_FAILURE(success)) { + return; + } - processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance); + GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder); + if (processor.isBogus()) { + success = LE_MEMORY_ALLOCATION_ERROR; + return; + } + + processor.process(glyphStorage, glyphPositionAdjustments, rightToLeft, glyphDefinitionTableHeader, fontInstance, success); glyphPositionAdjustments->applyCursiveAdjustments(glyphStorage, rightToLeft, fontInstance); } diff --git a/icu4c/source/layout/GlyphPositioningTables.h b/icu4c/source/layout/GlyphPositioningTables.h index a07c8c2671..590488cd67 100644 --- a/icu4c/source/layout/GlyphPositioningTables.h +++ b/icu4c/source/layout/GlyphPositioningTables.h @@ -1,5 +1,5 @@ /* - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -28,7 +28,7 @@ struct GlyphPositioningTableHeader : public GlyphLookupTableHeader { void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, + const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success, const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const; }; diff --git a/icu4c/source/layout/GlyphPosnLookupProc.cpp b/icu4c/source/layout/GlyphPosnLookupProc.cpp index 6f923a1389..d45ecf99f5 100644 --- a/icu4c/source/layout/GlyphPosnLookupProc.cpp +++ b/icu4c/source/layout/GlyphPosnLookupProc.cpp @@ -1,5 +1,5 @@ /* - * (C) Copyright IBM Corp. 1998 - 2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998 - 2008 - All Rights Reserved * */ @@ -50,8 +50,13 @@ GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor() le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const + const LEFontInstance *fontInstance, + LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint32 delta = 0; switch(lookupType) @@ -111,7 +116,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l { const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable; - delta = subtable->process(this, glyphIterator, fontInstance); + delta = subtable->process(this, glyphIterator, fontInstance, success); break; } @@ -119,7 +124,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l { const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable; - delta = subtable->process(this, glyphIterator, fontInstance); + delta = subtable->process(this, glyphIterator, fontInstance, success); break; } @@ -127,7 +132,7 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *l { const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; - delta = subtable->process(this, lookupType, glyphIterator, fontInstance); + delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success); break; } diff --git a/icu4c/source/layout/GlyphPosnLookupProc.h b/icu4c/source/layout/GlyphPosnLookupProc.h index ee3606565d..135715c283 100644 --- a/icu4c/source/layout/GlyphPosnLookupProc.h +++ b/icu4c/source/layout/GlyphPosnLookupProc.h @@ -1,5 +1,5 @@ /* - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -32,7 +32,7 @@ public: virtual ~GlyphPositioningLookupProcessor(); virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const; + const LEFontInstance *fontInstance, LEErrorCode& success) const; protected: GlyphPositioningLookupProcessor(); diff --git a/icu4c/source/layout/GlyphSubstLookupProc.cpp b/icu4c/source/layout/GlyphSubstLookupProc.cpp index eb25680cce..c9a26f2648 100644 --- a/icu4c/source/layout/GlyphSubstLookupProc.cpp +++ b/icu4c/source/layout/GlyphSubstLookupProc.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -43,8 +43,12 @@ GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor() } le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, - GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const + GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint32 delta = 0; switch(lookupType) @@ -64,7 +68,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * { const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable; - delta = subtable->process(glyphIterator, fFilter); + delta = subtable->process(glyphIterator, success, fFilter); break; } @@ -88,7 +92,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * { const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable; - delta = subtable->process(this, glyphIterator, fontInstance); + delta = subtable->process(this, glyphIterator, fontInstance, success); break; } @@ -96,7 +100,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * { const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable; - delta = subtable->process(this, glyphIterator, fontInstance); + delta = subtable->process(this, glyphIterator, fontInstance, success); break; } @@ -104,7 +108,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable * { const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; - delta = subtable->process(this, lookupType, glyphIterator, fontInstance); + delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success); break; } diff --git a/icu4c/source/layout/GlyphSubstLookupProc.h b/icu4c/source/layout/GlyphSubstLookupProc.h index d8c5684a03..5e60b1231b 100644 --- a/icu4c/source/layout/GlyphSubstLookupProc.h +++ b/icu4c/source/layout/GlyphSubstLookupProc.h @@ -1,5 +1,5 @@ /* - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -33,7 +33,7 @@ public: virtual ~GlyphSubstitutionLookupProcessor(); virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const; + const LEFontInstance *fontInstance, LEErrorCode& success) const; protected: GlyphSubstitutionLookupProcessor(); diff --git a/icu4c/source/layout/GlyphSubstitutionTables.cpp b/icu4c/source/layout/GlyphSubstitutionTables.cpp index 661b30f3ab..9ea9b18b89 100644 --- a/icu4c/source/layout/GlyphSubstitutionTables.cpp +++ b/icu4c/source/layout/GlyphSubstitutionTables.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -17,13 +17,23 @@ U_NAMESPACE_BEGIN -le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, - const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const +le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, + le_bool rightToLeft, + LETag scriptTag, + LETag languageTag, + const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, + const LEGlyphFilter *filter, + const FeatureMap *featureMap, + le_int32 featureMapCount, + le_bool featureOrder, + LEErrorCode &success) const { - GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder); + if (LE_FAILURE(success)) { + return 0; + } - return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL); + GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder); + return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success); } U_NAMESPACE_END diff --git a/icu4c/source/layout/GlyphSubstitutionTables.h b/icu4c/source/layout/GlyphSubstitutionTables.h index 620da29c93..b899bee4bf 100644 --- a/icu4c/source/layout/GlyphSubstitutionTables.h +++ b/icu4c/source/layout/GlyphSubstitutionTables.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -25,9 +25,16 @@ struct GlyphDefinitionTableHeader; struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader { - le_int32 process(LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEGlyphFilter *filter, - const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const; + le_int32 process(LEGlyphStorage &glyphStorage, + le_bool rightToLeft, + LETag scriptTag, + LETag languageTag, + const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, + const LEGlyphFilter *filter, + const FeatureMap *featureMap, + le_int32 featureMapCount, + le_bool featureOrder, + LEErrorCode &success) const; }; enum GlyphSubstitutionSubtableTypes diff --git a/icu4c/source/layout/IndicLayoutEngine.cpp b/icu4c/source/layout/IndicLayoutEngine.cpp index ec83e73e46..6f514b28c0 100644 --- a/icu4c/source/layout/IndicLayoutEngine.cpp +++ b/icu4c/source/layout/IndicLayoutEngine.cpp @@ -1,7 +1,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -66,7 +66,7 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_ return 0; } - IndicReordering::adjustMPres(fMPreFixups, glyphStorage); + IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success); return retCount; } @@ -105,7 +105,12 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], // NOTE: assumes this allocates featureTags... // (probably better than doing the worst case stuff here...) - le_int32 outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups); + le_int32 outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success); + + if (LE_FAILURE(success)) { + LE_DELETE_ARRAY(outChars); + return 0; + } glyphStorage.adoptGlyphCount(outCharCount); return outCharCount; diff --git a/icu4c/source/layout/IndicReordering.cpp b/icu4c/source/layout/IndicReordering.cpp index cbd2b60b6f..2a68a0de50 100644 --- a/icu4c/source/layout/IndicReordering.cpp +++ b/icu4c/source/layout/IndicReordering.cpp @@ -418,13 +418,21 @@ le_int32 IndicReordering::findSyllable(const IndicClassTable *classTable, const le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le_int32 scriptCode, LEUnicode *outChars, LEGlyphStorage &glyphStorage, - MPreFixups **outMPreFixups) + MPreFixups **outMPreFixups, LEErrorCode& success) { + if (LE_FAILURE(success)) { + return 0; + } + MPreFixups *mpreFixups = NULL; const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode); if (classTable->scriptFlags & SF_MPRE_FIXUP) { mpreFixups = new MPreFixups(charCount); + if (mpreFixups == NULL) { + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } } IndicReorderingOutput output(outChars, glyphStorage, mpreFixups); @@ -752,10 +760,10 @@ le_int32 IndicReordering::reorder(const LEUnicode *chars, le_int32 charCount, le return output.getOutputIndex(); } -void IndicReordering::adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage) +void IndicReordering::adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success) { if (mpreFixups != NULL) { - mpreFixups->apply(glyphStorage); + mpreFixups->apply(glyphStorage, success); delete mpreFixups; } diff --git a/icu4c/source/layout/IndicReordering.h b/icu4c/source/layout/IndicReordering.h index abd1b72239..1027070c80 100644 --- a/icu4c/source/layout/IndicReordering.h +++ b/icu4c/source/layout/IndicReordering.h @@ -135,9 +135,9 @@ public: static le_int32 reorder(const LEUnicode *theChars, le_int32 charCount, le_int32 scriptCode, LEUnicode *outChars, LEGlyphStorage &glyphStorage, - MPreFixups **outMPreFixups); + MPreFixups **outMPreFixups, LEErrorCode& success); - static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage); + static void adjustMPres(MPreFixups *mpreFixups, LEGlyphStorage &glyphStorage, LEErrorCode& success); static const FeatureMap *getFeatureMap(le_int32 &count); diff --git a/icu4c/source/layout/LEGlyphStorage.cpp b/icu4c/source/layout/LEGlyphStorage.cpp index 42824c3611..ce82ae4f7e 100644 --- a/icu4c/source/layout/LEGlyphStorage.cpp +++ b/icu4c/source/layout/LEGlyphStorage.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1998-2006, International Business Machines + * Copyright (C) 1998-2008, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -109,6 +109,16 @@ void LEGlyphStorage::allocateGlyphArray(le_int32 initialGlyphCount, le_bool righ if (fInsertionList == NULL) { // FIXME: check this for failure? fInsertionList = new LEInsertionList(rightToLeft); + if (fInsertionList == NULL) { + LE_DELETE_ARRAY(fCharIndices); + fCharIndices = NULL; + + LE_DELETE_ARRAY(fGlyphs); + fGlyphs = NULL; + + success = LE_MEMORY_ALLOCATION_ERROR; + return; + } } } @@ -501,9 +511,9 @@ void LEGlyphStorage::adoptGlyphCount(le_int32 newGlyphCount) } // FIXME: add error checking? -LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount) +LEGlyphID *LEGlyphStorage::insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success) { - return fInsertionList->insert(atIndex, insertCount); + return fInsertionList->insert(atIndex, insertCount, success); } le_int32 LEGlyphStorage::applyInsertions() @@ -516,13 +526,31 @@ le_int32 LEGlyphStorage::applyInsertions() le_int32 newGlyphCount = fGlyphCount + growAmount; - fGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount); - fCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount); + LEGlyphID *newGlyphs = (LEGlyphID *) LE_GROW_ARRAY(fGlyphs, newGlyphCount); + if (newGlyphs == NULL) { + // Could not grow the glyph array + return fGlyphCount; + } - if (fAuxData != NULL) { - fAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount); + le_int32 *newCharIndices = (le_int32 *) LE_GROW_ARRAY(fCharIndices, newGlyphCount); + if (newCharIndices == NULL) { + // Could not grow the glyph array + return fGlyphCount; + } + + if (fAuxData != NULL) { + le_uint32 *newAuxData = (le_uint32 *) LE_GROW_ARRAY(fAuxData, newGlyphCount); + if (newAuxData == NULL) { + // could not grow the aux data array + return fGlyphCount; + } + fAuxData = (le_uint32 *)newAuxData; } + // Set grown arrays + fGlyphs = newGlyphs; + fCharIndices = newCharIndices; + fSrcIndex = fGlyphCount - 1; fDestIndex = newGlyphCount - 1; diff --git a/icu4c/source/layout/LEGlyphStorage.h b/icu4c/source/layout/LEGlyphStorage.h index 5e6abcd64b..0eecb46fbe 100644 --- a/icu4c/source/layout/LEGlyphStorage.h +++ b/icu4c/source/layout/LEGlyphStorage.h @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1998-2007, International Business Machines + * Copyright (C) 1998-2008, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -321,6 +321,7 @@ public: * * @param atIndex the index of the glyph to be replaced * @param insertCount the number of glyphs to replace it with + * @param success set to an error code if the auxillary data cannot be retrieved. * * @return the address at which to store the replacement glyphs. * @@ -328,7 +329,7 @@ public: * * @stable ICU 3.0 */ - LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount); + LEGlyphID *insertGlyphs(le_int32 atIndex, le_int32 insertCount, LEErrorCode& success); /** * This method causes all of the glyph insertions recorded by diff --git a/icu4c/source/layout/LEInsertionList.cpp b/icu4c/source/layout/LEInsertionList.cpp index b92cc47493..c64b8a198d 100644 --- a/icu4c/source/layout/LEInsertionList.cpp +++ b/icu4c/source/layout/LEInsertionList.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1998-2004, International Business Machines + * Copyright (C) 1998-2008, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -51,9 +51,17 @@ le_int32 LEInsertionList::getGrowAmount() return growAmount; } -LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count) +LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count, LEErrorCode &success) { + if (LE_FAILURE(success)) { + return 0; + } + InsertionRecord *insertion = (InsertionRecord *) LE_NEW_ARRAY(char, sizeof(InsertionRecord) + (count - ANY_NUMBER) * sizeof (LEGlyphID)); + if (insertion == NULL) { + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } insertion->position = position; insertion->count = count; diff --git a/icu4c/source/layout/LEInsertionList.h b/icu4c/source/layout/LEInsertionList.h index a894295280..68148b5248 100644 --- a/icu4c/source/layout/LEInsertionList.h +++ b/icu4c/source/layout/LEInsertionList.h @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1998-2006, International Business Machines + * Copyright (C) 1998-2008, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -83,13 +83,14 @@ public: * @param position the glyph at this position in the array will be * replaced by the new glyphs. * @param count the number of new glyphs + * @param success set to an error code if the auxillary data cannot be retrieved. * * @return the address of an array in which to store the new glyphs. This will * not be in the glyph array. * * @internal */ - LEGlyphID *insert(le_int32 position, le_int32 count); + LEGlyphID *insert(le_int32 position, le_int32 count, LEErrorCode &success); /** * Return the number of new glyphs that have been inserted. diff --git a/icu4c/source/layout/LayoutEngine.cpp b/icu4c/source/layout/LayoutEngine.cpp index 019fbffbd8..c27e8cd38a 100644 --- a/icu4c/source/layout/LayoutEngine.cpp +++ b/icu4c/source/layout/LayoutEngine.cpp @@ -141,6 +141,11 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCo fGlyphStorage = new LEGlyphStorage(); } +le_bool LayoutEngine::isBogus() +{ + return fGlyphStorage == NULL; +} + le_int32 LayoutEngine::getGlyphCount() const { return fGlyphStorage->getGlyphCount(); @@ -197,6 +202,11 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off if (canonGSUBTable->coversScript(scriptTag)) { CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance); + if (substitutionFilter == NULL) { + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } + const LEUnicode *inChars = &chars[offset]; LEUnicode *reordered = NULL; LEGlyphStorage fakeGlyphStorage; @@ -204,6 +214,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success); if (LE_FAILURE(success)) { + delete substitutionFilter; return 0; } @@ -214,6 +225,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off reordered = LE_NEW_ARRAY(LEUnicode, count); if (reordered == NULL) { + delete substitutionFilter; success = LE_MEMORY_ALLOCATION_ERROR; return 0; } @@ -225,6 +237,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off fakeGlyphStorage.allocateAuxData(success); if (LE_FAILURE(success)) { + delete substitutionFilter; return 0; } @@ -242,7 +255,12 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off LE_DELETE_ARRAY(reordered); } - outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE); + outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success); + + if (LE_FAILURE(success)) { + delete substitutionFilter; + return 0; + } out = (rightToLeft? outCharCount - 1 : 0); @@ -255,6 +273,13 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off glyphStorage.adoptCharIndicesArray(fakeGlyphStorage); outChars = LE_NEW_ARRAY(LEUnicode, outCharCount); + + if (outChars == NULL) { + delete substitutionFilter; + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } + for (i = 0; i < outCharCount; i += 1, out += dir) { outChars[out] = (LEUnicode) LE_GET_GLYPH(fakeGlyphStorage[i]); } @@ -598,6 +623,11 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan } } + if (result && result->isBogus()) { + delete result; + result = NULL; + } + if (result == NULL) { success = LE_MEMORY_ALLOCATION_ERROR; } diff --git a/icu4c/source/layout/LayoutEngine.h b/icu4c/source/layout/LayoutEngine.h index f7711504c8..51c6643f43 100644 --- a/icu4c/source/layout/LayoutEngine.h +++ b/icu4c/source/layout/LayoutEngine.h @@ -1,7 +1,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -132,6 +132,14 @@ protected: */ LayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags); + /** + * Returns true if the constructor failed, leaving the object in an + * inconsistent state. + * + * @internal + */ + le_bool isBogus(); + /** * This overrides the default no argument constructor to make it * difficult for clients to call it. Clients are expected to call diff --git a/icu4c/source/layout/LookupProcessor.cpp b/icu4c/source/layout/LookupProcessor.cpp index 6f26a13bed..233ddbaf54 100644 --- a/icu4c/source/layout/LookupProcessor.cpp +++ b/icu4c/source/layout/LookupProcessor.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2007 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -20,8 +20,12 @@ U_NAMESPACE_BEGIN le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const + const LEFontInstance *fontInstance, LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + le_uint16 lookupType = SWAPW(lookupTable->lookupType); le_uint16 subtableCount = SWAPW(lookupTable->subTableCount); le_int32 startPosition = glyphIterator->getCurrStreamPosition(); @@ -30,9 +34,9 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) { const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable); - delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance); + delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success); - if (delta > 0) { + if (delta > 0 && LE_FAILURE(success)) { return 1; } @@ -44,8 +48,12 @@ le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, Glyp le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, - const LEFontInstance *fontInstance) const + const LEFontInstance *fontInstance, LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + le_int32 glyphCount = glyphStorage.getGlyphCount(); if (lookupSelectArray == NULL) { @@ -67,7 +75,10 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj glyphIterator.reset(lookupFlags, selectMask); while (glyphIterator.findFeatureTag()) { - applyLookupTable(lookupTable, &glyphIterator, fontInstance); + applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); + if (LE_FAILURE(success)) { + return 0; + } } newGlyphCount = glyphIterator.applyInsertions(); @@ -78,12 +89,16 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj } le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, - const LEFontInstance *fontInstance) const + const LEFontInstance *fontInstance, LEErrorCode& success) const { + if (LE_FAILURE(success)) { + return 0; + } + const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex); le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags); GlyphIterator tempIterator(*glyphIterator, lookupFlags); - le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance); + le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success); return delta; } @@ -141,6 +156,9 @@ LookupProcessor::LookupProcessor(const char *baseAddress, requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex); lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount); + if (lookupSelectArray == NULL) { + return; + } for (int i = 0; i < lookupListCount; i += 1) { lookupSelectArray[i] = 0; @@ -171,6 +189,9 @@ LookupProcessor::LookupProcessor(const char *baseAddress, } lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences); + if (lookupOrderArray == NULL) { + return; + } for (le_int32 f = 0; f < featureMapCount; f += 1) { FeatureMap fm = featureMap[f]; @@ -260,6 +281,13 @@ LookupProcessor::LookupProcessor(const char *baseAddress, LookupProcessor::LookupProcessor() { + lookupOrderArray = NULL; + lookupSelectArray = NULL; +} + +le_bool LookupProcessor::isBogus() +{ + return lookupOrderArray && lookupSelectArray; } LookupProcessor::~LookupProcessor() diff --git a/icu4c/source/layout/LookupProcessor.h b/icu4c/source/layout/LookupProcessor.h index bc05ae63b7..c9a90f3127 100644 --- a/icu4c/source/layout/LookupProcessor.h +++ b/icu4c/source/layout/LookupProcessor.h @@ -1,7 +1,7 @@ /* * %W% %E% * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -33,15 +33,17 @@ struct LookupTable; class LookupProcessor : public UMemory { public: + le_bool isBogus(); + le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, - le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance) const; + le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const; - le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; - le_uint32 applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 subtableType, - GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const = 0; + GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const = 0; virtual ~LookupProcessor(); diff --git a/icu4c/source/layout/MPreFixups.cpp b/icu4c/source/layout/MPreFixups.cpp index 75791eed02..08ad7a75df 100644 --- a/icu4c/source/layout/MPreFixups.cpp +++ b/icu4c/source/layout/MPreFixups.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved * */ @@ -40,8 +40,12 @@ void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex) } } -void MPreFixups::apply(LEGlyphStorage &glyphStorage) +void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success) { + if (LE_FAILURE(success)) { + return; + } + for (le_int32 fixup = 0; fixup < fFixupCount; fixup += 1) { le_int32 baseIndex = fFixupData[fixup].fBaseIndex; le_int32 mpreIndex = fFixupData[fixup].fMPreIndex; @@ -65,6 +69,14 @@ void MPreFixups::apply(LEGlyphStorage &glyphStorage) le_int32 mpreDest = baseIndex - mpreCount; LEGlyphID *mpreSave = LE_NEW_ARRAY(LEGlyphID, mpreCount); le_int32 *indexSave = LE_NEW_ARRAY(le_int32, mpreCount); + + if (mpreSave == NULL || indexSave == NULL) { + LE_DELETE_ARRAY(mpreSave); + LE_DELETE_ARRAY(indexSave); + success = LE_MEMORY_ALLOCATION_ERROR; + return; + } + le_int32 i; for (i = 0; i < mpreCount; i += 1) { diff --git a/icu4c/source/layout/MPreFixups.h b/icu4c/source/layout/MPreFixups.h index 6053c088d2..18fefe0de9 100644 --- a/icu4c/source/layout/MPreFixups.h +++ b/icu4c/source/layout/MPreFixups.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 2002-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved * */ @@ -29,7 +29,7 @@ public: void add(le_int32 baseIndex, le_int32 mpreIndex); - void apply(LEGlyphStorage &glyphStorage); + void apply(LEGlyphStorage &glyphStorage, LEErrorCode& success); private: FixupData *fFixupData; diff --git a/icu4c/source/layout/MultipleSubstSubtables.cpp b/icu4c/source/layout/MultipleSubstSubtables.cpp index 450bf35bc9..f017722f86 100644 --- a/icu4c/source/layout/MultipleSubstSubtables.cpp +++ b/icu4c/source/layout/MultipleSubstSubtables.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -14,8 +14,12 @@ U_NAMESPACE_BEGIN -le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const +le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const { + if (LE_FAILURE(success)) { + return 0; + } + LEGlyphID glyph = glyphIterator->getCurrGlyphID(); // If there's a filter, we only want to do the @@ -62,7 +66,11 @@ le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, co } } - LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount); + LEGlyphID *newGlyphs = glyphIterator->insertGlyphs(glyphCount, success); + if (LE_FAILURE(success)) { + return 0; + } + le_int32 insert = 0, direction = 1; if (glyphIterator->isRightToLeft()) { diff --git a/icu4c/source/layout/MultipleSubstSubtables.h b/icu4c/source/layout/MultipleSubstSubtables.h index e29963c585..1d6c978ad1 100644 --- a/icu4c/source/layout/MultipleSubstSubtables.h +++ b/icu4c/source/layout/MultipleSubstSubtables.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -31,7 +31,7 @@ struct MultipleSubstitutionSubtable : GlyphSubstitutionSubtable le_uint16 sequenceCount; Offset sequenceTableOffsetArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; + le_uint32 process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const; }; U_NAMESPACE_END diff --git a/icu4c/source/layout/OpenTypeLayoutEngine.cpp b/icu4c/source/layout/OpenTypeLayoutEngine.cpp index c08eb69cb6..dcebb4442d 100644 --- a/icu4c/source/layout/OpenTypeLayoutEngine.cpp +++ b/icu4c/source/layout/OpenTypeLayoutEngine.cpp @@ -212,7 +212,7 @@ le_int32 OpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_int32 if (fGSUBTable != NULL) { count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, - fFeatureMap, fFeatureMapCount, fFeatureOrder); + fFeatureMap, fFeatureMapCount, fFeatureOrder, success); } return count; @@ -309,7 +309,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3 } #endif - fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, fFontInstance, + fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); float xAdjust = 0, yAdjust = 0; diff --git a/icu4c/source/layout/SubstitutionLookups.cpp b/icu4c/source/layout/SubstitutionLookups.cpp index fa6771ac1f..1fb281300e 100644 --- a/icu4c/source/layout/SubstitutionLookups.cpp +++ b/icu4c/source/layout/SubstitutionLookups.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -28,18 +28,23 @@ void SubstitutionLookup::applySubstitutionLookups( le_uint16 substCount, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, - le_int32 position) + le_int32 position, + LEErrorCode& success) { + if (LE_FAILURE(success)) { + return; + } + GlyphIterator tempIterator(*glyphIterator); - for (le_uint16 subst = 0; subst < substCount; subst += 1) { + for (le_uint16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) { le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex); le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex); tempIterator.setCurrStreamPosition(position); tempIterator.next(sequenceIndex); - lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance); + lookupProcessor->applySingleLookup(lookupListIndex, &tempIterator, fontInstance, success); } } diff --git a/icu4c/source/layout/SubstitutionLookups.h b/icu4c/source/layout/SubstitutionLookups.h index 3365850642..582b6f661e 100644 --- a/icu4c/source/layout/SubstitutionLookups.h +++ b/icu4c/source/layout/SubstitutionLookups.h @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved * */ @@ -35,7 +35,8 @@ struct SubstitutionLookup le_uint16 substCount, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, - le_int32 position); + le_int32 position, + LEErrorCode& success); }; U_NAMESPACE_END diff --git a/icu4c/source/layoutex/ParagraphLayout.cpp b/icu4c/source/layoutex/ParagraphLayout.cpp index 694f2e23e2..3e8572c016 100644 --- a/icu4c/source/layoutex/ParagraphLayout.cpp +++ b/icu4c/source/layoutex/ParagraphLayout.cpp @@ -366,9 +366,17 @@ ParagraphLayout::ParagraphLayout(const LEUnicode chars[], le_int32 count, fStyleRunInfo[run].engine = LayoutEngine::layoutEngineFactory(fStyleRunInfo[run].font, fStyleRunInfo[run].script, getLanguageCode(fStyleRunInfo[run].locale), layoutStatus); + if (LE_FAILURE(layoutStatus)) { + status = layoutStatus; + return; + } fStyleRunInfo[run].glyphCount = fStyleRunInfo[run].engine->layoutChars(fChars, runStart, fStyleRunLimits[run] - runStart, fCharCount, fStyleRunInfo[run].level & 1, 0, 0, layoutStatus); + if (LE_FAILURE(layoutStatus)) { + status = layoutStatus; + return; + } runStart = fStyleRunLimits[run]; styleIndices += styleCount;