]> granicus.if.org Git - php/commitdiff
- Unicode impl of {add,strip}slashes()
authorRolland Santimano <rolland@php.net>
Wed, 28 Sep 2005 09:22:08 +0000 (09:22 +0000)
committerRolland Santimano <rolland@php.net>
Wed, 28 Sep 2005 09:22:08 +0000 (09:22 +0000)
ext/standard/php_string.h
ext/standard/string.c

index 6fcc9ad4bed8d10687c970fe30cd1471d7dc4a3e..d1261280083de92083f705fdda2a2a6702f534b9 100644 (file)
@@ -120,10 +120,13 @@ PHPAPI char *php_strtolower(char *s, size_t len);
 PHPAPI UChar *php_u_strtoupper(UChar **s, int32_t *len, const char *locale);
 PHPAPI UChar *php_u_strtolower(UChar **s, int32_t *len, const char *locale);
 PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen);
+PHPAPI UChar *php_u_addslashes(UChar *str, int32_t length, int32_t *new_length, int freeit TSRMLS_DC);
+PHPAPI UChar *php_u_addslashes_ex(UChar *str, int32_t length, int32_t *new_length, int freeit, int ignore_sybase TSRMLS_DC);
 PHPAPI char *php_addslashes(char *str, int length, int *new_length, int freeit TSRMLS_DC);
 PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int freeit, int ignore_sybase TSRMLS_DC);
 PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int freeit, char *what, int wlength TSRMLS_DC);
 PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC);
+PHPAPI void php_u_stripslashes(UChar *str, int32_t *len TSRMLS_DC);
 PHPAPI void php_stripcslashes(char *str, int *len);
 PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len TSRMLS_DC);
 PHPAPI size_t php_dirname(char *str, size_t len);
index 09d68c112377d843956e01bc9b1c4cb4c814e57d..638d2be0ffe3e9d9e57cafa0b183dcb278328700 100644 (file)
@@ -3427,6 +3427,66 @@ PHP_FUNCTION(similar_text)
 }
 /* }}} */
 
+/* {{{ php_u_stripslashes
+ *
+ * be careful, this edits the string in-place */
+PHPAPI void php_u_stripslashes(UChar *str, int32_t *len TSRMLS_DC)
+{
+       int32_t tmp_len = 0, i = 0;
+       UChar32 ch1, ch2;
+
+       ch1 = -1; ch2 = -1;
+       if (PG(magic_quotes_sybase)) {
+               while (i < *len) {
+                       U16_NEXT(str, i, *len, ch1);
+                       if (ch1 == '\'') {
+                               tmp_len += zend_codepoint_to_uchar(ch1, str+tmp_len);
+                               if (i < *len) {
+                                       U16_NEXT(str, i, *len, ch2);
+                                       if (ch2 != '\'') {
+                                               tmp_len += zend_codepoint_to_uchar(ch2, str+tmp_len);
+                                       }
+                               }
+                       } else if (ch1 == '\\') {
+                               if (i < *len) {
+                                       U16_NEXT(str, i, *len, ch2);
+                                       if (ch2 == '0') {
+                                               tmp_len += zend_codepoint_to_uchar('\0', str+tmp_len);
+                                       } else {
+                                               tmp_len += zend_codepoint_to_uchar(ch1, str+tmp_len);
+                                               tmp_len += zend_codepoint_to_uchar(ch2, str+tmp_len);
+                                       }
+                               } else {
+                                       tmp_len += zend_codepoint_to_uchar(ch1, str+tmp_len);
+                               }
+                       } else {
+                               tmp_len += zend_codepoint_to_uchar(ch1, str+tmp_len);
+                       }
+               }
+       } else {
+               while (i < *len) {
+                       U16_NEXT(str, i, *len, ch1);
+                       if (ch1 == '\\') {
+                               if (i < *len) {
+                                       U16_NEXT(str, i, *len, ch2);
+                                       if (ch2 == '0') {
+                                               tmp_len += zend_codepoint_to_uchar('\0', str+tmp_len);
+                                       } else {
+                                               tmp_len += zend_codepoint_to_uchar(ch2, str+tmp_len);
+                                       }
+                               }
+                       } else {
+                               tmp_len += zend_codepoint_to_uchar(ch1, str+tmp_len);
+                       }
+               }
+       }
+       *(str+tmp_len) = 0;
+       str = eurealloc(str, tmp_len+1);
+       *len = tmp_len;
+       return;
+}
+/* }}} */
+
 /* {{{ php_stripslashes
  *
  * be careful, this edits the string in-place */
@@ -3531,20 +3591,35 @@ PHP_FUNCTION(addcslashes)
 PHP_FUNCTION(addslashes)
 {
        zval **str;
+       void *tmp = NULL;
+       int32_t tmp_len = 0;
 
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_string_ex(str);
+       convert_to_text_ex(str);
 
-       if (Z_STRLEN_PP(str) == 0) {
+       if (Z_TYPE_PP(str) == IS_UNICODE && Z_USTRLEN_PP(str) == 0) {
+               RETURN_EMPTY_UNICODE();
+       } else if (Z_TYPE_PP(str) == IS_BINARY && Z_BINLEN_PP(str) == 0) {
+               RETURN_EMPTY_BINARY();
+       } else if (Z_TYPE_PP(str) == IS_STRING && Z_STRLEN_PP(str) == 0) {
                RETURN_EMPTY_STRING();
        }
 
-       RETURN_STRING(php_addslashes(Z_STRVAL_PP(str),
-                                    Z_STRLEN_PP(str), 
-                                    &Z_STRLEN_P(return_value), 0 
-                                    TSRMLS_CC), 0);
+       if (Z_TYPE_PP(str) == IS_UNICODE) {
+               tmp = (UChar *)php_u_addslashes(Z_USTRVAL_PP(str), Z_USTRLEN_PP(str),
+                                                                               &tmp_len, 0 TSRMLS_CC);
+               RETURN_UNICODEL((UChar *)tmp, tmp_len, 0);
+       } else {
+               tmp = (char *)php_addslashes(Z_STRVAL_PP(str), Z_STRLEN_PP(str),
+                                                                        &tmp_len, 0 TSRMLS_CC);
+               if (Z_TYPE_PP(str) == IS_BINARY) {
+                       RETURN_BINARYL((char *)tmp, tmp_len, 0);
+               } else {
+                       RETURN_STRINGL((char *)tmp, tmp_len, 0);
+               }
+       }
 }
 /* }}} */
 
@@ -3573,10 +3648,19 @@ PHP_FUNCTION(stripslashes)
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
-       convert_to_string_ex(str);
+       convert_to_text_ex(str);
 
-       ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
-       php_stripslashes(Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC);
+       if (Z_TYPE_PP(str) == IS_UNICODE) {
+               ZVAL_UNICODEL(return_value, Z_USTRVAL_PP(str), Z_USTRLEN_PP(str), 1);
+               php_u_stripslashes(Z_USTRVAL_P(return_value), &Z_USTRLEN_P(return_value) TSRMLS_CC);
+       } else {
+               if (Z_TYPE_PP(str) == IS_BINARY) {
+                       ZVAL_BINARYL(return_value, Z_BINVAL_PP(str), Z_BINLEN_PP(str), 1);
+               } else {
+                       ZVAL_STRINGL(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
+               }
+               php_stripslashes(Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC);
+       }
 }
 /* }}} */
 
@@ -3718,6 +3802,77 @@ PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int should_
 }
 /* }}} */
 
+/* {{{ php_u_addslashes
+ */
+PHPAPI UChar *php_u_addslashes(UChar *str, int32_t length, int32_t *new_length, int should_free TSRMLS_DC)
+{
+       return php_u_addslashes_ex(str, length, new_length, should_free, 0 TSRMLS_CC);
+}
+
+/* {{{ php_u_addslashes_ex
+ */
+PHPAPI UChar *php_u_addslashes_ex(UChar *str, int32_t length, int32_t *new_length, int should_free, int ignore_sybase TSRMLS_DC)
+{
+       UChar *buf;
+       int32_t buf_len = 0, i = 0;
+       UChar32 ch;
+
+       if (!new_length) {
+               new_length = &buf_len;
+       }
+       if (!str) {
+               *new_length = 0;
+               return str;
+       }
+
+       buf = eumalloc(length * 2);
+       if (!ignore_sybase && PG(magic_quotes_sybase)) {
+               while (i < length) {
+                       U16_NEXT(str, i, length, ch);
+                       switch (ch) {
+                       case '\0':
+                               buf_len += zend_codepoint_to_uchar('\\', buf+buf_len);
+                               buf_len += zend_codepoint_to_uchar('0', buf+buf_len);
+                               break;
+                       case '\'':
+                               buf_len += zend_codepoint_to_uchar('\'', buf+buf_len);
+                               buf_len += zend_codepoint_to_uchar('\'', buf+buf_len);
+                               break;
+                       default:
+                               buf_len += zend_codepoint_to_uchar(ch, buf+buf_len);
+                               break;
+                       }
+               }
+       } else {
+               while (i < length) {
+                       U16_NEXT(str, i, length, ch);
+                       switch (ch) {
+                       case '\0':
+                               buf_len += zend_codepoint_to_uchar('\\', buf+buf_len);
+                               buf_len += zend_codepoint_to_uchar('0', buf+buf_len);
+                               break;
+                       case '\'':
+                       case '\"':
+                       case '\\':
+                               buf_len += zend_codepoint_to_uchar('\\', buf+buf_len);
+                               /* break is missing *intentionally* */
+                       default:
+                               buf_len += zend_codepoint_to_uchar(ch, buf+buf_len);
+                               break;  
+                       }
+               }
+       }
+       *(buf+buf_len) = 0;
+
+       if (should_free) {
+               STR_FREE(str);
+       }
+       buf = eurealloc(buf, buf_len+1);
+       *new_length = buf_len;
+       return buf;
+}
+/* }}} */
+
 /* {{{ php_addslashes
  */
 PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC)