X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/51004dcb01e06fef634b61be77ed73dd61cb6db9..ef6cf650f4a75c3f97de06b51fa104f2069b9ea2:/icuSources/layout/IndicRearrangementProcessor2.cpp?ds=sidebyside diff --git a/icuSources/layout/IndicRearrangementProcessor2.cpp b/icuSources/layout/IndicRearrangementProcessor2.cpp index b7849e3a..b54e20c8 100644 --- a/icuSources/layout/IndicRearrangementProcessor2.cpp +++ b/icuSources/layout/IndicRearrangementProcessor2.cpp @@ -1,6 +1,6 @@ /* * - * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * (C) Copyright IBM Corp. and others 1998-2015 - All Rights Reserved * */ @@ -18,11 +18,11 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2) -IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader) - : StateTableProcessor2(morphSubtableHeader) +IndicRearrangementProcessor2::IndicRearrangementProcessor2( + const LEReferenceTo &morphSubtableHeader, LEErrorCode &success) + : StateTableProcessor2(morphSubtableHeader, success), entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY), + indicRearrangementSubtableHeader(morphSubtableHeader, success) { - indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader2 *) morphSubtableHeader; - entryTable = (const IndicRearrangementStateEntry2 *) ((char *) &stateTableHeader->stHeader + entryTableOffset); } IndicRearrangementProcessor2::~IndicRearrangementProcessor2() @@ -35,21 +35,23 @@ void IndicRearrangementProcessor2::beginStateTable() lastGlyph = 0; } -le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index) +le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, + EntryTableIndex2 index, LEErrorCode &success) { - const IndicRearrangementStateEntry2 *entry = &entryTable[index]; + const IndicRearrangementStateEntry2 *entry = entryTable.getAlias(index, success); + if (LE_FAILURE(success)) return 0; // TODO - what to return in bad state? le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags); if (flags & irfMarkFirst) { - firstGlyph = currGlyph; + firstGlyph = (le_uint32)currGlyph; } if (flags & irfMarkLast) { - lastGlyph = currGlyph; + lastGlyph = (le_uint32)currGlyph; } - doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask)); + doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask), success); if (!(flags & irfDontAdvance)) { currGlyph += dir; @@ -62,18 +64,29 @@ void IndicRearrangementProcessor2::endStateTable() { } -void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const +void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb, LEErrorCode &success) const { LEGlyphID a, b, c, d; le_int32 ia, ib, ic, id, ix, x; - LEErrorCode success = LE_NO_ERROR; + + if (LE_FAILURE(success)) return; + + if (verb == irvNoAction) { + return; + } + if (firstGlyph > lastGlyph) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + return; + } switch(verb) { - case irvNoAction: - break; - case irvxA: + if (firstGlyph == lastGlyph) break; + if (firstGlyph + 1 < firstGlyph) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; ia = glyphStorage.getCharIndex(firstGlyph, success); x = firstGlyph + 1; @@ -90,6 +103,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvDx: + if (firstGlyph == lastGlyph) break; + if (lastGlyph - 1 > lastGlyph) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } d = glyphStorage[lastGlyph]; id = glyphStorage.getCharIndex(lastGlyph, success); x = lastGlyph - 1; @@ -118,6 +136,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvxAB: + if ((firstGlyph + 2 < firstGlyph) || + (lastGlyph - firstGlyph < 1)) { // difference == 1 is a no-op, < 1 is an error. + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1]; ia = glyphStorage.getCharIndex(firstGlyph, success); @@ -139,6 +162,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvxBA: + if ((firstGlyph + 2 < firstGlyph) || + (lastGlyph - firstGlyph < 1)) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1]; ia = glyphStorage.getCharIndex(firstGlyph, success); @@ -160,6 +188,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvCDx: + if ((lastGlyph - 2 > lastGlyph) || + (lastGlyph - firstGlyph < 1)) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } c = glyphStorage[lastGlyph - 1]; d = glyphStorage[lastGlyph]; ic = glyphStorage.getCharIndex(lastGlyph - 1, success); @@ -181,6 +214,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvDCx: + if ((lastGlyph - 2 > lastGlyph) || + (lastGlyph - firstGlyph < 1)) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } c = glyphStorage[lastGlyph - 1]; d = glyphStorage[lastGlyph]; ic = glyphStorage.getCharIndex(lastGlyph - 1, success); @@ -202,6 +240,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvCDxA: + if ((lastGlyph - 2 > lastGlyph) || + (lastGlyph - firstGlyph < 2)) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; c = glyphStorage[lastGlyph - 1]; d = glyphStorage[lastGlyph]; @@ -227,6 +270,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvDCxA: + if ((lastGlyph - 2 > lastGlyph) || + (lastGlyph - firstGlyph < 2)) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; c = glyphStorage[lastGlyph - 1]; d = glyphStorage[lastGlyph]; @@ -252,6 +300,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvDxAB: + if ((firstGlyph + 2 < firstGlyph) || + (lastGlyph - firstGlyph < 2)) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1]; d = glyphStorage[lastGlyph]; @@ -277,6 +330,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvDxBA: + if ((firstGlyph + 2 < firstGlyph) || + (lastGlyph - firstGlyph < 2)) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1]; d = glyphStorage[lastGlyph]; @@ -302,6 +360,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvCDxAB: + if (lastGlyph - firstGlyph < 3) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1]; @@ -324,6 +386,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvCDxBA: + if (lastGlyph - firstGlyph < 3) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1]; @@ -346,6 +412,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvDCxAB: + if (lastGlyph - firstGlyph < 3) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1]; @@ -368,6 +438,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt break; case irvDCxBA: + if (lastGlyph - firstGlyph < 3) { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + break; + } a = glyphStorage[firstGlyph]; b = glyphStorage[firstGlyph + 1];