--- embedaddon/php/Zend/zend_operators.c 2012/02/21 23:47:52 1.1.1.1 +++ embedaddon/php/Zend/zend_operators.c 2012/05/29 12:34:36 1.1.1.2 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_operators.c,v 1.1.1.1 2012/02/21 23:47:52 misho Exp $ */ +/* $Id: zend_operators.c,v 1.1.1.2 2012/05/29 12:34:36 misho Exp $ */ #include @@ -27,13 +27,10 @@ #include "zend_globals.h" #include "zend_list.h" #include "zend_API.h" -#include "zend_multiply.h" #include "zend_strtod.h" #include "zend_exceptions.h" #include "zend_closures.h" -#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1)) - #if ZEND_USE_TOLOWER_L #include static _locale_t current_locale = NULL; @@ -153,14 +150,9 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS case IS_STRING: { char *strval; - int strl; strval = Z_STRVAL_P(op); - strl = Z_STRLEN_P(op); -#if SUHOSIN_PATCH - Z_STRLEN_P(op) = 0; -#endif - if ((Z_TYPE_P(op)=is_numeric_string(strval, strl, &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) { + if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) { ZVAL_LONG(op, 0); } STR_FREE(strval); @@ -192,8 +184,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS } else { \ switch (Z_TYPE_P(op)) { \ case IS_STRING: \ - { \ - Z_STRLEN(holder) = 0; \ + { \ if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) { \ ZVAL_LONG(&(holder), 0); \ } \ @@ -235,7 +226,6 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op)); \ break; \ case IS_STRING: \ - Z_STRLEN(holder) = 0; \ Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10); \ break; \ case IS_ARRAY: \ @@ -278,7 +268,6 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0); \ break; \ case IS_STRING: \ - Z_STRLEN(holder) = 0; \ if (Z_STRLEN_P(op) == 0 \ || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) { \ Z_LVAL(holder) = 0; \ @@ -364,9 +353,6 @@ ZEND_API void convert_to_long_base(zval *op, int base) { char *strval = Z_STRVAL_P(op); -#if SUHOSIN_PATCH - Z_STRLEN_P(op) = 0; -#endif Z_LVAL_P(op) = strtol(strval, NULL, base); STR_FREE(strval); } @@ -427,9 +413,6 @@ ZEND_API void convert_to_double(zval *op) /* {{{ */ { char *strval = Z_STRVAL_P(op); -#if SUHOSIN_PATCH - Z_STRLEN_P(op) = 0; -#endif Z_DVAL_P(op) = zend_strtod(strval, NULL); STR_FREE(strval); } @@ -516,14 +499,8 @@ ZEND_API void convert_to_boolean(zval *op) /* {{{ */ if (Z_STRLEN_P(op) == 0 || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) { -#if SUHOSIN_PATCH - Z_STRLEN_P(op) = 0; -#endif Z_LVAL_P(op) = 0; } else { -#if SUHOSIN_PATCH - Z_STRLEN_P(op) = 0; -#endif Z_LVAL_P(op) = 1; } STR_FREE(strval); @@ -637,9 +614,6 @@ static void convert_scalar_to_array(zval *op, int type *entry = *op; INIT_PZVAL(entry); -#if SUHOSIN_PATCH - Z_STRLEN_P(op) = 0; -#endif switch (type) { case IS_ARRAY: ALLOC_HASHTABLE(Z_ARRVAL_P(op)); @@ -1222,11 +1196,18 @@ ZEND_API int shift_right_function(zval *result, zval * /* must support result==op1 */ ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */ { - Z_STRLEN_P(result) = Z_STRLEN_P(op1) + 1; - Z_STRVAL_P(result) = (char *) erealloc(Z_STRVAL_P(op1), Z_STRLEN_P(result)+1); - Z_STRVAL_P(result)[Z_STRLEN_P(result) - 1] = (char) Z_LVAL_P(op2); - Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0; - Z_TYPE_P(result) = IS_STRING; + int length = Z_STRLEN_P(op1) + 1; + char *buf; + + if (IS_INTERNED(Z_STRVAL_P(op1))) { + buf = (char *) emalloc(length + 1); + memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1)); + } else { + buf = (char *) erealloc(Z_STRVAL_P(op1), length + 1); + } + buf[length - 1] = (char) Z_LVAL_P(op2); + buf[length] = 0; + ZVAL_STRINGL(result, buf, length, 0); return SUCCESS; } /* }}} */ @@ -1235,12 +1216,17 @@ ZEND_API int add_char_to_string(zval *result, const zv ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */ { int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2); + char *buf; - Z_STRVAL_P(result) = (char *) erealloc(Z_STRVAL_P(op1), length+1); - memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); - Z_STRVAL_P(result)[length] = 0; - Z_STRLEN_P(result) = length; - Z_TYPE_P(result) = IS_STRING; + if (IS_INTERNED(Z_STRVAL_P(op1))) { + buf = (char *) emalloc(length+1); + memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1)); + } else { + buf = (char *) erealloc(Z_STRVAL_P(op1), length+1); + } + memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); + buf[length] = 0; + ZVAL_STRINGL(result, buf, length, 0); return SUCCESS; } /* }}} */ @@ -1269,7 +1255,7 @@ ZEND_API int concat_function(zval *result, zval *op1, if (use_copy2) { op2 = &op2_copy; } - if (result==op1) { /* special case, perform operations on result */ + if (result==op1 && !IS_INTERNED(Z_STRVAL_P(op1))) { /* special case, perform operations on result */ uint res_len = Z_STRLEN_P(op1) + Z_STRLEN_P(op2); if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) { @@ -1284,12 +1270,13 @@ ZEND_API int concat_function(zval *result, zval *op1, Z_STRVAL_P(result)[res_len]=0; Z_STRLEN_P(result) = res_len; } else { - Z_STRLEN_P(result) = Z_STRLEN_P(op1) + Z_STRLEN_P(op2); - Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1); - memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1)); - memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); - Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0; - Z_TYPE_P(result) = IS_STRING; + int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2); + char *buf = (char *) emalloc(length + 1); + + memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1)); + memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)); + buf[length] = 0; + ZVAL_STRINGL(result, buf, length, 0); } if (use_copy1) { zval_dtor(op1); @@ -1301,7 +1288,7 @@ ZEND_API int concat_function(zval *result, zval *op1, } /* }}} */ -ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ +ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */ { zval op1_copy, op2_copy; int use_copy1 = 0, use_copy2 = 0; @@ -1320,7 +1307,11 @@ ZEND_API int string_compare_function(zval *result, zva op2 = &op2_copy; } - ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2)); + if (case_insensitive) { + ZVAL_LONG(result, zend_binary_zval_strcasecmp(op1, op2)); + } else { + ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2)); + } if (use_copy1) { zval_dtor(op1); @@ -1332,6 +1323,18 @@ ZEND_API int string_compare_function(zval *result, zva } /* }}} */ +ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ +{ + return string_compare_function_ex(result, op1, op2, 0 TSRMLS_CC); +} +/* }}} */ + +ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ +{ + return string_compare_function_ex(result, op1, op2, 1 TSRMLS_CC); +} +/* }}} */ + #if HAVE_STRCOLL ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ { @@ -1420,8 +1423,12 @@ ZEND_API int compare_function(zval *result, zval *op1, return SUCCESS; case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): - Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2); - ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result))); + if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) { + ZVAL_LONG(result, 0); + } else { + Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2); + ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result))); + } return SUCCESS; case TYPE_PAIR(IS_ARRAY, IS_ARRAY): @@ -1713,6 +1720,12 @@ static void increment_string(zval *str) /* {{{ */ return; } + if (IS_INTERNED(s)) { + s = (char*) emalloc(Z_STRLEN_P(str) + 1); + memcpy(s, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1); + Z_STRVAL_P(str) = s; + } + while (pos >= 0) { ch = s[pos]; if (ch >= 'a' && ch <= 'z') { @@ -1798,7 +1811,7 @@ ZEND_API int increment_function(zval *op1) /* {{{ */ switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) { case IS_LONG: - efree(Z_STRVAL_P(op1)); + str_efree(Z_STRVAL_P(op1)); if (lval == LONG_MAX) { /* switch to double */ double d = (double)lval; @@ -1808,7 +1821,7 @@ ZEND_API int increment_function(zval *op1) /* {{{ */ } break; case IS_DOUBLE: - efree(Z_STRVAL_P(op1)); + str_efree(Z_STRVAL_P(op1)); ZVAL_DOUBLE(op1, dval+1); break; default: @@ -1924,6 +1937,9 @@ ZEND_API int zend_binary_strcmp(const char *s1, uint l { int retval; + if (s1 == s2) { + return 0; + } retval = memcmp(s1, s2, MIN(len1, len2)); if (!retval) { return (len1 - len2); @@ -1937,6 +1953,9 @@ ZEND_API int zend_binary_strncmp(const char *s1, uint { int retval; + if (s1 == s2) { + return 0; + } retval = memcmp(s1, s2, MIN(length, MIN(len1, len2))); if (!retval) { return (MIN(length, len1) - MIN(length, len2)); @@ -1951,8 +1970,11 @@ ZEND_API int zend_binary_strcasecmp(const char *s1, ui int len; int c1, c2; - len = MIN(len1, len2); + if (s1 == s2) { + return 0; + } + len = MIN(len1, len2); while (len--) { c1 = zend_tolower((int)*(unsigned char *)s1++); c2 = zend_tolower((int)*(unsigned char *)s2++); @@ -1970,8 +1992,10 @@ ZEND_API int zend_binary_strncasecmp(const char *s1, u int len; int c1, c2; + if (s1 == s2) { + return 0; + } len = MIN(length, MIN(len1, len2)); - while (len--) { c1 = zend_tolower((int)*(unsigned char *)s1++); c2 = zend_tolower((int)*(unsigned char *)s2++);