]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/cpdtrans.cpp
ICU-62107.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / cpdtrans.cpp
index afd1fdbf8bdcfedfe374da26121e31c8736fb5f0..db2ddb703481f6c6e3f00e7a18b04f302885d9ef 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1999-2006, International Business Machines
+*   Copyright (C) 1999-2011, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
@@ -24,8 +26,6 @@
 static const UChar ID_DELIM = 0x003B; /*;*/
 static const UChar NEWLINE  = 10;
 
-// Empty string
-static const UChar EMPTY[] = {0}; //""
 static const UChar COLON_COLON[] = {0x3A, 0x3A, 0}; //"::"
 
 U_NAMESPACE_BEGIN
@@ -110,7 +110,7 @@ CompoundTransliterator::CompoundTransliterator(const UnicodeString& newID,
 CompoundTransliterator::CompoundTransliterator(UVector& list,
                                                UParseError& /*parseError*/,
                                                UErrorCode& status) :
-    Transliterator(EMPTY, NULL),
+    Transliterator(UnicodeString(), NULL),
     trans(0), numAnonymousRBTs(0)
 {
     // TODO add code for parseError...currently unused, but
@@ -123,7 +123,7 @@ CompoundTransliterator::CompoundTransliterator(UVector& list,
                                                int32_t anonymousRBTs,
                                                UParseError& /*parseError*/,
                                                UErrorCode& status) :
-    Transliterator(EMPTY, NULL),
+    Transliterator(UnicodeString(), NULL),
     trans(0), numAnonymousRBTs(anonymousRBTs)
 {
     init(list, UTRANS_FORWARD, FALSE, status);
@@ -280,20 +280,41 @@ void CompoundTransliterator::freeTransliterators(void) {
  * Assignment operator.
  */
 CompoundTransliterator& CompoundTransliterator::operator=(
-                                             const CompoundTransliterator& t) {
+                                             const CompoundTransliterator& t)
+{
     Transliterator::operator=(t);
-    int32_t i;
-    for (i=0; i<count; ++i) {
-        delete trans[i];
-        trans[i] = 0;
+    int32_t i = 0;
+    UBool failed = FALSE;
+    if (trans != NULL) {
+        for (i=0; i<count; ++i) {
+            delete trans[i];
+            trans[i] = 0;
+        }
     }
     if (t.count > count) {
-        uprv_free(trans);
+        if (trans != NULL) {
+            uprv_free(trans);
+        }
         trans = (Transliterator **)uprv_malloc(t.count * sizeof(Transliterator *));
     }
     count = t.count;
-    for (i=0; i<count; ++i) {
-        trans[i] = t.trans[i]->clone();
+    if (trans != NULL) {
+        for (i=0; i<count; ++i) {
+            trans[i] = t.trans[i]->clone();
+            if (trans[i] == NULL) {
+                failed = TRUE;
+                break;
+            }
+        }
+    }
+
+    // if memory allocation failed delete backwards trans array
+    if (failed && i > 0) {
+        int32_t n;
+        for (n = i-1; n >= 0; n--) {
+            uprv_free(trans[n]);
+            trans[n] = NULL;
+        }
     }
     numAnonymousRBTs = t.numAnonymousRBTs;
     return *this;
@@ -326,8 +347,25 @@ const Transliterator& CompoundTransliterator::getTransliterator(int32_t index) c
 void CompoundTransliterator::setTransliterators(Transliterator* const transliterators[],
                                                 int32_t transCount) {
     Transliterator** a = (Transliterator **)uprv_malloc(transCount * sizeof(Transliterator *));
-    for (int32_t i=0; i<transCount; ++i) {
+    if (a == NULL) {
+        return;
+    }
+    int32_t i = 0;
+    UBool failed = FALSE;
+    for (i=0; i<transCount; ++i) {
         a[i] = transliterators[i]->clone();
+        if (a[i] == NULL) {
+            failed = TRUE;
+            break;
+        }
+    }
+    if (failed && i > 0) {
+        int32_t n;
+        for (n = i-1; n >= 0; n--) {
+            uprv_free(a[n]);
+            a[n] = NULL;
+        }
+        return;
     }
     adoptTransliterators(a, transCount);
 }
@@ -366,7 +404,7 @@ UnicodeString& CompoundTransliterator::toRules(UnicodeString& rulesSource,
         // If we are a compound RBT and if we have a global
         // filter, then emit it at the top.
         UnicodeString pat;
-        rulesSource.append(COLON_COLON).append(getFilter()->toPattern(pat, escapeUnprintable)).append(ID_DELIM);
+        rulesSource.append(COLON_COLON, 2).append(getFilter()->toPattern(pat, escapeUnprintable)).append(ID_DELIM);
     }
     for (int32_t i=0; i<count; ++i) {
         UnicodeString rule;
@@ -375,9 +413,9 @@ UnicodeString& CompoundTransliterator::toRules(UnicodeString& rulesSource,
         // ::BEGIN/::END blocks) are given IDs that begin with
         // "%Pass": use toRules() to write all the rules to the output
         // (and insert "::Null;" if we have two in a row)
-        if (trans[i]->getID().startsWith(PASS_STRING)) {
+        if (trans[i]->getID().startsWith(PASS_STRING, 5)) {
             trans[i]->toRules(rule, escapeUnprintable);
-            if (numAnonymousRBTs > 1 && i > 0 && trans[i - 1]->getID().startsWith(PASS_STRING))
+            if (numAnonymousRBTs > 1 && i > 0 && trans[i - 1]->getID().startsWith(PASS_STRING, 5))
                 rule = UNICODE_STRING_SIMPLE("::Null;") + rule;
 
         // we also use toRules() on CompoundTransliterators (which we