Diff for /embedaddon/php/ext/standard/string.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/21 23:48:02 version 1.1.1.4, 2013/10/14 08:02:35
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2013 The PHP Group                                |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | This source file is subject to version 3.01 of the PHP license,      |     | This source file is subject to version 3.01 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |     | that is bundled with this package in the file LICENSE, and is        |
Line 23 Line 23
 /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */  /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
   
 #include <stdio.h>  #include <stdio.h>
   #ifdef PHP_WIN32
   # include "win32/php_stdint.h"
   #else
   # include <stdint.h>
   #endif
 #include "php.h"  #include "php.h"
 #include "php_rand.h"  #include "php_rand.h"
 #include "php_string.h"  #include "php_string.h"
Line 36 Line 41
 #ifdef HAVE_MONETARY_H  #ifdef HAVE_MONETARY_H
 # include <monetary.h>  # include <monetary.h>
 #endif  #endif
/* /*
  * This define is here because some versions of libintl redefine setlocale   * This define is here because some versions of libintl redefine setlocale
  * to point to libintl_setlocale.  That's a ridiculous thing to do as far   * to point to libintl_setlocale.  That's a ridiculous thing to do as far
  * as I am concerned, but with this define and the subsequent undef we   * as I am concerned, but with this define and the subsequent undef we
Line 57 Line 62
 #include "php_globals.h"  #include "php_globals.h"
 #include "basic_functions.h"  #include "basic_functions.h"
 #include "php_smart_str.h"  #include "php_smart_str.h"
   #include <Zend/zend_exceptions.h>
 #ifdef ZTS  #ifdef ZTS
 #include "TSRM.h"  #include "TSRM.h"
 #endif  #endif
Line 89  void register_string_constants(INIT_FUNC_ARGS) Line 95  void register_string_constants(INIT_FUNC_ARGS)
         REGISTER_LONG_CONSTANT("PATHINFO_FILENAME", PHP_PATHINFO_FILENAME, CONST_CS | CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("PATHINFO_FILENAME", PHP_PATHINFO_FILENAME, CONST_CS | CONST_PERSISTENT);
   
 #ifdef HAVE_LOCALECONV  #ifdef HAVE_LOCALECONV
        /* If last members of struct lconv equal CHAR_MAX, no grouping is done */               /* If last members of struct lconv equal CHAR_MAX, no grouping is done */
   
 /* This is bad, but since we are going to be hardcoding in the POSIX stuff anyway... */  /* This is bad, but since we are going to be hardcoding in the POSIX stuff anyway... */
 # ifndef HAVE_LIMITS_H  # ifndef HAVE_LIMITS_H
Line 110  void register_string_constants(INIT_FUNC_ARGS) Line 116  void register_string_constants(INIT_FUNC_ARGS)
         REGISTER_LONG_CONSTANT("LC_MESSAGES", LC_MESSAGES, CONST_CS | CONST_PERSISTENT);          REGISTER_LONG_CONSTANT("LC_MESSAGES", LC_MESSAGES, CONST_CS | CONST_PERSISTENT);
 # endif  # endif
 #endif  #endif
        
 }  }
 /* }}} */  /* }}} */
   
Line 131  static char *php_bin2hex(const unsigned char *old, con Line 137  static char *php_bin2hex(const unsigned char *old, con
         register unsigned char *result = NULL;          register unsigned char *result = NULL;
         size_t i, j;          size_t i, j;
   
        result = (unsigned char *) safe_emalloc(oldlen * 2, sizeof(char), 1);        result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1);
        
         for (i = j = 0; i < oldlen; i++) {          for (i = j = 0; i < oldlen; i++) {
                 result[j++] = hexconvtab[old[i] >> 4];                  result[j++] = hexconvtab[old[i] >> 4];
                 result[j++] = hexconvtab[old[i] & 15];                  result[j++] = hexconvtab[old[i] & 15];
         }          }
         result[j] = '\0';          result[j] = '\0';
   
        if (newlen)         if (newlen)
                 *newlen = oldlen * 2 * sizeof(char);                  *newlen = oldlen * 2 * sizeof(char);
   
         return (char *)result;          return (char *)result;
 }  }
 /* }}} */  /* }}} */
   
   /* {{{ php_hex2bin
    */
   static char *php_hex2bin(const unsigned char *old, const size_t oldlen, size_t *newlen)
   {
           size_t target_length = oldlen >> 1;
           register unsigned char *str = (unsigned char *)safe_emalloc(target_length, sizeof(char), 1);
           size_t i, j;
           for (i = j = 0; i < target_length; i++) {
                   char c = old[j++];
                   if (c >= '0' && c <= '9') {
                           str[i] = (c - '0') << 4;
                   } else if (c >= 'a' && c <= 'f') {
                           str[i] = (c - 'a' + 10) << 4;
                   } else if (c >= 'A' && c <= 'F') {
                           str[i] = (c - 'A' + 10) << 4;
                   } else {
                           efree(str);
                           return NULL;
                   }
                   c = old[j++];
                   if (c >= '0' && c <= '9') {
                           str[i] |= c - '0';
                   } else if (c >= 'a' && c <= 'f') {
                           str[i] |= c - 'a' + 10;
                   } else if (c >= 'A' && c <= 'F') {
                           str[i] |= c - 'A' + 10;
                   } else {
                           efree(str);
                           return NULL;
                   }
           }
           str[target_length] = '\0';
   
           if (newlen)
                   *newlen = target_length;
   
           return (char *)str;
   }
   /* }}} */
   
 #ifdef HAVE_LOCALECONV  #ifdef HAVE_LOCALECONV
 /* {{{ localeconv_r  /* {{{ localeconv_r
  * glibc's localeconv is not reentrant, so lets make it so ... sorta */   * glibc's localeconv is not reentrant, so lets make it so ... sorta */
Line 205  PHP_FUNCTION(bin2hex) Line 251  PHP_FUNCTION(bin2hex)
         }          }
   
         result = php_bin2hex((unsigned char *)data, datalen, &newlen);          result = php_bin2hex((unsigned char *)data, datalen, &newlen);
        
         if (!result) {          if (!result) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
Line 214  PHP_FUNCTION(bin2hex) Line 260  PHP_FUNCTION(bin2hex)
 }  }
 /* }}} */  /* }}} */
   
   /* {{{ proto string hex2bin(string data)
      Converts the hex representation of data to binary */
   PHP_FUNCTION(hex2bin)
   {
           char *result, *data;
           size_t newlen;
           int datalen;
   
           if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &datalen) == FAILURE) {
                   return;
           }
   
           if (datalen % 2 != 0) {
                   php_error_docref(NULL TSRMLS_CC, E_WARNING, "Hexadecimal input string must have an even length");
                   RETURN_FALSE;
           }
   
           result = php_hex2bin((unsigned char *)data, datalen, &newlen);
   
           if (!result) {
                   RETURN_FALSE;
           }
   
           RETURN_STRINGL(result, newlen, 0);
   }
   /* }}} */
   
 static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ */  static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ */
 {  {
         char *s11, *s22;          char *s11, *s22;
         int len1, len2;          int len1, len2;
         long start = 0, len = 0;          long start = 0, len = 0;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", &s11, &len1,          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", &s11, &len1,
                                 &s22, &len2, &start, &len) == FAILURE) {                                  &s22, &len2, &start, &len) == FAILURE) {
                 return;                  return;
         }          }
        
         if (ZEND_NUM_ARGS() < 4) {          if (ZEND_NUM_ARGS() < 4) {
                 len = len1;                  len = len1;
         }          }
        
         /* look at substr() function for more information */          /* look at substr() function for more information */
        
         if (start < 0) {          if (start < 0) {
                 start += len1;                  start += len1;
                 if (start < 0) {                  if (start < 0) {
Line 239  static void php_spn_common_handler(INTERNAL_FUNCTION_P Line 312  static void php_spn_common_handler(INTERNAL_FUNCTION_P
         } else if (start > len1) {          } else if (start > len1) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
         if (len < 0) {          if (len < 0) {
                 len += (len1 - start);                  len += (len1 - start);
                 if (len < 0) {                  if (len < 0) {
                         len = 0;                          len = 0;
                 }                  }
         }          }
        
         if (len > len1 - start) {          if (len > len1 - start) {
                 len = len1 - start;                  len = len1 - start;
         }          }
Line 266  static void php_spn_common_handler(INTERNAL_FUNCTION_P Line 339  static void php_spn_common_handler(INTERNAL_FUNCTION_P
                                                 s11 + start + len /*str1_end*/,                                                  s11 + start + len /*str1_end*/,
                                                 s22 + len2 /*str2_end*/));                                                  s22 + len2 /*str2_end*/));
         }          }
        
 }  }
 /* }}} */  /* }}} */
   
Line 462  PHP_FUNCTION(nl_langinfo) Line 535  PHP_FUNCTION(nl_langinfo)
 {  {
         long item;          long item;
         char *value;          char *value;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &item) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &item) == FAILURE) {
                 return;                  return;
         }          }
Line 650  PHP_FUNCTION(strcoll) Line 723  PHP_FUNCTION(strcoll)
 {  {
         char *s1, *s2;          char *s1, *s2;
         int s1len, s2len;          int s1len, s2len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1len, &s2, &s2len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1len, &s2, &s2len) == FAILURE) {
                 return;                  return;
         }          }
   
        RETURN_LONG(strcoll((const char *) s1,         RETURN_LONG(strcoll((const char *) s1,
                             (const char *) s2));                              (const char *) s2));
 }  }
 /* }}} */  /* }}} */
Line 663  PHP_FUNCTION(strcoll) Line 736  PHP_FUNCTION(strcoll)
   
 /* {{{ php_charmask  /* {{{ php_charmask
  * Fills a 256-byte bytemask with input. You can specify a range like 'a..z',   * Fills a 256-byte bytemask with input. You can specify a range like 'a..z',
 * it needs to be incrementing.   * it needs to be incrementing.
  * Returns: FAILURE/SUCCESS whether the input was correct (i.e. no range errors)   * Returns: FAILURE/SUCCESS whether the input was correct (i.e. no range errors)
  */   */
 static inline int php_charmask(unsigned char *input, int len, char *mask TSRMLS_DC)  static inline int php_charmask(unsigned char *input, int len, char *mask TSRMLS_DC)
Line 674  static inline int php_charmask(unsigned char *input, i Line 747  static inline int php_charmask(unsigned char *input, i
   
         memset(mask, 0, 256);          memset(mask, 0, 256);
         for (end = input+len; input < end; input++) {          for (end = input+len; input < end; input++) {
                c=*input;                 c=*input;
                if ((input+3 < end) && input[1] == '.' && input[2] == '.'                 if ((input+3 < end) && input[1] == '.' && input[2] == '.'
                                 && input[3] >= c) {                                  && input[3] >= c) {
                         memset(mask+c, 1, input[3] - c + 1);                          memset(mask+c, 1, input[3] - c + 1);
                         input+=3;                          input+=3;
Line 696  static inline int php_charmask(unsigned char *input, i Line 769  static inline int php_charmask(unsigned char *input, i
                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, '..'-range needs to be incrementing");                                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range, '..'-range needs to be incrementing");
                                 result = FAILURE;                                  result = FAILURE;
                                 continue;                                  continue;
                        }                         }
                         /* FIXME: better error (a..b..c is the only left possibility?) */                          /* FIXME: better error (a..b..c is the only left possibility?) */
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid '..'-range");
                         result = FAILURE;                          result = FAILURE;
Line 765  static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS,  Line 838  static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, 
         char *str;          char *str;
         char *what = NULL;          char *what = NULL;
         int str_len, what_len = 0;          int str_len, what_len = 0;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, &str_len, &what, &what_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, &str_len, &what, &what_len) == FAILURE) {
                 return;                  return;
         }          }
        
         php_trim(str, str_len, what, what_len, return_value, mode TSRMLS_CC);          php_trim(str, str_len, what, what_len, return_value, mode TSRMLS_CC);
 }  }
 /* }}} */  /* }}} */
Line 939  PHP_FUNCTION(wordwrap) Line 1012  PHP_FUNCTION(wordwrap)
   
 /* {{{ php_explode  /* {{{ php_explode
  */   */
PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit) PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit)
 {  {
         char *p1, *p2, *endp;          char *p1, *p2, *endp;
   
Line 965  PHPAPI void php_explode(zval *delim, zval *str, zval * Line 1038  PHPAPI void php_explode(zval *delim, zval *str, zval *
   
 /* {{{ php_explode_negative_limit  /* {{{ php_explode_negative_limit
  */   */
PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_value, long limit) PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_value, long limit)
 {  {
 #define EXPLODE_ALLOC_STEP 64  #define EXPLODE_ALLOC_STEP 64
         char *p1, *p2, *endp;          char *p1, *p2, *endp;
        
         endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);          endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);
   
         p1 = Z_STRVAL_P(str);          p1 = Z_STRVAL_P(str);
Line 993  PHPAPI void php_explode_negative_limit(zval *delim, zv Line 1066  PHPAPI void php_explode_negative_limit(zval *delim, zv
                         }                          }
                         positions[found++] = p1 = p2 + Z_STRLEN_P(delim);                          positions[found++] = p1 = p2 + Z_STRLEN_P(delim);
                 } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL);                  } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL);
                
                 to_return = limit + found;                  to_return = limit + found;
                 /* limit is at least -1 therefore no need of bounds checking : i will be always less than found */                  /* limit is at least -1 therefore no need of bounds checking : i will be always less than found */
                 for (i = 0;i < to_return;i++) { /* this checks also for to_return > 0 */                  for (i = 0;i < to_return;i++) { /* this checks also for to_return > 0 */
                        add_next_index_stringl(return_value, positions[i],                         add_next_index_stringl(return_value, positions[i],
                                         (positions[i+1] - Z_STRLEN_P(delim)) - positions[i],                                          (positions[i+1] - Z_STRLEN_P(delim)) - positions[i],
                                         1                                          1
                                 );                                  );
Line 1016  PHP_FUNCTION(explode) Line 1089  PHP_FUNCTION(explode)
         int str_len = 0, delim_len = 0;          int str_len = 0, delim_len = 0;
         long limit = LONG_MAX; /* No limit */          long limit = LONG_MAX; /* No limit */
         zval zdelim, zstr;          zval zdelim, zstr;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &delim, &delim_len, &str, &str_len, &limit) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &delim, &delim_len, &str, &str_len, &limit) == FAILURE) {
                 return;                  return;
         }          }
        
         if (delim_len == 0) {          if (delim_len == 0) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");
                 RETURN_FALSE;                  RETURN_FALSE;
Line 1031  PHP_FUNCTION(explode) Line 1104  PHP_FUNCTION(explode)
         if (str_len == 0) {          if (str_len == 0) {
                 if (limit >= 0) {                  if (limit >= 0) {
                         add_next_index_stringl(return_value, "", sizeof("") - 1, 1);                          add_next_index_stringl(return_value, "", sizeof("") - 1, 1);
                }                 }
                 return;                  return;
         }          }
   
Line 1053  PHP_FUNCTION(explode) Line 1126  PHP_FUNCTION(explode)
   
 /* {{{ php_implode  /* {{{ php_implode
  */   */
PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC) PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
 {  {
         zval         **tmp;          zval         **tmp;
         HashPosition   pos;          HashPosition   pos;
Line 1088  PHPAPI void php_implode(zval *delim, zval *arr, zval * Line 1161  PHPAPI void php_implode(zval *delim, zval *arr, zval *
                                         smart_str_appendl(&implstr, "1", sizeof("1")-1);                                          smart_str_appendl(&implstr, "1", sizeof("1")-1);
                                 }                                  }
                                 break;                                  break;
                        
                         case IS_NULL:                          case IS_NULL:
                                 break;                                  break;
   
Line 1118  PHPAPI void php_implode(zval *delim, zval *arr, zval * Line 1191  PHPAPI void php_implode(zval *delim, zval *arr, zval *
                                 smart_str_appendl(&implstr, Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));                                  smart_str_appendl(&implstr, Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
                                 zval_dtor(&tmp_val);                                  zval_dtor(&tmp_val);
                                 break;                                  break;
                                
                 }                  }
   
                 if (++i != numelems) {                  if (++i != numelems) {
Line 1146  PHP_FUNCTION(implode) Line 1219  PHP_FUNCTION(implode)
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &arg1, &arg2) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &arg1, &arg2) == FAILURE) {
                 return;                  return;
         }          }
        
         if (arg2 == NULL) {          if (arg2 == NULL) {
                 if (Z_TYPE_PP(arg1) != IS_ARRAY) {                  if (Z_TYPE_PP(arg1) != IS_ARRAY) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument must be an array");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument must be an array");
Line 1173  PHP_FUNCTION(implode) Line 1246  PHP_FUNCTION(implode)
                         return;                          return;
                 }                  }
         }          }
        
         php_implode(delim, arr, return_value TSRMLS_CC);          php_implode(delim, arr, return_value TSRMLS_CC);
   
         if (arg2 == NULL) {          if (arg2 == NULL) {
Line 1182  PHP_FUNCTION(implode) Line 1255  PHP_FUNCTION(implode)
 }  }
 /* }}} */  /* }}} */
   
#define STRTOK_TABLE(p) BG(strtok_table)[(unsigned char) *p]    #define STRTOK_TABLE(p) BG(strtok_table)[(unsigned char) *p]
   
 /* {{{ proto string strtok([string str,] string token)  /* {{{ proto string strtok([string str,] string token)
    Tokenize a string */     Tokenize a string */
 PHP_FUNCTION(strtok)  PHP_FUNCTION(strtok)
{               {
         char *str, *tok = NULL;          char *str, *tok = NULL;
         int str_len, tok_len = 0;          int str_len, tok_len = 0;
         zval *zv;          zval *zv;
        
         char *token;          char *token;
         char *token_end;          char *token_end;
         char *p;          char *p;
         char *pe;          char *pe;
         int skipped = 0;          int skipped = 0;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, &str_len, &tok, &tok_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, &str_len, &tok, &tok_len) == FAILURE) {
                 return;                  return;
         }          }
Line 1216  PHP_FUNCTION(strtok) Line 1289  PHP_FUNCTION(strtok)
                 BG(strtok_last) = BG(strtok_string) = Z_STRVAL_P(zv);                  BG(strtok_last) = BG(strtok_string) = Z_STRVAL_P(zv);
                 BG(strtok_len) = str_len;                  BG(strtok_len) = str_len;
         }          }
        
         p = BG(strtok_last); /* Where we start to search */          p = BG(strtok_last); /* Where we start to search */
         pe = BG(strtok_string) + BG(strtok_len);          pe = BG(strtok_string) + BG(strtok_len);
   
         if (!p || p >= pe) {          if (!p || p >= pe) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
         token = tok;          token = tok;
         token_end = token + tok_len;          token_end = token + tok_len;
   
         while (token < token_end) {          while (token < token_end) {
                 STRTOK_TABLE(token++) = 1;                  STRTOK_TABLE(token++) = 1;
         }          }
        
         /* Skip leading delimiters */          /* Skip leading delimiters */
         while (STRTOK_TABLE(p)) {          while (STRTOK_TABLE(p)) {
                 if (++p >= pe) {                  if (++p >= pe) {
Line 1241  PHP_FUNCTION(strtok) Line 1314  PHP_FUNCTION(strtok)
                 }                  }
                 skipped++;                  skipped++;
         }          }
        
        /* We know at this place that *p is no delimiter, so skip it */         /* We know at this place that *p is no delimiter, so skip it */
         while (++p < pe) {          while (++p < pe) {
                 if (STRTOK_TABLE(p)) {                  if (STRTOK_TABLE(p)) {
                        goto return_token;                              goto return_token;
                 }                  }
         }          }
        
         if (p - BG(strtok_last)) {          if (p - BG(strtok_last)) {
 return_token:  return_token:
                 RETVAL_STRINGL(BG(strtok_last) + skipped, (p - BG(strtok_last)) - skipped, 1);                  RETVAL_STRINGL(BG(strtok_last) + skipped, (p - BG(strtok_last)) - skipped, 1);
Line 1261  return_token: Line 1334  return_token:
         /* Restore table -- usually faster then memset'ing the table on every invocation */          /* Restore table -- usually faster then memset'ing the table on every invocation */
 restore:  restore:
         token = tok;          token = tok;
        
         while (token < token_end) {          while (token < token_end) {
                 STRTOK_TABLE(token++) = 0;                  STRTOK_TABLE(token++) = 0;
         }          }
Line 1273  restore: Line 1346  restore:
 PHPAPI char *php_strtoupper(char *s, size_t len)  PHPAPI char *php_strtoupper(char *s, size_t len)
 {  {
         unsigned char *c, *e;          unsigned char *c, *e;
        
         c = (unsigned char *)s;          c = (unsigned char *)s;
         e = (unsigned char *)c+len;          e = (unsigned char *)c+len;
   
Line 1291  PHP_FUNCTION(strtoupper) Line 1364  PHP_FUNCTION(strtoupper)
 {  {
         char *arg;          char *arg;
         int arglen;          int arglen;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arglen) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arglen) == FAILURE) {
                 return;                  return;
         }          }
   
         arg = estrndup(arg, arglen);          arg = estrndup(arg, arglen);
        php_strtoupper(arg, arglen);            php_strtoupper(arg, arglen);
         RETURN_STRINGL(arg, arglen, 0);          RETURN_STRINGL(arg, arglen, 0);
 }  }
 /* }}} */  /* }}} */
Line 1307  PHP_FUNCTION(strtoupper) Line 1380  PHP_FUNCTION(strtoupper)
 PHPAPI char *php_strtolower(char *s, size_t len)  PHPAPI char *php_strtolower(char *s, size_t len)
 {  {
         unsigned char *c, *e;          unsigned char *c, *e;
        
         c = (unsigned char *)s;          c = (unsigned char *)s;
         e = c+len;          e = c+len;
   
Line 1325  PHP_FUNCTION(strtolower) Line 1398  PHP_FUNCTION(strtolower)
 {  {
         char *str;          char *str;
         int arglen;          int arglen;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &arglen) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &arglen) == FAILURE) {
                 return;                  return;
         }          }
Line 1338  PHP_FUNCTION(strtolower) Line 1411  PHP_FUNCTION(strtolower)
   
 /* {{{ php_basename  /* {{{ php_basename
  */   */
PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len TSRMLS_DC)PHPAPI void php_basename(const char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len TSRMLS_DC)
 {  {
         char *ret = NULL, *c, *comp, *cend;          char *ret = NULL, *c, *comp, *cend;
         size_t inc_len, cnt;          size_t inc_len, cnt;
         int state;          int state;
   
        c = comp = cend = s;        c = comp = cend = (char*)s;
         cnt = len;          cnt = len;
         state = 0;          state = 0;
         while (cnt > 0) {          while (cnt > 0) {
Line 1354  PHPAPI void php_basename(char *s, size_t len, char *su Line 1427  PHPAPI void php_basename(char *s, size_t len, char *su
                         case -2:                          case -2:
                         case -1:                          case -1:
                                 inc_len = 1;                                  inc_len = 1;
                                php_mblen(NULL, 0);                                php_ignore_value(php_mblen(NULL, 0));
                                 break;                                  break;
                         case 0:                          case 0:
                                 goto quit_loop;                                  goto quit_loop;
Line 1446  PHP_FUNCTION(dirname) Line 1519  PHP_FUNCTION(dirname)
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
        
         ret = estrndup(str, str_len);          ret = estrndup(str, str_len);
         ret_len = php_dirname(ret, str_len);          ret_len = php_dirname(ret, str_len);
   
Line 1469  PHP_FUNCTION(pathinfo) Line 1542  PHP_FUNCTION(pathinfo)
         }          }
   
         have_basename = ((opt & PHP_PATHINFO_BASENAME) == PHP_PATHINFO_BASENAME);          have_basename = ((opt & PHP_PATHINFO_BASENAME) == PHP_PATHINFO_BASENAME);
        
         MAKE_STD_ZVAL(tmp);          MAKE_STD_ZVAL(tmp);
         array_init(tmp);          array_init(tmp);
        
         if ((opt & PHP_PATHINFO_DIRNAME) == PHP_PATHINFO_DIRNAME) {          if ((opt & PHP_PATHINFO_DIRNAME) == PHP_PATHINFO_DIRNAME) {
                 ret = estrndup(path, path_len);                  ret = estrndup(path, path_len);
                 php_dirname(ret, path_len);                  php_dirname(ret, path_len);
Line 1482  PHP_FUNCTION(pathinfo) Line 1555  PHP_FUNCTION(pathinfo)
                 efree(ret);                  efree(ret);
                 ret = NULL;                  ret = NULL;
         }          }
        
         if (have_basename) {          if (have_basename) {
                 php_basename(path, path_len, NULL, 0, &ret, &ret_len TSRMLS_CC);                  php_basename(path, path_len, NULL, 0, &ret, &ret_len TSRMLS_CC);
                 add_assoc_stringl(tmp, "basename", ret, ret_len, 0);                  add_assoc_stringl(tmp, "basename", ret, ret_len, 0);
         }          }
        
         if ((opt & PHP_PATHINFO_EXTENSION) == PHP_PATHINFO_EXTENSION) {          if ((opt & PHP_PATHINFO_EXTENSION) == PHP_PATHINFO_EXTENSION) {
                char *p;                const char *p;
                 int idx;                  int idx;
   
                 if (!have_basename) {                  if (!have_basename) {
Line 1503  PHP_FUNCTION(pathinfo) Line 1576  PHP_FUNCTION(pathinfo)
                         add_assoc_stringl(tmp, "extension", ret + idx + 1, ret_len - idx - 1, 1);                          add_assoc_stringl(tmp, "extension", ret + idx + 1, ret_len - idx - 1, 1);
                 }                  }
         }          }
        
         if ((opt & PHP_PATHINFO_FILENAME) == PHP_PATHINFO_FILENAME) {          if ((opt & PHP_PATHINFO_FILENAME) == PHP_PATHINFO_FILENAME) {
                char *p;                const char *p;
                 int idx;                  int idx;
   
                /* Have we alrady looked up the basename? */                /* Have we already looked up the basename? */
                 if (!have_basename && !ret) {                  if (!have_basename && !ret) {
                         php_basename(path, path_len, NULL, 0, &ret, &ret_len TSRMLS_CC);                          php_basename(path, path_len, NULL, 0, &ret, &ret_len TSRMLS_CC);
                 }                  }
Line 1632  PHP_FUNCTION(stristr) Line 1705  PHP_FUNCTION(stristr)
         char *haystack_dup;          char *haystack_dup;
         char needle_char[2];          char needle_char[2];
         zend_bool part = 0;          zend_bool part = 0;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) {
                 return;                  return;
         }          }
Line 1642  PHP_FUNCTION(stristr) Line 1715  PHP_FUNCTION(stristr)
         if (Z_TYPE_P(needle) == IS_STRING) {          if (Z_TYPE_P(needle) == IS_STRING) {
                 char *orig_needle;                  char *orig_needle;
                 if (!Z_STRLEN_P(needle)) {                  if (!Z_STRLEN_P(needle)) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty needle");
                         efree(haystack_dup);                          efree(haystack_dup);
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
Line 1665  PHP_FUNCTION(stristr) Line 1738  PHP_FUNCTION(stristr)
                         RETVAL_STRINGL(haystack, found_offset, 1);                          RETVAL_STRINGL(haystack, found_offset, 1);
                 } else {                  } else {
                         RETVAL_STRINGL(haystack + found_offset, haystack_len - found_offset, 1);                          RETVAL_STRINGL(haystack + found_offset, haystack_len - found_offset, 1);
                }                                       }
         } else {          } else {
                 RETVAL_FALSE;                  RETVAL_FALSE;
         }          }
Line 1685  PHP_FUNCTION(strstr) Line 1758  PHP_FUNCTION(strstr)
         char needle_char[2];          char needle_char[2];
         long found_offset;          long found_offset;
         zend_bool part = 0;          zend_bool part = 0;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) {
                 return;                  return;
         }          }
   
         if (Z_TYPE_P(needle) == IS_STRING) {          if (Z_TYPE_P(needle) == IS_STRING) {
                 if (!Z_STRLEN_P(needle)) {                  if (!Z_STRLEN_P(needle)) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty needle");
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
   
Line 1732  PHP_FUNCTION(strpos) Line 1805  PHP_FUNCTION(strpos)
         char  needle_char[2];          char  needle_char[2];
         long  offset = 0;          long  offset = 0;
         int   haystack_len;          int   haystack_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &needle, &offset) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &needle, &offset) == FAILURE) {
                 return;                  return;
         }          }
Line 1744  PHP_FUNCTION(strpos) Line 1817  PHP_FUNCTION(strpos)
   
         if (Z_TYPE_P(needle) == IS_STRING) {          if (Z_TYPE_P(needle) == IS_STRING) {
                 if (!Z_STRLEN_P(needle)) {                  if (!Z_STRLEN_P(needle)) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter");                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty needle");
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
   
Line 1816  PHP_FUNCTION(stripos) Line 1889  PHP_FUNCTION(stripos)
                 }                  }
                 needle_char[0] = tolower(needle_char[0]);                  needle_char[0] = tolower(needle_char[0]);
                 needle_char[1] = '\0';                  needle_char[1] = '\0';
                found = php_memnstr(haystack_dup + offset,                 found = php_memnstr(haystack_dup + offset,
                                                        needle_char,                                                         needle_char,
                                                        sizeof(needle_char) - 1,                                                         sizeof(needle_char) - 1,
                                                         haystack_dup + haystack_len);                                                          haystack_dup + haystack_len);
         }          }
   
Line 1940  PHP_FUNCTION(strripos) Line 2013  PHP_FUNCTION(strripos)
         }          }
   
         if (needle_len == 1) {          if (needle_len == 1) {
                /* Single character search can shortcut memcmps                 /* Single character search can shortcut memcmps
                    Can also avoid tolower emallocs */                     Can also avoid tolower emallocs */
                 if (offset >= 0) {                  if (offset >= 0) {
                         if (offset > haystack_len) {                          if (offset > haystack_len) {
Line 2018  PHP_FUNCTION(strrchr) Line 2091  PHP_FUNCTION(strrchr)
 {  {
         zval *needle;          zval *needle;
         char *haystack;          char *haystack;
        char *found = NULL;        const char *found = NULL;
         long found_offset;          long found_offset;
         int  haystack_len;          int  haystack_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &haystack, &haystack_len, &needle) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &haystack, &haystack_len, &needle) == FAILURE) {
                 return;                  return;
         }          }
Line 2054  static char *php_chunk_split(char *src, int srclen, ch Line 2127  static char *php_chunk_split(char *src, int srclen, ch
         char *p, *q;          char *p, *q;
         int chunks; /* complete chunks! */          int chunks; /* complete chunks! */
         int restlen;          int restlen;
        int out_len;         int out_len;
   
         chunks = srclen / chunklen;          chunks = srclen / chunklen;
         restlen = srclen - chunks * chunklen; /* srclen % chunklen */          restlen = srclen - chunks * chunklen; /* srclen % chunklen */
Line 2100  static char *php_chunk_split(char *src, int srclen, ch Line 2173  static char *php_chunk_split(char *src, int srclen, ch
   
 /* {{{ proto string chunk_split(string str [, int chunklen [, string ending]])  /* {{{ proto string chunk_split(string str [, int chunklen [, string ending]])
    Returns split line */     Returns split line */
PHP_FUNCTION(chunk_split) PHP_FUNCTION(chunk_split)
 {  {
         char *str;          char *str;
         char *result;          char *result;
Line 2109  PHP_FUNCTION(chunk_split)  Line 2182  PHP_FUNCTION(chunk_split) 
         long chunklen = 76;          long chunklen = 76;
         int result_len;          int result_len;
         int str_len;          int str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", &str, &str_len, &chunklen, &end, &endlen) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", &str, &str_len, &chunklen, &end, &endlen) == FAILURE) {
                 return;                  return;
         }          }
Line 2125  PHP_FUNCTION(chunk_split)  Line 2198  PHP_FUNCTION(chunk_split) 
                 result = emalloc(result_len + 1);                  result = emalloc(result_len + 1);
                 memcpy(result, str, str_len);                  memcpy(result, str, str_len);
                 memcpy(result + str_len, end, endlen);                  memcpy(result + str_len, end, endlen);
                result[result_len] = '\0';                 result[result_len] = '\0';
                RETURN_STRINGL(result, result_len, 0);                  RETURN_STRINGL(result, result_len, 0);
         }          }
   
         if (!str_len) {          if (!str_len) {
Line 2151  PHP_FUNCTION(substr) Line 2224  PHP_FUNCTION(substr)
         long l = 0, f;          long l = 0, f;
         int str_len;          int str_len;
         int argc = ZEND_NUM_ARGS();          int argc = ZEND_NUM_ARGS();
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &str, &str_len, &f, &l) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &str, &str_len, &f, &l) == FAILURE) {
                 return;                  return;
         }          }
Line 2165  PHP_FUNCTION(substr) Line 2238  PHP_FUNCTION(substr)
         } else {          } else {
                 l = str_len;                  l = str_len;
         }          }
        
         if (f > str_len) {          if (f > str_len) {
                 RETURN_FALSE;                  RETURN_FALSE;
         } else if (f < 0 && -f > str_len) {          } else if (f < 0 && -f > str_len) {
Line 2228  PHP_FUNCTION(substr_replace) Line 2301  PHP_FUNCTION(substr_replace)
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|Z", &str, &repl, &from, &len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|Z", &str, &repl, &from, &len) == FAILURE) {
                 return;                  return;
         }          }
        
         if (Z_TYPE_PP(str) != IS_ARRAY) {          if (Z_TYPE_PP(str) != IS_ARRAY) {
                 if (Z_ISREF_PP(str)) {                  if (Z_ISREF_PP(str)) {
                         SEPARATE_ZVAL(str);                          SEPARATE_ZVAL(str);
Line 2262  PHP_FUNCTION(substr_replace) Line 2335  PHP_FUNCTION(substr_replace)
   
         if (Z_TYPE_PP(str) == IS_STRING) {          if (Z_TYPE_PP(str) == IS_STRING) {
                 if (                  if (
                        (argc == 3 && Z_TYPE_PP(from) == IS_ARRAY) ||                         (argc == 3 && Z_TYPE_PP(from) == IS_ARRAY) ||
                         (argc == 4 && Z_TYPE_PP(from) != Z_TYPE_PP(len))                          (argc == 4 && Z_TYPE_PP(from) != Z_TYPE_PP(len))
                 ) {                  ) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should be of same type - numerical or array ");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should be of same type - numerical or array ");
                        RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);                                  RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
                 }                  }
                 if (argc == 4 && Z_TYPE_PP(from) == IS_ARRAY) {                  if (argc == 4 && Z_TYPE_PP(from) == IS_ARRAY) {
                         if (zend_hash_num_elements(Z_ARRVAL_PP(from)) != zend_hash_num_elements(Z_ARRVAL_PP(len))) {                          if (zend_hash_num_elements(Z_ARRVAL_PP(from)) != zend_hash_num_elements(Z_ARRVAL_PP(len))) {
                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should have the same number of elements");                                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should have the same number of elements");
                                RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);                                          RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
                         }                          }
                 }                  }
         }          }
        
         if (Z_TYPE_PP(str) != IS_ARRAY) {          if (Z_TYPE_PP(str) != IS_ARRAY) {
                 if (Z_TYPE_PP(from) != IS_ARRAY) {                  if (Z_TYPE_PP(from) != IS_ARRAY) {
                         int repl_len = 0;                          int repl_len = 0;
Line 2333  PHP_FUNCTION(substr_replace) Line 2406  PHP_FUNCTION(substr_replace)
                         RETURN_STRINGL(result, result_len, 0);                          RETURN_STRINGL(result, result_len, 0);
                 } else {                  } else {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Functionality of 'from' and 'len' as arrays is not implemented");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Functionality of 'from' and 'len' as arrays is not implemented");
                        RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);                          RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
                 }                  }
         } else { /* str is array of strings */          } else { /* str is array of strings */
                 char *str_index = NULL;                  char *str_index = NULL;
Line 2358  PHP_FUNCTION(substr_replace) Line 2431  PHP_FUNCTION(substr_replace)
                 while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(str), (void **) &tmp_str, &pos_str) == SUCCESS) {                  while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(str), (void **) &tmp_str, &pos_str) == SUCCESS) {
                         zval *orig_str;                          zval *orig_str;
                         zval dummy;                          zval dummy;
                           ulong refcount;
                           int was_ref;
   
                         if(Z_TYPE_PP(tmp_str) != IS_STRING) {                          if(Z_TYPE_PP(tmp_str) != IS_STRING) {
                                 dummy = **tmp_str;                                  dummy = **tmp_str;
                                 orig_str = &dummy;                                  orig_str = &dummy;
Line 2366  PHP_FUNCTION(substr_replace) Line 2442  PHP_FUNCTION(substr_replace)
                         } else {                          } else {
                                 orig_str = *tmp_str;                                  orig_str = *tmp_str;
                         }                          }
                           was_ref = Z_ISREF_P(orig_str);
                           Z_UNSET_ISREF_P(orig_str);
                           refcount = Z_REFCOUNT_P(orig_str);
   
                         if (Z_TYPE_PP(from) == IS_ARRAY) {                          if (Z_TYPE_PP(from) == IS_ARRAY) {
                                 if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(from), (void **) &tmp_from, &pos_from)) {                                  if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(from), (void **) &tmp_from, &pos_from)) {
Line 2416  PHP_FUNCTION(substr_replace) Line 2495  PHP_FUNCTION(substr_replace)
                                 } else {                                  } else {
                                         l = Z_STRLEN_P(orig_str);                                          l = Z_STRLEN_P(orig_str);
                                 }                                  }
                        } else if (argc > 3) {                         } else if (argc > 3) {
                                 l = Z_LVAL_PP(len);                                  l = Z_LVAL_PP(len);
                         } else {                          } else {
                                 l = Z_STRLEN_P(orig_str);                                  l = Z_STRLEN_P(orig_str);
Line 2448  PHP_FUNCTION(substr_replace) Line 2527  PHP_FUNCTION(substr_replace)
                                                 repl_str = *tmp_repl;                                                  repl_str = *tmp_repl;
                                         }                                          }
   
                                           if(Z_REFCOUNT_P(orig_str) != refcount) {
                                                   php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument was modified while replacing");
                                                   if(Z_TYPE_PP(tmp_repl) != IS_STRING) {
                                                           zval_dtor(repl_str);
                                                   }
                                                   break;
                                           }
   
                                         result_len += Z_STRLEN_P(repl_str);                                          result_len += Z_STRLEN_P(repl_str);
                                        zend_hash_move_forward_ex(Z_ARRVAL_PP(repl), &pos_repl);                                                zend_hash_move_forward_ex(Z_ARRVAL_PP(repl), &pos_repl);
                                         result = emalloc(result_len + 1);                                          result = emalloc(result_len + 1);
   
                                         memcpy(result, Z_STRVAL_P(orig_str), f);                                          memcpy(result, Z_STRVAL_P(orig_str), f);
Line 2460  PHP_FUNCTION(substr_replace) Line 2547  PHP_FUNCTION(substr_replace)
                                         }                                          }
                                 } else {                                  } else {
                                         result = emalloc(result_len + 1);                                          result = emalloc(result_len + 1);
        
                                         memcpy(result, Z_STRVAL_P(orig_str), f);                                          memcpy(result, Z_STRVAL_P(orig_str), f);
                                         memcpy((result + f), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l);                                          memcpy((result + f), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l);
                                 }                                  }
Line 2484  PHP_FUNCTION(substr_replace) Line 2571  PHP_FUNCTION(substr_replace)
   
                         if(Z_TYPE_PP(tmp_str) != IS_STRING) {                          if(Z_TYPE_PP(tmp_str) != IS_STRING) {
                                 zval_dtor(orig_str);                                  zval_dtor(orig_str);
                           } else {
                                   Z_SET_ISREF_TO_P(orig_str, was_ref);
                         }                          }
                         zend_hash_move_forward_ex(Z_ARRVAL_PP(str), &pos_str);                          zend_hash_move_forward_ex(Z_ARRVAL_PP(str), &pos_str);
                 } /*while*/                  } /*while*/
Line 2504  PHP_FUNCTION(quotemeta) Line 2593  PHP_FUNCTION(quotemeta)
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &old, &old_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &old, &old_len) == FAILURE) {
                 return;                  return;
         }          }
        
         old_end = old + old_len;          old_end = old + old_len;
                
         if (old == old_end) {          if (old == old_end) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
         str = safe_emalloc(2, old_len, 1);          str = safe_emalloc(2, old_len, 1);
        
         for (p = old, q = str; p != old_end; p++) {          for (p = old, q = str; p != old_end; p++) {
                 c = *p;                  c = *p;
                 switch (c) {                  switch (c) {
Line 2545  PHP_FUNCTION(ord) Line 2634  PHP_FUNCTION(ord)
 {  {
         char *str;          char *str;
         int   str_len;          int   str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
        
         RETURN_LONG((unsigned char) str[0]);          RETURN_LONG((unsigned char) str[0]);
 }  }
 /* }}} */  /* }}} */
Line 2578  PHP_FUNCTION(chr) Line 2667  PHP_FUNCTION(chr)
   
 /* {{{ php_ucfirst  /* {{{ php_ucfirst
    Uppercase the first character of the word in a native string */     Uppercase the first character of the word in a native string */
static void php_ucfirst(char *str) static void php_ucfirst(char *str)
 {  {
         register char *r;          register char *r;
         r = str;          r = str;
Line 2592  PHP_FUNCTION(ucfirst) Line 2681  PHP_FUNCTION(ucfirst)
 {  {
         char *str;          char *str;
         int  str_len;          int  str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
Line 2643  PHP_FUNCTION(ucwords) Line 2732  PHP_FUNCTION(ucwords)
         char *str;          char *str;
         register char *r, *r_end;          register char *r, *r_end;
         int str_len;          int str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
Line 2689  PHPAPI char *php_strtr(char *str, int len, char *str_f Line 2778  PHPAPI char *php_strtr(char *str, int len, char *str_f
 }  }
 /* }}} */  /* }}} */
   
/* {{{ php_strtr_array/* {{{ Definitions for php_strtr_array */
 */typedef size_t STRLEN;  /* STRLEN should be unsigned */
static void php_strtr_array(zval *return_value, char *str, int slen, HashTable *hash)typedef uint16_t HASH;
 typedef struct {
         HASH                    table_mask;
         STRLEN                  entries[1];
 } SHIFT_TAB;
 typedef struct {
         HASH                    table_mask;
         int                             entries[1];
 } HASH_TAB;
 typedef struct {
         const char      *s;
         STRLEN          l;
 } STR;
 typedef struct _pat_and_repl {
         STR                     pat;
         STR                     repl;
 } PATNREPL;
 
 #define S(a) ((a)->s)
 #define L(a) ((a)->l)
 
 #define SHIFT_TAB_BITS  13
 #define HASH_TAB_BITS   10 /* should be less than sizeof(HASH) * 8 */
 #define SHIFT_TAB_SIZE  (1U << SHIFT_TAB_BITS)
 #define HASH_TAB_SIZE   (1U << HASH_TAB_BITS)
 
 typedef struct {
         int                             B;                      /* size of suffixes */
         int                             Bp;                     /* size of prefixes */
         STRLEN                  m;                      /* minimum pattern length */
         int                             patnum;         /* number of patterns */
         SHIFT_TAB               *shift;         /* table mapping hash to allowed shift */
         HASH_TAB                *hash;          /* table mapping hash to int (pair of pointers) */
         HASH                    *prefix;        /* array of hashes of prefixes by pattern suffix hash order */
         PATNREPL                *patterns;      /* array of prefixes by pattern suffix hash order */
 } PPRES;
 /* }}} */
 
 /* {{{ php_strtr_hash */
 static inline HASH php_strtr_hash(const char *str, int len)
 {  {
        zval **entry;        HASH    res = 0;
        char  *string_key;        int             i;
        uint   string_key_len;        for (i = 0; i < len; i++) {
        zval **trans;                res = res * 33 + (unsigned char)str[i];
        zval   ctmp;        }
        ulong num_key; 
        int minlen = 128*1024; 
        int maxlen = 0, pos, len, found; 
        char *key; 
        HashPosition hpos; 
        smart_str result = {0}; 
        HashTable tmp_hash; 
         
        zend_hash_init(&tmp_hash, zend_hash_num_elements(hash), NULL, NULL, 0); 
        zend_hash_internal_pointer_reset_ex(hash, &hpos); 
        while (zend_hash_get_current_data_ex(hash, (void **)&entry, &hpos) == SUCCESS) { 
                switch (zend_hash_get_current_key_ex(hash, &string_key, &string_key_len, &num_key, 0, &hpos)) { 
                        case HASH_KEY_IS_STRING: 
                                len = string_key_len-1; 
                                if (len < 1) { 
                                        zend_hash_destroy(&tmp_hash); 
                                        RETURN_FALSE; 
                                } 
                                zend_hash_add(&tmp_hash, string_key, string_key_len, entry, sizeof(zval*), NULL); 
                                if (len > maxlen) { 
                                        maxlen = len; 
                                } 
                                if (len < minlen) { 
                                        minlen = len; 
                                } 
                                break;  
                         
                        case HASH_KEY_IS_LONG: 
                                Z_TYPE(ctmp) = IS_LONG; 
                                Z_LVAL(ctmp) = num_key; 
                         
                                convert_to_string(&ctmp); 
                                len = Z_STRLEN(ctmp); 
                                zend_hash_add(&tmp_hash, Z_STRVAL(ctmp), len+1, entry, sizeof(zval*), NULL); 
                                zval_dtor(&ctmp); 
   
                                if (len > maxlen) {        return res;
                                        maxlen = len;}
                                }/* }}} */
                                if (len < minlen) {/* {{{ php_strtr_populate_shift */
                                        minlen = len;static inline void php_strtr_populate_shift(PATNREPL *patterns, int patnum, int B, STRLEN m, SHIFT_TAB *shift)
                                }{
                                break;        int             i;
         STRLEN  j,
                         max_shift;
 
         max_shift = m - B + 1;
         for (i = 0; i < SHIFT_TAB_SIZE; i++) {
                 shift->entries[i] = max_shift;
         }
         for (i = 0; i < patnum; i++) {
                 for (j = 0; j < m - B + 1; j++) {
                         HASH h = php_strtr_hash(&S(&patterns[i].pat)[j], B) & shift->table_mask;
                         assert((long long) m - (long long) j - B >= 0);
                         shift->entries[h] = MIN(shift->entries[h], m - j - B);
                 }                  }
                 zend_hash_move_forward_ex(hash, &hpos);  
         }          }
   }
   /* }}} */
   /* {{{ php_strtr_compare_hash_suffix */
   static int php_strtr_compare_hash_suffix(const void *a, const void *b, void *ctx_g)
   {
           const PPRES             *res = ctx_g;
           const PATNREPL  *pnr_a = a,
                                           *pnr_b = b;
           HASH                    hash_a = php_strtr_hash(&S(&pnr_a->pat)[res->m - res->B], res->B)
                                                                   & res->hash->table_mask,
                                           hash_b = php_strtr_hash(&S(&pnr_b->pat)[res->m - res->B], res->B)
                                                                   & res->hash->table_mask;
           /* TODO: don't recalculate the hashes all the time */
           if (hash_a > hash_b) {
                   return 1;
           } else if (hash_a < hash_b) {
                   return -1;
           } else {
                   /* longer patterns must be sorted first */
                   if (L(&pnr_a->pat) > L(&pnr_b->pat)) {
                           return -1;
                   } else if (L(&pnr_a->pat) < L(&pnr_b->pat)) {
                           return 1;
                   } else {
                           return 0;
                   }
           }
   }
   /* }}} */
   /* {{{ Sorting (no zend_qsort_r in this PHP version) */
   #define HS_LEFT(i)              ((i) * 2 + 1)
   #define HS_RIGHT(i)     ((i) * 2 + 2)
   #define HS_PARENT(i)    (((i) - 1) / 2);
   #define HS_OFF(data, i) ((void *)(&((data)->arr)[i]))
   #define HS_CMP_CALL(data, i1, i2) \
                   (php_strtr_compare_hash_suffix(HS_OFF((data), (i1)), HS_OFF((data), (i2)), (data)->res))
   struct hs_data {
           PATNREPL        *arr;
           size_t          nel;
           size_t          heapel;
           PPRES           *res;
   };
   static inline void php_strtr_swap(PATNREPL *a, PATNREPL *b)
   {
           PATNREPL tmp = *a;
           *a = *b;
           *b = tmp;
   }
   static inline void php_strtr_fix_heap(struct hs_data *data, size_t i)
   {
           size_t  li =    HS_LEFT(i),
                           ri =    HS_RIGHT(i),
                           largei;
           if (li < data->heapel && HS_CMP_CALL(data, li, i) > 0) {
                   largei = li;
           } else {
                   largei = i;
           }
           if (ri < data->heapel && HS_CMP_CALL(data, ri, largei) > 0) {
                   largei = ri;
           }
           if (largei != i) {
                   php_strtr_swap(HS_OFF(data, i), HS_OFF(data, largei));
                   php_strtr_fix_heap(data, largei);
           }
   }
   static inline void php_strtr_build_heap(struct hs_data *data)
   {
           size_t i;
           for (i = data->nel / 2; i > 0; i--) {
                   php_strtr_fix_heap(data, i - 1);
           }
   }
   static inline void php_strtr_heapsort(PATNREPL *arr, size_t nel, PPRES *res)
   {
           struct hs_data data = { arr, nel, nel, res };
           size_t i;
           php_strtr_build_heap(&data);
           for (i = nel; i > 1; i--) {
                   php_strtr_swap(arr, HS_OFF(&data, i - 1));
                   data.heapel--;
                   php_strtr_fix_heap(&data, 0);
           }
   }
   /* }}} */
   /* {{{ php_strtr_free_strp */
   static void php_strtr_free_strp(void *strp)
   {
           STR_FREE(*(char**)strp);
   }
   /* }}} */
   /* {{{ php_strtr_array_prepare_repls */
   static PATNREPL *php_strtr_array_prepare_repls(int slen, HashTable *pats, zend_llist **allocs, int *outsize)
   {
           PATNREPL                *patterns;
           HashPosition    hpos;
           zval                    **entry;
           int                             num_pats = zend_hash_num_elements(pats),
                                           i;
   
        key = emalloc(maxlen+1);        patterns = safe_emalloc(num_pats, sizeof(*patterns), 0);
        pos = 0;        *allocs = emalloc(sizeof **allocs);
         zend_llist_init(*allocs, sizeof(void*), &php_strtr_free_strp, 0);
   
        while (pos < slen) {        for (i = 0, zend_hash_internal_pointer_reset_ex(pats, &hpos);
                if ((pos + maxlen) > slen) {                        zend_hash_get_current_data_ex(pats, (void **)&entry, &hpos) == SUCCESS;
                        maxlen = slen - pos;                        zend_hash_move_forward_ex(pats, &hpos)) {
                 char    *string_key;
                 uint    string_key_len;
                 ulong   num_key;
                 zval    *tzv = NULL;
 
                 switch (zend_hash_get_current_key_ex(pats, &string_key, &string_key_len, &num_key, 0, &hpos)) {
                 case HASH_KEY_IS_LONG:
                         string_key_len = 1 + zend_spprintf(&string_key, 0, "%ld", (long)num_key);
                         zend_llist_add_element(*allocs, &string_key);
                         /* break missing intentionally */
 
                 case HASH_KEY_IS_STRING:
                         string_key_len--; /* exclude final '\0' */
                         if (string_key_len == 0) { /* empty string given as pattern */
                                 efree(patterns);
                                 zend_llist_destroy(*allocs);
                                 efree(*allocs);
                                 *allocs = NULL;
                                 return NULL;
                         }
                         if (string_key_len > slen) { /* this pattern can never match */
                                 continue;
                         }
 
                         if (Z_TYPE_PP(entry) != IS_STRING) {
                                 tzv = *entry;
                                 zval_addref_p(tzv);
                                 SEPARATE_ZVAL(&tzv);
                                 convert_to_string(tzv);
                                 entry = &tzv;
                                 zend_llist_add_element(*allocs, &Z_STRVAL_PP(entry));
                         }
 
                         S(&patterns[i].pat) = string_key;
                         L(&patterns[i].pat) = string_key_len;
                         S(&patterns[i].repl) = Z_STRVAL_PP(entry);
                         L(&patterns[i].repl) = Z_STRLEN_PP(entry);
                         i++;
 
                         if (tzv) {
                                 efree(tzv);
                         }
                 }                  }
           }
   
                found = 0;        *outsize = i;
                memcpy(key, str+pos, maxlen);        return patterns;
 }
 /* }}} */
   
                for (len = maxlen; len >= minlen; len--) {/* {{{ PPRES *php_strtr_array_prepare(STR *text, PATNREPL *patterns, int patnum, int B, int Bp) */
                        key[len] = 0;static PPRES *php_strtr_array_prepare(STR *text, PATNREPL *patterns, int patnum, int B, int Bp)
                        {
                        if (zend_hash_find(&tmp_hash, key, len+1, (void**)&trans) == SUCCESS) {        int             i;
                                char *tval;        PPRES   *res = emalloc(sizeof *res);
                                int tlen; 
                                zval tmp; 
   
                                if (Z_TYPE_PP(trans) != IS_STRING) {        res->m = (STRLEN)-1;
                                        tmp = **trans;        for (i = 0; i < patnum; i++) {
                                        zval_copy_ctor(&tmp);                if (L(&patterns[i].pat) < res->m) {
                                        convert_to_string(&tmp);                        res->m = L(&patterns[i].pat);
                                        tval = Z_STRVAL(tmp);                }
                                        tlen = Z_STRLEN(tmp);        }
                                } else {        assert(res->m > 0);
                                        tval = Z_STRVAL_PP(trans);        res->B  = B             = MIN(B, res->m);
                                        tlen = Z_STRLEN_PP(trans);        res->Bp = Bp    = MIN(Bp, res->m);
                                } 
   
                                smart_str_appendl(&result, tval, tlen);        res->shift = safe_emalloc(SHIFT_TAB_SIZE, sizeof(*res->shift->entries), sizeof(*res->shift));
                                pos += len;        res->shift->table_mask = SHIFT_TAB_SIZE - 1;
                                found = 1;        php_strtr_populate_shift(patterns, patnum, B, res->m, res->shift);
   
                                if (Z_TYPE_PP(trans) != IS_STRING) {        res->hash = safe_emalloc(HASH_TAB_SIZE, sizeof(*res->hash->entries), sizeof(*res->hash));
                                        zval_dtor(&tmp);        res->hash->table_mask = HASH_TAB_SIZE - 1;
                                }
                                break;        res->patterns = safe_emalloc(patnum, sizeof(*res->patterns), 0);
                        }         memcpy(res->patterns, patterns, sizeof(*patterns) * patnum);
         php_strtr_heapsort(res->patterns, patnum, res);
 
         res->prefix = safe_emalloc(patnum, sizeof(*res->prefix), 0);
         for (i = 0; i < patnum; i++) {
                 res->prefix[i] = php_strtr_hash(S(&res->patterns[i].pat), Bp);
         }
 
         /* Initialize the rest of ->hash */
         for (i = 0; i < HASH_TAB_SIZE; i++) {
                 res->hash->entries[i] = -1;
         }
         {
                 HASH last_h = -1; /* assumes not all bits are used in res->hash */
                 /* res->patterns is already ordered by hash.
                  * Make res->hash->entries[h] de index of the first pattern in
                  * res->patterns that has hash h */
                 for (i = 0; i < patnum; i++) {
                         HASH h = php_strtr_hash(&S(&res->patterns[i].pat)[res->m - res->B], res->B)
                                                 & res->hash->table_mask;
                         if (h != last_h) {
                                 res->hash->entries[h] = i;
                                 last_h = h;
                         }
                 }                  }
           }
           res->hash->entries[HASH_TAB_SIZE] = patnum; /* OK, we effectively allocated SIZE+1 */
           for (i = HASH_TAB_SIZE - 1; i >= 0; i--) {
                   if (res->hash->entries[i] == -1) {
                           res->hash->entries[i] = res->hash->entries[i + 1];
                   }
           }
   
                if (! found) {        res->patnum     = patnum;
                        smart_str_appendc(&result, str[pos++]);
         return res;
 }
 /* }}} */
 /* {{{ php_strtr_array_destroy_ppres(PPRES *d) */
 static void php_strtr_array_destroy_ppres(PPRES *d)
 {
         efree(d->shift);
         efree(d->hash);
         efree(d->prefix);
         efree(d->patterns);
         efree(d);
 }
 /* }}} */
 
 /* {{{ php_strtr_array_do_repl(STR *text, PPRES *d, zval *return_value) */
 static void php_strtr_array_do_repl(STR *text, PPRES *d, zval *return_value)
 {
         STRLEN          pos = 0,
                                 nextwpos = 0,
                                 lastpos = L(text) - d->m;
         smart_str       result = {0};
 
         while (pos <= lastpos) {
                 HASH    h               = php_strtr_hash(&S(text)[pos + d->m - d->B], d->B) & d->shift->table_mask;
                 STRLEN  shift   = d->shift->entries[h];
 
                 if (shift > 0) {
                         pos += shift;
                 } else {
                         HASH    h2                              = h & d->hash->table_mask,
                                         prefix_h                = php_strtr_hash(&S(text)[pos], d->Bp);
 
                         int             offset_start    = d->hash->entries[h2],
                                         offset_end              = d->hash->entries[h2 + 1], /* exclusive */
                                         i                               = 0;
 
                         for (i = offset_start; i < offset_end; i++) {
                                 PATNREPL *pnr;
                                 if (d->prefix[i] != prefix_h)
                                         continue;
 
                                 pnr = &d->patterns[i];
                                 if (L(&pnr->pat) > L(text) - pos ||
                                                 memcmp(S(&pnr->pat), &S(text)[pos], L(&pnr->pat)) != 0)
                                         continue;
 
                                 smart_str_appendl(&result, &S(text)[nextwpos], pos - nextwpos);
                                 smart_str_appendl(&result, S(&pnr->repl), L(&pnr->repl));
                                 pos += L(&pnr->pat);
                                 nextwpos = pos;
                                 goto end_outer_loop;
                         }
 
                         pos++;
 end_outer_loop: ;
                 }                  }
         }          }
   
        efree(key);        smart_str_appendl(&result, &S(text)[nextwpos], L(text) - nextwpos);
        zend_hash_destroy(&tmp_hash);
        smart_str_0(&result);        if (result.c != NULL) {
        RETVAL_STRINGL(result.c, result.len, 0);                smart_str_0(&result);
                 RETVAL_STRINGL(result.c, result.len, 0);
         } else {
                 RETURN_EMPTY_STRING();
         }
 }  }
 /* }}} */  /* }}} */
   
   /* {{{ php_strtr_array */
   static void php_strtr_array(zval *return_value, char *str, int slen, HashTable *pats)
   {
           PPRES           *data;
           STR                     text;
           PATNREPL        *patterns;
           int                     patterns_len;
           zend_llist      *allocs;
   
           S(&text) = str;
           L(&text) = slen;
   
           patterns = php_strtr_array_prepare_repls(slen, pats, &allocs, &patterns_len);
           if (patterns == NULL) {
                   RETURN_FALSE;
           }
           data = php_strtr_array_prepare(&text, patterns, patterns_len, 2, 2);
           efree(patterns);
           php_strtr_array_do_repl(&text, data, return_value);
           php_strtr_array_destroy_ppres(data);
           zend_llist_destroy(allocs);
           efree(allocs);
   }
   /* }}} */
   
 /* {{{ proto string strtr(string str, string from[, string to])  /* {{{ proto string strtr(string str, string from[, string to])
    Translates characters in str using given translation tables */     Translates characters in str using given translation tables */
 PHP_FUNCTION(strtr)  PHP_FUNCTION(strtr)
{                                                               {
         zval **from;          zval **from;
         char *str, *to = NULL;          char *str, *to = NULL;
         int str_len, to_len = 0;          int str_len, to_len = 0;
         int ac = ZEND_NUM_ARGS();          int ac = ZEND_NUM_ARGS();
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|s", &str, &str_len, &from, &to, &to_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|s", &str, &str_len, &from, &to, &to_len) == FAILURE) {
                 return;                  return;
         }          }
        
         if (ac == 2 && Z_TYPE_PP(from) != IS_ARRAY) {          if (ac == 2 && Z_TYPE_PP(from) != IS_ARRAY) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument is not an array");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument is not an array");
                 RETURN_FALSE;                  RETURN_FALSE;
Line 2827  PHP_FUNCTION(strtr) Line 3187  PHP_FUNCTION(strtr)
                 convert_to_string_ex(from);                  convert_to_string_ex(from);
   
                 ZVAL_STRINGL(return_value, str, str_len, 1);                  ZVAL_STRINGL(return_value, str, str_len, 1);
                
                 php_strtr(Z_STRVAL_P(return_value),                  php_strtr(Z_STRVAL_P(return_value),
                                   Z_STRLEN_P(return_value),                                    Z_STRLEN_P(return_value),
                                   Z_STRVAL_PP(from),                                    Z_STRVAL_PP(from),
                                   to,                                    to,
                                  MIN(Z_STRLEN_PP(from),                                   MIN(Z_STRLEN_PP(from),
                                   to_len));                                    to_len));
         }          }
 }  }
Line 2845  PHP_FUNCTION(strrev) Line 3205  PHP_FUNCTION(strrev)
         char *str;          char *str;
         char *e, *n, *p;          char *e, *n, *p;
         int  str_len;          int  str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
        
         n = emalloc(str_len+1);          n = emalloc(str_len+1);
         p = n;          p = n;
        
         e = str + str_len;          e = str + str_len;
        
         while (--e>=str) {          while (--e>=str) {
                 *p++ = *e;                  *p++ = *e;
         }          }
        
         *p = '\0';          *p = '\0';
        
         RETVAL_STRINGL(n, str_len, 0);          RETVAL_STRINGL(n, str_len, 0);
 }  }
 /* }}} */  /* }}} */
Line 2873  static void php_similar_str(const char *txt1, int len1 Line 3233  static void php_similar_str(const char *txt1, int len1
         char *end1 = (char *) txt1 + len1;          char *end1 = (char *) txt1 + len1;
         char *end2 = (char *) txt2 + len2;          char *end2 = (char *) txt2 + len2;
         int l;          int l;
        
         *max = 0;          *max = 0;
         for (p = (char *) txt1; p < end1; p++) {          for (p = (char *) txt1; p < end1; p++) {
                 for (q = (char *) txt2; q < end2; q++) {                  for (q = (char *) txt2; q < end2; q++) {
Line 2893  static void php_similar_str(const char *txt1, int len1 Line 3253  static void php_similar_str(const char *txt1, int len1
 static int php_similar_char(const char *txt1, int len1, const char *txt2, int len2)  static int php_similar_char(const char *txt1, int len1, const char *txt2, int len2)
 {  {
         int sum;          int sum;
        int pos1, pos2, max;        int pos1 = 0, pos2 = 0, max;
   
         php_similar_str(txt1, len1, txt2, len2, &pos1, &pos2, &max);          php_similar_str(txt1, len1, txt2, len2, &pos1, &pos2, &max);
         if ((sum = max)) {          if ((sum = max)) {
                 if (pos1 && pos2) {                  if (pos1 && pos2) {
                        sum += php_similar_char(txt1, pos1,                         sum += php_similar_char(txt1, pos1,
                                                                         txt2, pos2);                                                                          txt2, pos2);
                 }                  }
                 if ((pos1 + max < len1) && (pos2 + max < len2)) {                  if ((pos1 + max < len1) && (pos2 + max < len2)) {
                        sum += php_similar_char(txt1 + pos1 + max, len1 - pos1 - max,                         sum += php_similar_char(txt1 + pos1 + max, len1 - pos1 - max,
                                                                         txt2 + pos2 + max, len2 - pos2 - max);                                                                          txt2 + pos2 + max, len2 - pos2 - max);
                 }                  }
         }          }
Line 2920  PHP_FUNCTION(similar_text) Line 3280  PHP_FUNCTION(similar_text)
         int ac = ZEND_NUM_ARGS();          int ac = ZEND_NUM_ARGS();
         int sim;          int sim;
         int t1_len, t2_len;          int t1_len, t2_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Z", &t1, &t1_len, &t2, &t2_len, &percent) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Z", &t1, &t1_len, &t2, &t2_len, &percent) == FAILURE) {
                 return;                  return;
         }          }
        
         if (ac > 2) {          if (ac > 2) {
                 convert_to_double_ex(percent);                  convert_to_double_ex(percent);
         }          }
        
         if (t1_len + t2_len == 0) {          if (t1_len + t2_len == 0) {
                 if (ac > 2) {                  if (ac > 2) {
                         Z_DVAL_PP(percent) = 0;                          Z_DVAL_PP(percent) = 0;
Line 2936  PHP_FUNCTION(similar_text) Line 3296  PHP_FUNCTION(similar_text)
   
                 RETURN_LONG(0);                  RETURN_LONG(0);
         }          }
           
         sim = php_similar_char(t1, t1_len, t2, t2_len);   
   
           sim = php_similar_char(t1, t1_len, t2, t2_len);
   
         if (ac > 2) {          if (ac > 2) {
                 Z_DVAL_PP(percent) = sim * 200.0 / (t1_len + t2_len);                  Z_DVAL_PP(percent) = sim * 200.0 / (t1_len + t2_len);
         }          }
Line 2963  PHPAPI void php_stripslashes(char *str, int *len TSRML Line 3323  PHPAPI void php_stripslashes(char *str, int *len TSRML
         s = str;          s = str;
         t = str;          t = str;
   
         if (PG(magic_quotes_sybase)) {  
                 while (l > 0) {  
                         if (*t == '\'') {  
                                 if ((l > 0) && (t[1] == '\'')) {  
                                         t++;  
                                         if (len != NULL) {  
                                                 (*len)--;  
                                         }  
                                         l--;  
                                 }  
                                 *s++ = *t++;  
                         } else if (*t == '\\' && t[1] == '0' && l > 0) {  
                                 *s++='\0';  
                                 t+=2;  
                                 if (len != NULL) {  
                                         (*len)--;  
                                 }  
                                 l--;  
                         } else {  
                                 *s++ = *t++;  
                         }  
                         l--;  
                 }  
                 *s = '\0';  
                   
                 return;  
         }  
   
         while (l > 0) {          while (l > 0) {
                 if (*t == '\\') {                  if (*t == '\\') {
                         t++;                            /* skip the slash */                          t++;                            /* skip the slash */
Line 3048  PHP_FUNCTION(addslashes) Line 3380  PHP_FUNCTION(addslashes)
 {  {
         char *str;          char *str;
         int  str_len;          int  str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
Line 3058  PHP_FUNCTION(addslashes) Line 3390  PHP_FUNCTION(addslashes)
         }          }
   
         RETURN_STRING(php_addslashes(str,          RETURN_STRING(php_addslashes(str,
                                     str_len,                                      str_len,
                                     &Z_STRLEN_P(return_value), 0                                      &Z_STRLEN_P(return_value), 0
                                      TSRMLS_CC), 0);                                       TSRMLS_CC), 0);
 }  }
 /* }}} */  /* }}} */
Line 3070  PHP_FUNCTION(stripcslashes) Line 3402  PHP_FUNCTION(stripcslashes)
 {  {
         char *str;          char *str;
         int  str_len;          int  str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
Line 3086  PHP_FUNCTION(stripslashes) Line 3418  PHP_FUNCTION(stripslashes)
 {  {
         char *str;          char *str;
         int  str_len;          int  str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
                 return;                  return;
         }          }
Line 3099  PHP_FUNCTION(stripslashes) Line 3431  PHP_FUNCTION(stripslashes)
 #ifndef HAVE_STRERROR  #ifndef HAVE_STRERROR
 /* {{{ php_strerror  /* {{{ php_strerror
  */   */
char *php_strerror(int errnum) char *php_strerror(int errnum)
 {  {
         extern int sys_nerr;          extern int sys_nerr;
         extern char *sys_errlist[];          extern char *sys_errlist[];
Line 3150  PHPAPI void php_stripcslashes(char *str, int *len) Line 3482  PHPAPI void php_stripcslashes(char *str, int *len)
                                                 break;                                                  break;
                                         }                                          }
                                         /* break is left intentionally */                                          /* break is left intentionally */
                                default:                                 default:
                                        i=0;                                         i=0;
                                         while (source < end && *source >= '0' && *source <= '7' && i<3) {                                          while (source < end && *source >= '0' && *source <= '7' && i<3) {
                                                 numtmp[i++] = *source++;                                                  numtmp[i++] = *source++;
                                         }                                          }
Line 3177  PHPAPI void php_stripcslashes(char *str, int *len) Line 3509  PHPAPI void php_stripcslashes(char *str, int *len)
         *len = nlen;          *len = nlen;
 }  }
 /* }}} */  /* }}} */
                        
 /* {{{ php_addcslashes  /* {{{ php_addcslashes
  */   */
PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int should_free, char *what, int wlength TSRMLS_DC)PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int should_free, char *what, int wlength TSRMLS_DC)
 {  {
         char flags[256];          char flags[256];
         char *new_str = safe_emalloc(4, (length?length:(length=strlen(str))), 1);          char *new_str = safe_emalloc(4, (length?length:(length=strlen(str))), 1);
Line 3195  PHPAPI char *php_addcslashes(char *str, int length, in Line 3527  PHPAPI char *php_addcslashes(char *str, int length, in
   
         php_charmask((unsigned char *)what, wlength, flags TSRMLS_CC);          php_charmask((unsigned char *)what, wlength, flags TSRMLS_CC);
   
        for (source = str, end = source + length, target = new_str; source < end; source++) {        for (source = (char*)str, end = source + length, target = new_str; source < end; source++) {
                c = *source;                 c = *source;
                 if (flags[(unsigned char)c]) {                  if (flags[(unsigned char)c]) {
                         if ((unsigned char) c < 32 || (unsigned char) c > 126) {                          if ((unsigned char) c < 32 || (unsigned char) c > 126) {
                                 *target++ = '\\';                                  *target++ = '\\';
Line 3211  PHPAPI char *php_addcslashes(char *str, int length, in Line 3543  PHPAPI char *php_addcslashes(char *str, int length, in
                                         default: target += sprintf(target, "%03o", (unsigned char) c);                                          default: target += sprintf(target, "%03o", (unsigned char) c);
                                 }                                  }
                                 continue;                                  continue;
                        }                         }
                         *target++ = '\\';                          *target++ = '\\';
                 }                  }
                 *target++ = c;                  *target++ = c;
Line 3225  PHPAPI char *php_addcslashes(char *str, int length, in Line 3557  PHPAPI char *php_addcslashes(char *str, int length, in
                 *new_length = newlen;                  *new_length = newlen;
         }          }
         if (should_free) {          if (should_free) {
                STR_FREE(str);                STR_FREE((char*)str);
         }          }
         return new_str;          return new_str;
 }  }
Line 3235  PHPAPI char *php_addcslashes(char *str, int length, in Line 3567  PHPAPI char *php_addcslashes(char *str, int length, in
  */   */
 PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC)  PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC)
 {  {
         return php_addslashes_ex(str, length, new_length, should_free, 0 TSRMLS_CC);  
 }  
 /* }}} */  
   
 /* {{{ php_addslashes_ex  
  */  
 PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int should_free, int ignore_sybase TSRMLS_DC)  
 {  
         /* maximum string length, worst case situation */          /* maximum string length, worst case situation */
         char *new_str;          char *new_str;
         char *source, *target;          char *source, *target;
         char *end;          char *end;
         int local_new_length;          int local_new_length;
                
         if (!new_length) {          if (!new_length) {
                 new_length = &local_new_length;                  new_length = &local_new_length;
         }          }
Line 3260  PHPAPI char *php_addslashes_ex(char *str, int length,  Line 3584  PHPAPI char *php_addslashes_ex(char *str, int length, 
         source = str;          source = str;
         end = source + length;          end = source + length;
         target = new_str;          target = new_str;
        
        if (!ignore_sybase && PG(magic_quotes_sybase)) {        while (source < end) {
                while (source < end) {                switch (*source) {
                        switch (*source) {                        case '\0':
                                case '\0':                                *target++ = '\\';
                                        *target++ = '\\';                                *target++ = '0';
                                        *target++ = '0';                                break;
                                        break;                        case '\'':
                                case '\'':                        case '\"':
                                        *target++ = '\'';                        case '\\':
                                        *target++ = '\'';                                *target++ = '\\';
                                        break;                                /* break is missing *intentionally* */
                                default:                        default:
                                        *target++ = *source;                                *target++ = *source;
                                        break;                                break;
                        } 
                        source++; 
                 }                  }
        } else {
                while (source < end) {                source++;
                        switch (*source) { 
                                case '\0': 
                                        *target++ = '\\'; 
                                        *target++ = '0'; 
                                        break; 
                                case '\'': 
                                case '\"': 
                                case '\\': 
                                        *target++ = '\\'; 
                                        /* break is missing *intentionally* */ 
                                default: 
                                        *target++ = *source; 
                                        break;   
                        } 
                 
                        source++; 
                } 
         }          }
        
         *target = 0;          *target = 0;
         *new_length = target - new_str;          *new_length = target - new_str;
         if (should_free) {          if (should_free) {
Line 3322  PHPAPI int php_char_to_str_ex(char *str, uint len, cha Line 3627  PHPAPI int php_char_to_str_ex(char *str, uint len, cha
         int char_count = 0;          int char_count = 0;
         int replaced = 0;          int replaced = 0;
         char *source, *target, *tmp, *source_end=str+len, *tmp_end = NULL;          char *source, *target, *tmp, *source_end=str+len, *tmp_end = NULL;
                
         if (case_sensitivity) {          if (case_sensitivity) {
                 char *p = str, *e = p + len;                  char *p = str, *e = p + len;
                 while ((p = memchr(p, from, (e - p)))) {                  while ((p = memchr(p, from, (e - p)))) {
Line 3341  PHPAPI int php_char_to_str_ex(char *str, uint len, cha Line 3646  PHPAPI int php_char_to_str_ex(char *str, uint len, cha
                 ZVAL_STRINGL(result, str, len, 1);                  ZVAL_STRINGL(result, str, len, 1);
                 return 0;                  return 0;
         }          }
        
         Z_STRLEN_P(result) = len + (char_count * (to_len - 1));          Z_STRLEN_P(result) = len + (char_count * (to_len - 1));
         Z_STRVAL_P(result) = target = safe_emalloc(char_count, to_len, len + 1);          Z_STRVAL_P(result) = target = safe_emalloc(char_count, to_len, len + 1);
         Z_TYPE_P(result) = IS_STRING;          Z_TYPE_P(result) = IS_STRING;
Line 3395  PHPAPI int php_char_to_str(char *str, uint len, char f Line 3700  PHPAPI int php_char_to_str(char *str, uint len, char f
   
 /* {{{ php_str_to_str_ex  /* {{{ php_str_to_str_ex
  */   */
PHPAPI char *php_str_to_str_ex(char *haystack, int length, PHPAPI char *php_str_to_str_ex(char *haystack, int length,
         char *needle, int needle_len, char *str, int str_len, int *_new_length, int case_sensitivity, int *replace_count)          char *needle, int needle_len, char *str, int str_len, int *_new_length, int case_sensitivity, int *replace_count)
 {  {
         char *new_str;          char *new_str;
Line 3567  nothing_todo: Line 3872  nothing_todo:
   
 /* {{{ php_str_to_str  /* {{{ php_str_to_str
  */   */
PHPAPI char *php_str_to_str(char *haystack, int length, PHPAPI char *php_str_to_str(char *haystack, int length,
         char *needle, int needle_len, char *str, int str_len, int *_new_length)          char *needle, int needle_len, char *str, int str_len, int *_new_length)
 {  {
         return php_str_to_str_ex(haystack, length, needle, needle_len, str, str_len, _new_length, 1, NULL);          return php_str_to_str_ex(haystack, length, needle, needle_len, str, str_len, _new_length, 1, NULL);
}
 /* }}} */  /* }}} */
   
 /* {{{ php_str_replace_in_subject  /* {{{ php_str_replace_in_subject
Line 3584  static void php_str_replace_in_subject(zval *search, z Line 3889  static void php_str_replace_in_subject(zval *search, z
         char            *replace_value = NULL;          char            *replace_value = NULL;
         int                      replace_len = 0;          int                      replace_len = 0;
   
        /* Make sure we're dealing with strings. */             /* Make sure we're dealing with strings. */
         convert_to_string_ex(subject);          convert_to_string_ex(subject);
         Z_TYPE_P(result) = IS_STRING;          Z_TYPE_P(result) = IS_STRING;
         if (Z_STRLEN_PP(subject) == 0) {          if (Z_STRLEN_PP(subject) == 0) {
                 ZVAL_STRINGL(result, "", 0, 1);                  ZVAL_STRINGL(result, "", 0, 1);
                 return;                  return;
         }          }
        
         /* If search is an array */          /* If search is an array */
         if (Z_TYPE_P(search) == IS_ARRAY) {          if (Z_TYPE_P(search) == IS_ARRAY) {
                 /* Duplicate subject string for repeated replacement */                  /* Duplicate subject string for repeated replacement */
                 MAKE_COPY_ZVAL(subject, result);                  MAKE_COPY_ZVAL(subject, result);
                
                 zend_hash_internal_pointer_reset(Z_ARRVAL_P(search));                  zend_hash_internal_pointer_reset(Z_ARRVAL_P(search));
   
                 if (Z_TYPE_P(replace) == IS_ARRAY) {                  if (Z_TYPE_P(replace) == IS_ARRAY) {
Line 3609  static void php_str_replace_in_subject(zval *search, z Line 3914  static void php_str_replace_in_subject(zval *search, z
   
                 /* For each entry in the search array, get the entry */                  /* For each entry in the search array, get the entry */
                 while (zend_hash_get_current_data(Z_ARRVAL_P(search), (void **) &search_entry) == SUCCESS) {                  while (zend_hash_get_current_data(Z_ARRVAL_P(search), (void **) &search_entry) == SUCCESS) {
                        /* Make sure we're dealing with strings. */                             /* Make sure we're dealing with strings. */
                         SEPARATE_ZVAL(search_entry);                          SEPARATE_ZVAL(search_entry);
                         convert_to_string(*search_entry);                          convert_to_string(*search_entry);
                         if (Z_STRLEN_PP(search_entry) == 0) {                          if (Z_STRLEN_PP(search_entry) == 0) {
Line 3624  static void php_str_replace_in_subject(zval *search, z Line 3929  static void php_str_replace_in_subject(zval *search, z
                         if (Z_TYPE_P(replace) == IS_ARRAY) {                          if (Z_TYPE_P(replace) == IS_ARRAY) {
                                 /* Get current entry */                                  /* Get current entry */
                                 if (zend_hash_get_current_data(Z_ARRVAL_P(replace), (void **)&replace_entry) == SUCCESS) {                                  if (zend_hash_get_current_data(Z_ARRVAL_P(replace), (void **)&replace_entry) == SUCCESS) {
                                        /* Make sure we're dealing with strings. */                                             /* Make sure we're dealing with strings. */
                                         convert_to_string_ex(replace_entry);                                          convert_to_string_ex(replace_entry);
                                        
                                         /* Set replacement value to the one we got from array */                                          /* Set replacement value to the one we got from array */
                                         replace_value = Z_STRVAL_PP(replace_entry);                                          replace_value = Z_STRVAL_PP(replace_entry);
                                         replace_len = Z_STRLEN_PP(replace_entry);                                          replace_len = Z_STRLEN_PP(replace_entry);
Line 3638  static void php_str_replace_in_subject(zval *search, z Line 3943  static void php_str_replace_in_subject(zval *search, z
                                         replace_len = 0;                                          replace_len = 0;
                                 }                                  }
                         }                          }
                        
                         if (Z_STRLEN_PP(search_entry) == 1) {                          if (Z_STRLEN_PP(search_entry) == 1) {
                                 php_char_to_str_ex(Z_STRVAL_P(result),                                  php_char_to_str_ex(Z_STRVAL_P(result),
                                                                 Z_STRLEN_P(result),                                                                  Z_STRLEN_P(result),
Line 3654  static void php_str_replace_in_subject(zval *search, z Line 3959  static void php_str_replace_in_subject(zval *search, z
                                                                                                                    replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity, replace_count);                                                                                                                     replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity, replace_count);
                         }                          }
   
                        efree(Z_STRVAL_P(result));           str_efree(Z_STRVAL_P(result));
                         Z_STRVAL_P(result) = Z_STRVAL(temp_result);                          Z_STRVAL_P(result) = Z_STRVAL(temp_result);
                         Z_STRLEN_P(result) = Z_STRLEN(temp_result);                          Z_STRLEN_P(result) = Z_STRLEN(temp_result);
   
Line 3741  static void php_str_replace_common(INTERNAL_FUNCTION_P Line 4046  static void php_str_replace_common(INTERNAL_FUNCTION_P
                                         add_index_zval(return_value, num_key, result);                                          add_index_zval(return_value, num_key, result);
                                         break;                                          break;
                         }                          }
                
                         zend_hash_move_forward(Z_ARRVAL_PP(subject));                          zend_hash_move_forward(Z_ARRVAL_PP(subject));
                 }                  }
         } else {        /* if subject is not an array */          } else {        /* if subject is not an array */
                 php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity, (argc > 3) ? &count : NULL);                  php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity, (argc > 3) ? &count : NULL);
        }               }
         if (argc > 3) {          if (argc > 3) {
                 zval_dtor(*zcount);                  zval_dtor(*zcount);
                 ZVAL_LONG(*zcount, count);                  ZVAL_LONG(*zcount, count);
Line 3783  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i Line 4088  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i
         long max_chars=0;          long max_chars=0;
         int begin, end, char_count, orig_begin;          int begin, end, char_count, orig_begin;
         int str_len;          int str_len;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &max_chars) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &max_chars) == FAILURE) {
                 return;                  return;
         }          }
        
         if (str_len == 0) {          if (str_len == 0) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
Line 3807  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i Line 4112  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i
         } else {          } else {
                 block_type = _HEB_BLOCK_TYPE_ENG;                  block_type = _HEB_BLOCK_TYPE_ENG;
         }          }
        
         do {          do {
                 if (block_type == _HEB_BLOCK_TYPE_HEB) {                  if (block_type == _HEB_BLOCK_TYPE_HEB) {
                         while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end<str_len-1) {                          while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end<str_len-1) {
Line 3877  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i Line 4182  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i
         broken_str = (char *) emalloc(str_len+1);          broken_str = (char *) emalloc(str_len+1);
         begin=end=str_len-1;          begin=end=str_len-1;
         target = broken_str;          target = broken_str;
                
         while (1) {          while (1) {
                 char_count=0;                  char_count=0;
                 while ((!max_chars || char_count < max_chars) && begin > 0) {                  while ((!max_chars || char_count < max_chars) && begin > 0) {
Line 3893  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i Line 4198  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i
                 }                  }
                 if (char_count == max_chars) { /* try to avoid breaking words */                  if (char_count == max_chars) { /* try to avoid breaking words */
                         int new_char_count=char_count, new_begin=begin;                          int new_char_count=char_count, new_begin=begin;
                        
                         while (new_char_count > 0) {                          while (new_char_count > 0) {
                                 if (_isblank(heb_str[new_begin]) || _isnewline(heb_str[new_begin])) {                                  if (_isblank(heb_str[new_begin]) || _isnewline(heb_str[new_begin])) {
                                         break;                                          break;
Line 3902  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i Line 4207  static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, i
                                 new_char_count--;                                  new_char_count--;
                         }                          }
                         if (new_char_count > 0) {                          if (new_char_count > 0) {
                                 char_count=new_char_count;  
                                 begin=new_begin;                                  begin=new_begin;
                         }                          }
                 }                  }
                 orig_begin=begin;                  orig_begin=begin;
                
                 if (_isblank(heb_str[begin])) {                  if (_isblank(heb_str[begin])) {
                         heb_str[begin]='\n';                          heb_str[begin]='\n';
                 }                  }
Line 3971  PHP_FUNCTION(nl2br) Line 4275  PHP_FUNCTION(nl2br)
         int             repl_cnt = 0;          int             repl_cnt = 0;
         int             str_len;          int             str_len;
         zend_bool       is_xhtml = 1;          zend_bool       is_xhtml = 1;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &str, &str_len, &is_xhtml) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &str, &str_len, &is_xhtml) == FAILURE) {
                 return;                  return;
         }          }
        
         tmp = str;          tmp = str;
         end = str + str_len;          end = str + str_len;
        
         /* it is really faster to scan twice and allocate mem once instead of scanning once          /* it is really faster to scan twice and allocate mem once instead of scanning once
            and constantly reallocing */             and constantly reallocing */
         while (tmp < end) {          while (tmp < end) {
Line 3993  PHP_FUNCTION(nl2br) Line 4297  PHP_FUNCTION(nl2br)
                         }                          }
                         repl_cnt++;                          repl_cnt++;
                 }                  }
                
                 tmp++;                  tmp++;
         }          }
        
         if (repl_cnt == 0) {          if (repl_cnt == 0) {
                 RETURN_STRINGL(str, str_len, 1);                  RETURN_STRINGL(str, str_len, 1);
         }          }
   
        if (is_xhtml) {        {
                new_length = str_len + repl_cnt * (sizeof("<br />") - 1);                size_t repl_len = is_xhtml ? (sizeof("<br />") - 1) : (sizeof("<br>") - 1);
        } else {
                new_length = str_len + repl_cnt * (sizeof("<br>") - 1);                new_length = str_len + repl_cnt * repl_len;
                 tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1);
         }          }
   
         tmp = target = emalloc(new_length + 1);  
   
         while (str < end) {          while (str < end) {
                 switch (*str) {                  switch (*str) {
                         case '\r':                          case '\r':
Line 4023  PHP_FUNCTION(nl2br) Line 4326  PHP_FUNCTION(nl2br)
                                 }                                  }
   
                                 *target++ = '>';                                  *target++ = '>';
                                
                                 if ((*str == '\r' && *(str+1) == '\n') || (*str == '\n' && *(str+1) == '\r')) {                                  if ((*str == '\r' && *(str+1) == '\n') || (*str == '\n' && *(str+1) == '\r')) {
                                         *target++ = *str++;                                          *target++ = *str++;
                                 }                                  }
Line 4031  PHP_FUNCTION(nl2br) Line 4334  PHP_FUNCTION(nl2br)
                         default:                          default:
                                 *target++ = *str;                                  *target++ = *str;
                 }                  }
        
                 str++;                  str++;
         }          }
        
         *target = '\0';          *target = '\0';
   
         RETURN_STRINGL(tmp, new_length, 0);          RETURN_STRINGL(tmp, new_length, 0);
Line 4056  PHP_FUNCTION(strip_tags) Line 4359  PHP_FUNCTION(strip_tags)
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Z", &str, &str_len, &allow) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Z", &str, &str_len, &allow) == FAILURE) {
                 return;                  return;
         }          }
        
         /* To maintain a certain BC, we allow anything for the second parameter and return original string */          /* To maintain a certain BC, we allow anything for the second parameter and return original string */
         if (allow != NULL) {          if (allow != NULL) {
                 convert_to_string_ex(allow);                  convert_to_string_ex(allow);
Line 4085  PHP_FUNCTION(setlocale) Line 4388  PHP_FUNCTION(setlocale)
   
 #ifdef HAVE_SETLOCALE  #ifdef HAVE_SETLOCALE
         if (Z_TYPE_PP(pcategory) == IS_LONG) {          if (Z_TYPE_PP(pcategory) == IS_LONG) {
                convert_to_long_ex(pcategory);                  convert_to_long_ex(pcategory);
                 cat = Z_LVAL_PP(pcategory);                  cat = Z_LVAL_PP(pcategory);
         } else {          } else {
                 /* FIXME: The following behaviour should be removed. */                  /* FIXME: The following behaviour should be removed. */
                 char *category;                  char *category;
                
                 php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "Passing locale category name as string is deprecated. Use the LC_* -constants instead");                  php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "Passing locale category name as string is deprecated. Use the LC_* -constants instead");
                
                 convert_to_string_ex(pcategory);                  convert_to_string_ex(pcategory);
                 category = Z_STRVAL_PP(pcategory);                  category = Z_STRVAL_PP(pcategory);
   
Line 4114  PHP_FUNCTION(setlocale) Line 4417  PHP_FUNCTION(setlocale)
                         cat = LC_TIME;                          cat = LC_TIME;
                 } else {                  } else {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid locale category name %s, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, or LC_TIME", category);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid locale category name %s, must be one of LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, or LC_TIME", category);
                        
                         if (args) {                          if (args) {
                                 efree(args);                                  efree(args);
                        }                                               }
                         RETURN_FALSE;                          RETURN_FALSE;
                 }                  }
         }          }
Line 4125  PHP_FUNCTION(setlocale) Line 4428  PHP_FUNCTION(setlocale)
         if (Z_TYPE_PP(args[0]) == IS_ARRAY) {          if (Z_TYPE_PP(args[0]) == IS_ARRAY) {
                 zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args[0]));                  zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args[0]));
         }          }
        
         while (1) {          while (1) {
                 if (Z_TYPE_PP(args[0]) == IS_ARRAY) {                  if (Z_TYPE_PP(args[0]) == IS_ARRAY) {
                         if (!zend_hash_num_elements(Z_ARRVAL_PP(args[0]))) {                          if (!zend_hash_num_elements(Z_ARRVAL_PP(args[0]))) {
Line 4137  PHP_FUNCTION(setlocale) Line 4440  PHP_FUNCTION(setlocale)
                 }                  }
   
                 convert_to_string_ex(plocale);                  convert_to_string_ex(plocale);
                
                 if (!strcmp ("0", Z_STRVAL_PP(plocale))) {                  if (!strcmp ("0", Z_STRVAL_PP(plocale))) {
                         loc = NULL;                          loc = NULL;
                 } else {                  } else {
Line 4162  PHP_FUNCTION(setlocale) Line 4465  PHP_FUNCTION(setlocale)
                         }                          }
                         RETURN_STRING(retval, 1);                          RETURN_STRING(retval, 1);
                 }                  }
                
                 if (Z_TYPE_PP(args[0]) == IS_ARRAY) {                  if (Z_TYPE_PP(args[0]) == IS_ARRAY) {
                         if (zend_hash_move_forward(Z_ARRVAL_PP(args[0])) == FAILURE) break;                          if (zend_hash_move_forward(Z_ARRVAL_PP(args[0])) == FAILURE) break;
                 } else {                  } else {
Line 4203  PHP_FUNCTION(parse_str) Line 4506  PHP_FUNCTION(parse_str)
                 sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);                  sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);
         } else  {          } else  {
                 zval ret;                  zval ret;
                
                 array_init(&ret);                  array_init(&ret);
                 sapi_module.treat_data(PARSE_STRING, res, &ret TSRMLS_CC);                  sapi_module.treat_data(PARSE_STRING, res, &ret TSRMLS_CC);
                 /* Clear out the array that was passed in. */                  /* Clear out the array that was passed in. */
                 zval_dtor(arrayArg);                  zval_dtor(arrayArg);
                arrayArg->type = ret.type;                ZVAL_COPY_VALUE(arrayArg, &ret);
                arrayArg->value = ret.value; 
         }          }
 }  }
 /* }}} */  /* }}} */
Line 4218  PHP_FUNCTION(parse_str) Line 4520  PHP_FUNCTION(parse_str)
   
 /* {{{ php_tag_find  /* {{{ php_tag_find
  *   *
 * Check if tag is in a set of tags  * Check if tag is in a set of tags
  *   *
  * states:   * states:
 *  *
  * 0 start tag   * 0 start tag
  * 1 first non-whitespace char seen   * 1 first non-whitespace char seen
  */   */
Line 4233  int php_tag_find(char *tag, int len, char *set) { Line 4535  int php_tag_find(char *tag, int len, char *set) {
         if (len <= 0) {          if (len <= 0) {
                 return 0;                  return 0;
         }          }
        
         norm = emalloc(len+1);          norm = emalloc(len+1);
   
         n = norm;          n = norm;
         t = tag;          t = tag;
         c = tolower(*t);          c = tolower(*t);
        /*         /*
            normalize the tag removing leading and trailing whitespace             normalize the tag removing leading and trailing whitespace
            and turn any <a whatever...> into just <a> and any </tag>             and turn any <a whatever...> into just <a> and any </tag>
            into <tag>             into <tag>
Line 4267  int php_tag_find(char *tag, int len, char *set) { Line 4569  int php_tag_find(char *tag, int len, char *set) {
                                 break;                                  break;
                 }                  }
                 c = tolower(*(++t));                  c = tolower(*(++t));
        }          }
         *(n++) = '>';          *(n++) = '>';
        *n = '\0';         *n = '\0';
         if (strstr(set, norm)) {          if (strstr(set, norm)) {
                 done=1;                  done=1;
         } else {          } else {
Line 4287  PHPAPI size_t php_strip_tags(char *rbuf, int len, int  Line 4589  PHPAPI size_t php_strip_tags(char *rbuf, int len, int 
 /* }}} */  /* }}} */
   
 /* {{{ php_strip_tags  /* {{{ php_strip_tags
 
        A simple little state-machine to strip out html and php tags         A simple little state-machine to strip out html and php tags
        
         State 0 is the output state, State 1 means we are inside a          State 0 is the output state, State 1 means we are inside a
         normal html tag and state 2 means we are inside a php tag.          normal html tag and state 2 means we are inside a php tag.
   
Line 4311  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i Line 4613  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i
         char *tbuf, *buf, *p, *tp, *rp, c, lc;          char *tbuf, *buf, *p, *tp, *rp, c, lc;
         int br, i=0, depth=0, in_q = 0;          int br, i=0, depth=0, in_q = 0;
         int state = 0, pos;          int state = 0, pos;
           char *allow_free = NULL;
   
         if (stateptr)          if (stateptr)
                 state = *stateptr;                  state = *stateptr;
Line 4322  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i Line 4625  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i
         rp = rbuf;          rp = rbuf;
         br = 0;          br = 0;
         if (allow) {          if (allow) {
                php_strtolower(allow, allow_len);                if (IS_INTERNED(allow)) {
                         allow_free = allow = zend_str_tolower_dup(allow, allow_len);
                 } else {
                         allow_free = NULL;
                         php_strtolower(allow, allow_len);
                 }
                 tbuf = emalloc(PHP_TAG_BUF_SIZE + 1);                  tbuf = emalloc(PHP_TAG_BUF_SIZE + 1);
                 tp = tbuf;                  tp = tbuf;
         } else {          } else {
Line 4372  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i Line 4680  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i
                                 } else if (state == 0) {                                  } else if (state == 0) {
                                         *(rp++) = c;                                          *(rp++) = c;
                                 }                                  }
                                break;                                  break;
   
                         case ')':                          case ')':
                                 if (state == 2) {                                  if (state == 2) {
Line 4390  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i Line 4698  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i
                                 } else if (state == 0) {                                  } else if (state == 0) {
                                         *(rp++) = c;                                          *(rp++) = c;
                                 }                                  }
                                break;                                  break;
   
                         case '>':                          case '>':
                                 if (depth) {                                  if (depth) {
Line 4421  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i Line 4729  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i
                                                         tp = tbuf;                                                          tp = tbuf;
                                                 }                                                  }
                                                 break;                                                  break;
                                                
                                         case 2: /* PHP */                                          case 2: /* PHP */
                                                 if (!br && lc != '\"' && *(p-1) == '?') {                                                  if (!br && lc != '\"' && *(p-1) == '?') {
                                                         in_q = state = 0;                                                          in_q = state = 0;
                                                         tp = tbuf;                                                          tp = tbuf;
                                                 }                                                  }
                                                 break;                                                  break;
                                                
                                         case 3:                                          case 3:
                                                 in_q = state = 0;                                                  in_q = state = 0;
                                                 tp = tbuf;                                                  tp = tbuf;
Line 4476  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i Line 4784  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i
                                         }                                          }
                                 }                                  }
                                 break;                                  break;
                        
                        case '!':                         case '!':
                                 /* JavaScript & Other HTML scripting languages */                                  /* JavaScript & Other HTML scripting languages */
                                if (state == 1 && *(p-1) == '<') {                                 if (state == 1 && *(p-1) == '<') {
                                         state = 3;                                          state = 3;
                                         lc = c;                                          lc = c;
                                 } else {                                  } else {
Line 4506  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i Line 4814  PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, i
   
                         case '?':                          case '?':
   
                                if (state == 1 && *(p-1) == '<') {                                 if (state == 1 && *(p-1) == '<') {
                                         br=0;                                          br=0;
                                         state=2;                                          state=2;
                                         break;                                          break;
Line 4551  reg_char: Line 4859  reg_char:
                                                 tp = tbuf + pos;                                                  tp = tbuf + pos;
                                         }                                          }
                                         *(tp++) = c;                                          *(tp++) = c;
                                }                                 }
                                 break;                                  break;
                 }                  }
                 c = *(++p);                  c = *(++p);
                 i++;                  i++;
        }               }
         if (rp < rbuf + len) {          if (rp < rbuf + len) {
                 *rp = '\0';                  *rp = '\0';
         }          }
         efree(buf);          efree(buf);
        if (allow)        if (allow) {
                 efree(tbuf);                  efree(tbuf);
                   if (allow_free) {
                           efree(allow_free);
                   }
           }
         if (stateptr)          if (stateptr)
                 *stateptr = state;                  *stateptr = state;
   
Line 4578  PHP_FUNCTION(str_getcsv) Line 4890  PHP_FUNCTION(str_getcsv)
         char *delim_str = NULL, *enc_str = NULL, *esc_str = NULL;          char *delim_str = NULL, *enc_str = NULL, *esc_str = NULL;
         int str_len = 0, delim_len = 0, enc_len = 0, esc_len = 0;          int str_len = 0, delim_len = 0, enc_len = 0, esc_len = 0;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sss", &str, &str_len, &delim_str, &delim_len,         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sss", &str, &str_len, &delim_str, &delim_len,
                 &enc_str, &enc_len, &esc_str, &esc_len) == FAILURE) {                  &enc_str, &enc_len, &esc_str, &esc_len) == FAILURE) {
                 return;                  return;
         }          }
        
         delim = delim_len ? delim_str[0] : delim;          delim = delim_len ? delim_str[0] : delim;
         enc = enc_len ? enc_str[0] : enc;          enc = enc_len ? enc_str[0] : enc;
         esc = esc_len ? esc_str[0] : esc;          esc = esc_len ? esc_str[0] : esc;
Line 4600  PHP_FUNCTION(str_repeat) Line 4912  PHP_FUNCTION(str_repeat)
         long            mult;                   /* Multiplier */          long            mult;                   /* Multiplier */
         char            *result;                /* Resulting string */          char            *result;                /* Resulting string */
         size_t          result_len;             /* Length of the resulting string */          size_t          result_len;             /* Length of the resulting string */
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &input_str, &input_len, &mult) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &input_str, &input_len, &mult) == FAILURE) {
                 return;                  return;
         }          }
Line 4615  PHP_FUNCTION(str_repeat) Line 4927  PHP_FUNCTION(str_repeat)
         if (input_len == 0 || mult == 0)          if (input_len == 0 || mult == 0)
                 RETURN_EMPTY_STRING();                  RETURN_EMPTY_STRING();
   
        /* Initialize the result string */              /* Initialize the result string */
         result_len = input_len * mult;          result_len = input_len * mult;
         result = (char *)safe_emalloc(input_len, mult, 1);          result = (char *)safe_emalloc(input_len, mult, 1);
        
         /* Heavy optimization for situations where input string is 1 byte long */          /* Heavy optimization for situations where input string is 1 byte long */
         if (input_len == 1) {          if (input_len == 1) {
                memset(result, *(input_str), mult);                 memset(result, *(input_str), mult);
         } else {          } else {
                 char *s, *e, *ee;                  char *s, *e, *ee;
                 int l=0;                  int l=0;
Line 4629  PHP_FUNCTION(str_repeat) Line 4941  PHP_FUNCTION(str_repeat)
                 s = result;                  s = result;
                 e = result + input_len;                  e = result + input_len;
                 ee = result + result_len;                  ee = result + result_len;
                
                 while (e<ee) {                  while (e<ee) {
                         l = (e-s) < (ee-e) ? (e-s) : (ee-e);                          l = (e-s) < (ee-e) ? (e-s) : (ee-e);
                         memmove(e, s, l);                          memmove(e, s, l);
Line 4638  PHP_FUNCTION(str_repeat) Line 4950  PHP_FUNCTION(str_repeat)
         }          }
   
         result[result_len] = '\0';          result[result_len] = '\0';
        
         RETURN_STRINGL(result, result_len, 0);          RETURN_STRINGL(result, result_len, 0);
 }  }
 /* }}} */  /* }}} */
Line 4704  PHP_FUNCTION(count_chars) Line 5016  PHP_FUNCTION(count_chars)
                                 break;                                  break;
                 }                  }
         }          }
        
         if (mymode >= 3 && mymode <= 4) {          if (mymode >= 3 && mymode <= 4) {
                 RETURN_STRINGL(retstr, retlen, 1);                  RETURN_STRINGL(retstr, retlen, 1);
         }          }
Line 4728  static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS Line 5040  static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS
 }  }
 /* }}} */  /* }}} */
   
   PHPAPI int string_natural_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;
   
           if (Z_TYPE_P(op1) != IS_STRING) {
                   zend_make_printable_zval(op1, &op1_copy, &use_copy1);
           }
           if (Z_TYPE_P(op2) != IS_STRING) {
                   zend_make_printable_zval(op2, &op2_copy, &use_copy2);
           }
   
           if (use_copy1) {
                   op1 = &op1_copy;
           }
           if (use_copy2) {
                   op2 = &op2_copy;
           }
   
           ZVAL_LONG(result, strnatcmp_ex(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2), case_insensitive));
   
           if (use_copy1) {
                   zval_dtor(op1);
           }
           if (use_copy2) {
                   zval_dtor(op2);
           }
           return SUCCESS;
   }
   /* }}} */
   
   PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
   {
           return string_natural_compare_function_ex(result, op1, op2, 1 TSRMLS_CC);
   }
   /* }}} */
   
   PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
   {
           return string_natural_compare_function_ex(result, op1, op2, 0 TSRMLS_CC);
   }
   /* }}} */
   
 /* {{{ proto int strnatcmp(string s1, string s2)  /* {{{ proto int strnatcmp(string s1, string s2)
    Returns the result of string comparison using 'natural' algorithm */     Returns the result of string comparison using 'natural' algorithm */
 PHP_FUNCTION(strnatcmp)  PHP_FUNCTION(strnatcmp)
Line 4760  PHP_FUNCTION(localeconv) Line 5115  PHP_FUNCTION(localeconv)
                 struct lconv currlocdata;                  struct lconv currlocdata;
   
                 localeconv_r( &currlocdata );                  localeconv_r( &currlocdata );
   
                 /* Grab the grouping data out of the array */                  /* Grab the grouping data out of the array */
                 len = strlen(currlocdata.grouping);                  len = strlen(currlocdata.grouping);
   
Line 4849  PHP_FUNCTION(substr_count) Line 5204  PHP_FUNCTION(substr_count)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty substring");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty substring");
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
        
         p = haystack;          p = haystack;
         endp = p + haystack_len;          endp = p + haystack_len;
   
         if (offset < 0) {          if (offset < 0) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset should be greater than or equal to 0");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset should be greater than or equal to 0");
                RETURN_FALSE;                           RETURN_FALSE;
         }          }
   
         if (offset > haystack_len) {          if (offset > haystack_len) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset value %ld exceeds string length", offset);                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset value %ld exceeds string length", offset);
                RETURN_FALSE;                           RETURN_FALSE;
         }          }
         p += offset;          p += offset;
   
Line 4868  PHP_FUNCTION(substr_count) Line 5223  PHP_FUNCTION(substr_count)
   
                 if (length <= 0) {                  if (length <= 0) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length should be greater than 0");                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length should be greater than 0");
                        RETURN_FALSE;                                   RETURN_FALSE;
                 }                  }
                 if (length > (haystack_len - offset)) {                  if (length > (haystack_len - offset)) {
                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length value %ld exceeds string length", length);                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length value %ld exceeds string length", length);
Line 4876  PHP_FUNCTION(substr_count) Line 5231  PHP_FUNCTION(substr_count)
                 }                  }
                 endp = p + length;                  endp = p + length;
         }          }
        
         if (needle_len == 1) {          if (needle_len == 1) {
                 cmp = needle[0];                  cmp = needle[0];
   
Line 4893  PHP_FUNCTION(substr_count) Line 5248  PHP_FUNCTION(substr_count)
   
         RETURN_LONG(count);          RETURN_LONG(count);
 }  }
/* }}} */       /* }}} */
   
 /* {{{ proto string str_pad(string input, int pad_length [, string pad_string [, int pad_type]])  /* {{{ proto string str_pad(string input, int pad_length [, string pad_string [, int pad_type]])
    Returns input string padded on the left or right to specified length with pad_string */     Returns input string padded on the left or right to specified length with pad_string */
Line 4903  PHP_FUNCTION(str_pad) Line 5258  PHP_FUNCTION(str_pad)
         char *input;                            /* Input string */          char *input;                            /* Input string */
         int  input_len;          int  input_len;
         long pad_length;                        /* Length to pad to */          long pad_length;                        /* Length to pad to */
        
         /* Helper variables */          /* Helper variables */
         size_t     num_pad_chars;               /* Number of padding characters (total - input size) */          size_t     num_pad_chars;               /* Number of padding characters (total - input size) */
         char  *result = NULL;           /* Resulting string */          char  *result = NULL;           /* Resulting string */
Line 4928  PHP_FUNCTION(str_pad) Line 5283  PHP_FUNCTION(str_pad)
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding string cannot be empty");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding string cannot be empty");
                 return;                  return;
         }          }
        
         if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) {          if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding type has to be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH");
                 return;                  return;
Line 4937  PHP_FUNCTION(str_pad) Line 5292  PHP_FUNCTION(str_pad)
         num_pad_chars = pad_length - input_len;          num_pad_chars = pad_length - input_len;
         if (num_pad_chars >= INT_MAX) {          if (num_pad_chars >= INT_MAX) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding length is too long");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "Padding length is too long");
                return;                 return;
         }          }
         result = (char *)emalloc(input_len + num_pad_chars + 1);          result = (char *)emalloc(input_len + num_pad_chars + 1);
   
Line 4976  PHP_FUNCTION(str_pad) Line 5331  PHP_FUNCTION(str_pad)
         RETURN_STRINGL(result, result_len, 0);          RETURN_STRINGL(result, result_len, 0);
 }  }
 /* }}} */  /* }}} */
   
 /* {{{ proto mixed sscanf(string str, string format [, string ...])  /* {{{ proto mixed sscanf(string str, string format [, string ...])
    Implements an ANSI C compatible sscanf */     Implements an ANSI C compatible sscanf */
 PHP_FUNCTION(sscanf)  PHP_FUNCTION(sscanf)
Line 4985  PHP_FUNCTION(sscanf) Line 5340  PHP_FUNCTION(sscanf)
         char *str, *format;          char *str, *format;
         int str_len, format_len, result, num_args = 0;          int str_len, format_len, result, num_args = 0;
   
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss*", &str, &str_len, &format, &format_len,         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss*", &str, &str_len, &format, &format_len,
                 &args, &num_args) == FAILURE) {                  &args, &num_args) == FAILURE) {
                 return;                  return;
         }          }
        
         result = php_sscanf_internal(str, format, num_args, args, 0, &return_value TSRMLS_CC);          result = php_sscanf_internal(str, format, num_args, args, 0, &return_value TSRMLS_CC);
        
         if (args) {          if (args) {
                 efree(args);                  efree(args);
         }          }
Line 5029  static void php_string_shuffle(char *str, long len TSR Line 5384  static void php_string_shuffle(char *str, long len TSR
         /* The implementation is stolen from array_data_shuffle       */          /* The implementation is stolen from array_data_shuffle       */
         /* Thus the characteristics of the randomization are the same */          /* Thus the characteristics of the randomization are the same */
         n_elems = len;          n_elems = len;
        
         if (n_elems <= 1) {          if (n_elems <= 1) {
                 return;                  return;
         }          }
   
         n_left = n_elems;          n_left = n_elems;
        
         while (--n_left) {          while (--n_left) {
                 rnd_idx = php_rand(TSRMLS_C);                  rnd_idx = php_rand(TSRMLS_C);
                 RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX);                  RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX);
Line 5060  PHP_FUNCTION(str_shuffle) Line 5415  PHP_FUNCTION(str_shuffle)
         }          }
   
         RETVAL_STRINGL(arg, arglen, 1);          RETVAL_STRINGL(arg, arglen, 1);
        if (Z_STRLEN_P(return_value) > 1) {         if (Z_STRLEN_P(return_value) > 1) {
                 php_string_shuffle(Z_STRVAL_P(return_value), (long) Z_STRLEN_P(return_value) TSRMLS_CC);                  php_string_shuffle(Z_STRVAL_P(return_value), (long) Z_STRLEN_P(return_value) TSRMLS_CC);
         }          }
 }  }
Line 5072  PHP_FUNCTION(str_shuffle) Line 5427  PHP_FUNCTION(str_shuffle)
         found inside the string. If format of 2 is specified, then the function          found inside the string. If format of 2 is specified, then the function
         will return an associated array where the position of the word is the key          will return an associated array where the position of the word is the key
         and the word itself is the value.          and the word itself is the value.
        
         For the purpose of this function, 'word' is defined as a locale dependent          For the purpose of this function, 'word' is defined as a locale dependent
         string containing alphabetic characters, which also may contain, but not start          string containing alphabetic characters, which also may contain, but not start
         with "'" and "-" characters.          with "'" and "-" characters.
Line 5109  PHP_FUNCTION(str_word_count) Line 5464  PHP_FUNCTION(str_word_count)
         if (char_list) {          if (char_list) {
                 php_charmask((unsigned char *)char_list, char_list_len, ch TSRMLS_CC);                  php_charmask((unsigned char *)char_list, char_list_len, ch TSRMLS_CC);
         }          }
        
         p = str;          p = str;
         e = str + str_len;          e = str + str_len;
   
Line 5140  PHP_FUNCTION(str_word_count) Line 5495  PHP_FUNCTION(str_word_count)
                                         break;                                          break;
                                 default:                                  default:
                                         word_count++;                                          word_count++;
                                        break;                                                  break;
                         }                          }
                 }                  }
                 p++;                  p++;
         }          }
        
         if (!type) {          if (!type) {
                RETURN_LONG(word_count);                                RETURN_LONG(word_count);
         }          }
 }  }
   
Line 5171  PHP_FUNCTION(money_format) Line 5526  PHP_FUNCTION(money_format)
         e = p + format_len;          e = p + format_len;
         while ((p = memchr(p, '%', (e - p)))) {          while ((p = memchr(p, '%', (e - p)))) {
                 if (*(p + 1) == '%') {                  if (*(p + 1) == '%') {
                        p += 2;                         p += 2;
                 } else if (!check) {                  } else if (!check) {
                         check = 1;                          check = 1;
                         p++;                          p++;
Line 5203  PHP_FUNCTION(str_split) Line 5558  PHP_FUNCTION(str_split)
         long split_length = 1;          long split_length = 1;
         char *p;          char *p;
         int n_reg_segments;          int n_reg_segments;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &split_length) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &split_length) == FAILURE) {
                 return;                  return;
         }          }
Line 5240  PHP_FUNCTION(strpbrk) Line 5595  PHP_FUNCTION(strpbrk)
 {  {
         char *haystack, *char_list;          char *haystack, *char_list;
         int haystack_len, char_list_len;          int haystack_len, char_list_len;
        char *p;        char *haystack_ptr, *cl_ptr;
        
         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &haystack, &haystack_len, &char_list, &char_list_len) == FAILURE) {          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &haystack, &haystack_len, &char_list, &char_list_len) == FAILURE) {
                 RETURN_FALSE;                  RETURN_FALSE;
         }          }
   
         if (!char_list_len) {          if (!char_list_len) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The character list cannot be empty");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "The character list cannot be empty");
                RETURN_FALSE;                   RETURN_FALSE;
         }          }
   
        if ((p = strpbrk(haystack, char_list))) {        for (haystack_ptr = haystack; haystack_ptr < (haystack + haystack_len); ++haystack_ptr) {
                RETURN_STRINGL(p, (haystack + haystack_len - p), 1);                for (cl_ptr = char_list; cl_ptr < (char_list + char_list_len); ++cl_ptr) {
        } else {                        if (*cl_ptr == *haystack_ptr) {
                RETURN_FALSE;                                RETURN_STRINGL(haystack_ptr, (haystack + haystack_len - haystack_ptr), 1);
                         }
                 }
         }          }
   
           RETURN_FALSE;
 }  }
 /* }}} */  /* }}} */
   
Line 5286  PHP_FUNCTION(substr_compare) Line 5645  PHP_FUNCTION(substr_compare)
         if (offset >= s1_len) {          if (offset >= s1_len) {
                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position cannot exceed initial string length");                  php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position cannot exceed initial string length");
                 RETURN_FALSE;                  RETURN_FALSE;
         }  
   
         if (len > s1_len - offset) {  
                 len = s1_len - offset;  
         }          }
   
         cmp_len = (uint) (len ? len : MAX(s2_len, (s1_len - offset)));          cmp_len = (uint) (len ? len : MAX(s2_len, (s1_len - offset)));

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>