]> 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 a864b2968906d6a1dd2cfe50b9addc3e111d7efc..b54e20c8ef371ac2fd6734c13b2cca2ca6c039ce 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * (C) Copyright IBM Corp.  and others 1998-2014 - All Rights Reserved
+ * (C) Copyright IBM Corp.  and others 1998-2015 - All Rights Reserved
  *
  */
 
@@ -44,14 +44,14 @@ le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphS
     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;
@@ -64,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;
@@ -92,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;
@@ -120,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);
@@ -141,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);
@@ -162,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);
@@ -183,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);
@@ -204,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];
@@ -229,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];
@@ -254,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];
@@ -279,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];
@@ -304,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];
 
@@ -326,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];
 
@@ -348,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];
 
@@ -370,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];