php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #61860
Patch grapheme_util.c revision 2012-04-26 20:19 UTC by poinsot dot julien at gmail dot com

Patch grapheme_util.c for intl Bug #61860

Patch version 2012-04-26 20:19 UTC

Return to Bug #61860 | Download this patch
Patch Revisions:

Developer: poinsot.julien@gmail.com

diff --git a/ext/intl/grapheme/grapheme_util.c b/ext/intl/grapheme/grapheme_util.c
index 9200855..c347e95 100755
--- a/ext/intl/grapheme/grapheme_util.c
+++ b/ext/intl/grapheme/grapheme_util.c
@@ -47,6 +47,44 @@ grapheme_close_global_iterator( TSRMLS_D )
 }
 /* }}} */
 
+static int32_t utf16_simple_case_folding(UChar *dst, int32_t dst_len, const UChar *src, int32_t src_len, UErrorCode *status)
+{
+    UChar32 c;
+    int cp_len;
+    int32_t i, ret;
+    uint32_t options;
+
+    i = ret = 0;
+    options = /*INTL_G(turkic_casefolding) ? U_FOLD_CASE_EXCLUDE_SPECIAL_I :*/ U_FOLD_CASE_DEFAULT;
+    if (NULL != dst) {
+        while (i < src_len && dst_len > 0) {
+            U16_NEXT(src, i, src_len, c);
+            c = u_foldCase(c, options);
+            cp_len = U16_LENGTH(c);
+            if (dst_len < cp_len) {
+                break;
+            }
+            U16_APPEND_UNSAFE(dst, ret, c);
+            dst_len -= cp_len;
+        }
+        if (0 == dst_len) {
+            *status = U_STRING_NOT_TERMINATED_WARNING;
+        } else {
+            dst[ret] = 0;
+        }
+    }
+    if (i < src_len) {
+        *status = U_BUFFER_OVERFLOW_ERROR;
+        while (i < src_len) {
+            U16_NEXT(src, i, src_len, c);
+            c = u_foldCase(c, options);
+            ret += U16_LENGTH(c);
+        }
+    }
+
+    return ret;
+}
+
 /* {{{ grapheme_intl_case_fold: convert string to lowercase */
 void
 grapheme_intl_case_fold(UChar** ptr_to_free, UChar **str, int32_t *str_len, UErrorCode *pstatus )
@@ -55,11 +93,11 @@ grapheme_intl_case_fold(UChar** ptr_to_free, UChar **str, int32_t *str_len, UErr
     int32_t dest_len, size_required;
 
     /* allocate a destination string that is a bit larger than the src, hoping that is enough */
-    dest_len = (*str_len) + ( *str_len / 10 );
+    dest_len = (*str_len) + ( *str_len / 10 ) + 1; // assume we have enough for '\0'
     dest = (UChar*) eumalloc(dest_len);
 
     *pstatus = U_ZERO_ERROR;
-    size_required = u_strFoldCase(dest, dest_len, *str, *str_len, U_FOLD_CASE_DEFAULT, pstatus);
+    size_required = utf16_simple_case_folding(dest, dest_len, *str, *str_len, pstatus);
 
     dest_len = size_required;
 
@@ -68,7 +106,7 @@ grapheme_intl_case_fold(UChar** ptr_to_free, UChar **str, int32_t *str_len, UErr
         dest = (UChar*) eurealloc(dest, dest_len);
 
         *pstatus = U_ZERO_ERROR;
-        size_required = u_strFoldCase(dest, dest_len, *str, *str_len, U_FOLD_CASE_DEFAULT, pstatus);
+        size_required = utf16_simple_case_folding(dest, dest_len, *str, *str_len, pstatus);
     }
 
     if ( U_FAILURE(*pstatus) ) {
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 18:02:13 2014 UTC