summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2007-06-06 18:38:47 +0000
committerStanislav Malyshev <stas@php.net>2007-06-06 18:38:47 +0000
commit25df29e22332eced1fe666c00800c4f37918d105 (patch)
tree2803ae805fd2705c50e00e1eac31ec70d9b1fc52
parent58feae40d81a71c8e7d986cc3e5e41b814b59578 (diff)
downloadphp-git-25df29e22332eced1fe666c00800c4f37918d105.tar.gz
Fix chunk_split fix - avoid using floats
Fix money_format - don't give strfmon more arguments then supplied Fix str[c]spn integer overflow
-rw-r--r--ext/standard/string.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/ext/standard/string.c b/ext/standard/string.c
index b7b36afba8..66773a9520 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -234,10 +234,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);
+ }
+
s = s22;
e = s22 + len2;
while (s < e) {
@@ -1511,20 +1515,25 @@ static PHP_ATTRIBUTE_MALLOC char *php_chunk_split(char *src, int srclen, char *e
char *p, *q;
int chunks; /* complete chunks! */
int restlen;
- float out_len;
+ int out_len;
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;
- out_len += srclen + 1;
-
- if (out_len > INT_MAX || out_len <= 0) {
+ if(out_len > INT_MAX - srclen - 1) {
return NULL;
}
+ out_len += srclen + 1;
- dest = safe_emalloc((int)out_len, sizeof(char), 0);
+ dest = safe_emalloc(out_len, sizeof(char), 0);
for (p = src, q = dest; p < (src + srclen - chunklen + 1); ) {
memcpy(q, p, chunklen);
@@ -4097,14 +4106,29 @@ 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) {