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

version 1.1.1.1, 2012/02/21 23:48:02 version 1.1.1.5, 2014/06/15 20:03:57
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | PHP Version 5                                                        |     | PHP Version 5                                                        |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1997-2012 The PHP Group                                |   | Copyright (c) 1997-2014 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 1368  PHPAPI void php_basename(char *s, size_t len, char *su Line 1441  PHPAPI void php_basename(char *s, size_t len, char *su
                                                 state = 0;                                                  state = 0;
                                                 cend = c;                                                  cend = c;
                                         }                                          }
   #if defined(PHP_WIN32) || defined(NETWARE)
                                   /* Catch relative paths in c:file.txt style. They're not to confuse
                                      with the NTFS streams. This part ensures also, that no drive 
                                      letter traversing happens. */
                                   } else if ((*c == ':' && (c - comp == 1))) {
                                           if (state == 0) {
                                                   comp = c;
                                                   state = 1;
                                           } else {
                                                   cend = c;
                                                   state = 0;
                                           }
   #endif
                                 } else {                                  } else {
                                         if (state == 0) {                                          if (state == 0) {
                                                 comp = c;                                                  comp = c;
Line 1446  PHP_FUNCTION(dirname) Line 1532  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 1555  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 1568  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 1589  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 1718  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 1728  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 1751  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 1771  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 1818  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 1830  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 1902  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 2026  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 2104  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 2140  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 2186  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 2195  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 2211  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 2237  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 2251  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 2314  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 2348  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 2419  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 2444  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 2455  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 2508  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 2540  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 2560  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 2584  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 2606  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 2647  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 2680  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 2694  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 2745  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 2791  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 3200  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 3218  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 3246  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 3266  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 3293  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 3309  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 3336  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 3393  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 3403  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 3415  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 3431  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 3444  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 3495  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 3522  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 3540  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 3556  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 3570  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 3580  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 3597  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 3640  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 3659  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 3713  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 3885  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 3902  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 3927  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 3942  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 3956  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 3972  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 4059  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 4101  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 4125  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 4195  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 4211  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 4220  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 4288  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 4310  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 4339  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 4347  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 4372  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 4401  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 4430  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 4441  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 4453  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 4478  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 4519  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 4533  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 4548  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 4582  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 4602  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 4626  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 4638  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 4693  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 4711  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 4742  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 4797  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 4827  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 4872  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 4903  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 4925  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 4940  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 4954  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 4963  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 5029  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 5053  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 5128  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 5217  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 5236  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 5244  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 5261  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 5271  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 5296  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 5305  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 5344  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 5353  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 5397  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 5428  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 5440  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 5477  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 5508  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 5539  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 5571  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 5608  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 5658  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.5


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