]> granicus.if.org Git - php/commitdiff
MF5: Fix chunk_split fix - avoid using floats
authorStanislav Malyshev <stas@php.net>
Wed, 6 Jun 2007 20:06:43 +0000 (20:06 +0000)
committerStanislav Malyshev <stas@php.net>
Wed, 6 Jun 2007 20:06:43 +0000 (20:06 +0000)
MF5: Fix money_format - don't give strfmon more arguments then supplied
MF5: Fix str[c]spn integer overflow

ext/standard/string.c

index d4d35000c641bfee9eb8ce4eb00c4aba078ced98..155bbf6c69458366a6effac8dff34cf5f7958b74 100644 (file)
@@ -249,10 +249,14 @@ static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) /
                }
        }
 
-       if (((unsigned) start + (unsigned) len) > len1) {
+       if (len > len1 - start) {
                len = len1 - start;
        }
 
+       if(len == 0) {
+               RETURN_LONG(0);
+       }
+
        if (type1 == IS_UNICODE) {
                UChar *u_start, *u_end;
                int32_t i = 0;
@@ -3083,7 +3087,7 @@ static char* php_chunk_split(char *src, int srclen, char *end, int endlen, int c
        int chunks; /* complete chunks! */
        int restlen;
        int charsize = sizeof(char);
-       float out_len;
+       int out_len;
 
        if (str_type == IS_UNICODE) {
                charsize = sizeof(UChar);
@@ -3092,15 +3096,24 @@ static char* php_chunk_split(char *src, int srclen, char *end, int endlen, int c
        chunks = srclen / chunklen;
        restlen = srclen - chunks * chunklen; /* srclen % chunklen */
 
+       if(chunks > INT_MAX - 1) {
+               return NULL;
+       }
        out_len = chunks + 1;
+       if(endlen !=0 && out_len > INT_MAX/endlen) {
+               return NULL;
+       }
        out_len *= endlen;
+       if(out_len > INT_MAX - srclen - 1) {
+               return NULL;
+       }
        out_len += srclen + 1;
 
-       if ((out_len > INT_MAX || out_len <= 0) || ((out_len * charsize) > INT_MAX || (out_len * charsize) <= 0)) {
+       if (out_len > INT_MAX/charsize) {
                return NULL;
        }
 
-       dest = safe_emalloc((int)out_len, charsize, 0);
+       dest = safe_emalloc(out_len, charsize, 0);
 
        for (p = src, q = dest; p < (src + charsize * (srclen - chunklen + 1)); ) {
                memcpy(q, p, chunklen * charsize);
@@ -7654,13 +7667,28 @@ PHP_FUNCTION(str_word_count)
 PHP_FUNCTION(money_format)
 {
        int format_len = 0, str_len;
-       char *format, *str;
+       char *format, *str, *p, *e;
        double value;
+       zend_bool check = 0;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sd", &format, &format_len, &value) == FAILURE) {
                return;
        }
 
+       p = format;
+       e = p + format_len;
+       while ((p = memchr(p, '%', (e - p)))) {
+               if (*(p + 1) == '%') {
+                       p += 2; 
+               } else if (!check) {
+                       check = 1;
+                       p++;
+               } else {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only a single %%i or %%n token can be used");
+                       RETURN_FALSE;
+               }
+       }
+
        str_len = format_len + 1024;
        str = emalloc(str_len);
        if ((str_len = strfmon(str, str_len, format, value)) < 0) {