]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/IndicRearrangementProcessor2.cpp
ICU-57132.0.1.tar.gz
[apple/icu.git] / icuSources / layout / IndicRearrangementProcessor2.cpp
index b7849e3a65ff8c80711efdea9e90262d8c491c67..b54e20c8ef371ac2fd6734c13b2cca2ca6c039ce 100644 (file)
@@ -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)
 
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
 
-IndicRearrangementProcessor2::IndicRearrangementProcessor2(const MorphSubtableHeader2 *morphSubtableHeader)
-  : StateTableProcessor2(morphSubtableHeader)
+IndicRearrangementProcessor2::IndicRearrangementProcessor2(
+      const LEReferenceTo<MorphSubtableHeader2> &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()
 }
 
 IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
@@ -35,21 +35,23 @@ void IndicRearrangementProcessor2::beginStateTable()
     lastGlyph = 0;
 }
 
     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) {
     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) {
     }
 
     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;
 
     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;
 {
     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)
     {
 
     switch(verb)
     {
-    case irvNoAction:
-        break;
-
     case irvxA:
     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;
         a = glyphStorage[firstGlyph];
         ia = glyphStorage.getCharIndex(firstGlyph, success);
         x = firstGlyph + 1;
@@ -90,6 +103,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvDx:
         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;
         d = glyphStorage[lastGlyph];
         id = glyphStorage.getCharIndex(lastGlyph, success);
         x = lastGlyph - 1;
@@ -118,6 +136,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
         
     case irvxAB:
         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);
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
         ia = glyphStorage.getCharIndex(firstGlyph, success);
@@ -139,6 +162,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvxBA:
         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);
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
         ia = glyphStorage.getCharIndex(firstGlyph, success);
@@ -160,6 +188,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvCDx:
         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);
         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:
         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);
         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:
         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];
         a = glyphStorage[firstGlyph];
         c = glyphStorage[lastGlyph - 1];
         d = glyphStorage[lastGlyph];
@@ -227,6 +270,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break; 
 
     case irvDCxA:
         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];
         a = glyphStorage[firstGlyph];
         c = glyphStorage[lastGlyph - 1];
         d = glyphStorage[lastGlyph];
@@ -252,6 +300,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break; 
 
     case irvDxAB:
         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];
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
         d = glyphStorage[lastGlyph];
@@ -277,6 +330,11 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvDxBA:
         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];
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
         d = glyphStorage[lastGlyph];
@@ -302,6 +360,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvCDxAB:
         break;
 
     case irvCDxAB:
+        if (lastGlyph - firstGlyph < 3) {
+            success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+            break;
+        }
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
 
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
 
@@ -324,6 +386,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvCDxBA:
         break;
 
     case irvCDxBA:
+        if (lastGlyph - firstGlyph < 3) {
+            success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+            break;
+        }
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
 
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
 
@@ -346,6 +412,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvDCxAB:
         break;
 
     case irvDCxAB:
+        if (lastGlyph - firstGlyph < 3) {
+            success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+            break;
+        }
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
 
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
 
@@ -368,6 +438,10 @@ void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphSt
         break;
 
     case irvDCxBA:
         break;
 
     case irvDCxBA:
+        if (lastGlyph - firstGlyph < 3) {
+            success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+            break;
+        }
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];
 
         a = glyphStorage[firstGlyph];
         b = glyphStorage[firstGlyph + 1];