]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/tridpars.cpp
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / i18n / tridpars.cpp
index 3aadb70c0d9ed54bc48a16f084ff63902a4536fc..31bb034d6bbe862a49103754ba31de726c9ae70b 100644 (file)
@@ -1,6 +1,6 @@
 /*
 **********************************************************************
-*   Copyright (c) 2002-2004, International Business Machines Corporation
+*   Copyright (c) 2002-2008, International Business Machines Corporation
 *   and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
@@ -33,7 +33,7 @@ static const UChar VARIANT_SEP = 0x002F; // /
 static const UChar OPEN_REV    = 0x0028; // (
 static const UChar CLOSE_REV   = 0x0029; // )
 
-static const UChar EMPTY[]     = {0}; // ""
+//static const UChar EMPTY[]     = {0}; // ""
 static const UChar ANY[]       = {65,110,121,0}; // "Any"
 static const UChar ANY_NULL[]  = {65,110,121,45,78,117,108,108,0}; // "Any-Null"
 
@@ -146,6 +146,13 @@ TransliteratorIDParser::parseSingleID(const UnicodeString& id, int32_t& pos,
         if (dir == FORWARD) {
             SingleID* b = specsToID(specsB, FORWARD);
             single = specsToID(specsA, FORWARD);
+            // Null pointers check
+            if (b == NULL || single == NULL) {
+               delete b;
+               delete single;
+               status = U_MEMORY_ALLOCATION_ERROR;
+               return NULL;
+            }
             single->canonID.append(OPEN_REV)
                 .append(b->canonID).append(CLOSE_REV);
             if (specsA != NULL) {
@@ -155,6 +162,13 @@ TransliteratorIDParser::parseSingleID(const UnicodeString& id, int32_t& pos,
         } else {
             SingleID* a = specsToID(specsA, FORWARD);
             single = specsToID(specsB, FORWARD);
+            // Check for null pointer.
+            if (a == NULL || single == NULL) {
+               delete a;
+               delete single;
+               status = U_MEMORY_ALLOCATION_ERROR;
+               return NULL;
+            }
             single->canonID.append(OPEN_REV)
                 .append(a->canonID).append(CLOSE_REV);
             if (specsB != NULL) {
@@ -172,6 +186,11 @@ TransliteratorIDParser::parseSingleID(const UnicodeString& id, int32_t& pos,
                 single = specsToID(specsA, REVERSE);
             }
         }
+        // Check for NULL pointer
+        if (single == NULL) {
+               status = U_MEMORY_ALLOCATION_ERROR;
+               return NULL;
+        }
         single->filter = specsA->filter;
     }
 
@@ -203,7 +222,9 @@ TransliteratorIDParser::parseFilterID(const UnicodeString& id, int32_t& pos) {
 
     // Assemble return results
     SingleID* single = specsToID(specs, FORWARD);
-    single->filter = specs->filter;
+    if (single != NULL) {
+        single->filter = specs->filter;
+    }
     delete specs;
     return single;
 }
@@ -437,22 +458,13 @@ UBool TransliteratorIDParser::parseCompoundID(const UnicodeString& id, int32_t d
  * the reverse.  THIS MAY RESULT IN AN EMPTY VECTOR.  Convert
  * SingleID entries to actual transliterators.
  *
- * Also, optionally, insert the given transliterator at the given
- * position.  This effectively happens before anything else.
- *
  * @param list vector of SingleID objects.  On exit, vector
  * of one or more Transliterators.
- * @param insert Transliterator to insert, or NULL if none.
- * Adopted.
- * @param insertIndex index from 0..list.size()-1, at which
- * to place 'insert', or -1 if none.
  * @return new value of insertIndex.  The index will shift if
  * there are empty items, like "(Lower)", with indices less than
  * insertIndex.
  */
-int32_t TransliteratorIDParser::instantiateList(UVector& list,
-                                                Transliterator* insert,
-                                                int32_t insertIndex,
+void TransliteratorIDParser::instantiateList(UVector& list,
                                                 UErrorCode& ec) {
     UVector tlist(ec);
     if (U_FAILURE(ec)) {
@@ -463,15 +475,6 @@ int32_t TransliteratorIDParser::instantiateList(UVector& list,
     Transliterator* t;
     int32_t i;
     for (i=0; i<=list.size(); ++i) { // [sic]: i<=list.size()
-        if (insertIndex == i) {
-            insertIndex = tlist.size();
-            tlist.addElement(insert, ec);
-            if (U_FAILURE(ec)) {
-                goto RETURN;
-            }
-            insert = NULL;
-        }
-
         // We run the loop too long by one, so we can
         // do an insert after the last element
         if (i==list.size()) {
@@ -525,9 +528,7 @@ int32_t TransliteratorIDParser::instantiateList(UVector& list,
         }
     }
 
-    delete insert; // Clean up in case of failure
     list.setDeleter(save);
-    return insertIndex;
 }
 
 /**
@@ -601,6 +602,10 @@ void TransliteratorIDParser::STVtoID(const UnicodeString& source,
     if (variant.length() != 0) {
         id.append(VARIANT_SEP).append(variant);
     }
+    // NUL-terminate the ID string for getTerminatedBuffer.
+    // This prevents valgrind and Purify warnings.
+    id.append((UChar)0);
+    id.truncate(id.length()-1);
 }
 
 /**
@@ -652,9 +657,19 @@ void TransliteratorIDParser::registerSpecialInverse(const UnicodeString& target,
     umtx_init(&LOCK);
     Mutex lock(&LOCK);
 
-    SPECIAL_INVERSES->put(target, new UnicodeString(inverseTarget), status);
+    UnicodeString *tempus = new UnicodeString(inverseTarget);  // Used for null pointer check before usage.
+    if (tempus == NULL) {
+       status = U_MEMORY_ALLOCATION_ERROR;
+       return;
+    }
+    SPECIAL_INVERSES->put(target, tempus, status);
     if (bidirectional) {
-        SPECIAL_INVERSES->put(inverseTarget, new UnicodeString(target), status);
+       tempus = new UnicodeString(target);
+       if (tempus == NULL) {
+               status = U_MEMORY_ALLOCATION_ERROR;
+               return;
+       }
+        SPECIAL_INVERSES->put(inverseTarget, tempus, status);
     }
 }
 
@@ -889,6 +904,11 @@ void TransliteratorIDParser::init(UErrorCode &status) {
     }
 
     Hashtable* special_inverses = new Hashtable(TRUE, status);
+    // Null pointer check
+    if (special_inverses == NULL) {
+       status = U_MEMORY_ALLOCATION_ERROR;
+       return;
+    }
     special_inverses->setValueDeleter(uhash_deleteUnicodeString);
 
     umtx_init(&LOCK);
@@ -898,7 +918,7 @@ void TransliteratorIDParser::init(UErrorCode &status) {
         special_inverses = NULL;
     }
     umtx_unlock(&LOCK);
-    delete special_inverses;
+    delete special_inverses; /*null instance*/
 
     ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, transliterator_cleanup);
 }