From a44c89e8af7c2410f4bfc5e097be2a5d0639a60c Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 12 Jun 2016 23:18:23 -0700 Subject: Fix bug #72340: Double Free Courruption in wddx_deserialize --- ext/wddx/tests/bug72340.phpt | 24 ++++++++++++++++++++++++ ext/wddx/wddx.c | 4 ++++ 2 files changed, 28 insertions(+) create mode 100644 ext/wddx/tests/bug72340.phpt diff --git a/ext/wddx/tests/bug72340.phpt b/ext/wddx/tests/bug72340.phpt new file mode 100644 index 0000000000..8d694ca52e --- /dev/null +++ b/ext/wddx/tests/bug72340.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #72340: Double Free Courruption in wddx_deserialize +--SKIPIF-- + +--FILE-- + + + + TEST + + + + +EOF; +$array = wddx_deserialize($xml); +var_dump($array); +?> +--EXPECT-- +array(0) { +} diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index da3424695b..311d6aa4a5 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -1096,6 +1096,9 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) break; case ST_BOOLEAN: + if(!ent->data) { + break; + } if (!strcmp(s, "true")) { Z_LVAL_P(ent->data) = 1; } else if (!strcmp(s, "false")) { @@ -1104,6 +1107,7 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) zval_ptr_dtor(&ent->data); if (ent->varname) { efree(ent->varname); + ent->varname = NULL; } ent->data = NULL; } -- cgit v1.2.1 From 489fd56fe37bf40a662931c2b4d5baa918f13e37 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 13 Jun 2016 23:12:47 -0700 Subject: Fix bug #72275: don't allow smart_str to overflow int --- ext/standard/php_smart_str.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ext/standard/php_smart_str.h b/ext/standard/php_smart_str.h index 1872fa8647..fc1a753dd5 100644 --- a/ext/standard/php_smart_str.h +++ b/ext/standard/php_smart_str.h @@ -63,6 +63,9 @@ newlen = (d)->len + (n); \ if (newlen >= (d)->a) { \ (d)->a = newlen + SMART_STR_PREALLOC; \ + if (UNEXPECTED((d)->a >= INT_MAX)) { \ + zend_error(E_ERROR, "String size overflow"); \ + } \ SMART_STR_DO_REALLOC(d, what); \ } \ } \ @@ -148,17 +151,17 @@ * for GCC compatible compilers, e.g. * * #define f(..) ({char *r;..;__r;}) - */ - + */ + static inline char *smart_str_print_long(char *buf, long num) { - char *r; - smart_str_print_long4(buf, num, unsigned long, r); + char *r; + smart_str_print_long4(buf, num, unsigned long, r); return r; } static inline char *smart_str_print_unsigned(char *buf, long num) { - char *r; - smart_str_print_unsigned4(buf, num, unsigned long, r); + char *r; + smart_str_print_unsigned4(buf, num, unsigned long, r); return r; } @@ -168,7 +171,7 @@ static inline char *smart_str_print_unsigned(char *buf, long num) { smart_str_print##func##4 (__b + sizeof(__b) - 1, (num), vartype, __t); \ smart_str_appendl_ex((dest), __t, __b + sizeof(__b) - 1 - __t, (type)); \ } while (0) - + #define smart_str_append_unsigned_ex(dest, num, type) \ smart_str_append_generic_ex((dest), (num), (type), unsigned long, _unsigned) -- cgit v1.2.1 From 88746d60ab3ad51797612ee62603bb3e08d4aac4 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 15 Jun 2016 21:46:46 -0700 Subject: Fix bug #72400 and #72403 - prevent signed int overflows for string lengths --- ext/standard/string.c | 25 ++++++++++++-- ext/standard/url.c | 96 +++++++++++++++++++++++++++------------------------ 2 files changed, 72 insertions(+), 49 deletions(-) diff --git a/ext/standard/string.c b/ext/standard/string.c index 63eede1c71..acb6a01087 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -137,6 +137,9 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t * register unsigned char *result = NULL; size_t i, j; + if (UNEXPECTED(oldlen * 2 * sizeof(char) > INT_MAX)) { + zend_error(E_ERROR, "String size overflow"); + } result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1); for (i = j = 0; i < oldlen; i++) { @@ -2613,6 +2616,7 @@ PHP_FUNCTION(quotemeta) char *p, *q; char c; int old_len; + size_t new_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &old, &old_len) == FAILURE) { return; @@ -2647,8 +2651,13 @@ PHP_FUNCTION(quotemeta) } } *q = 0; + new_len = q - str; + if (UNEXPECTED(new_len > INT_MAX)) { + efree(str); + zend_error(E_ERROR, "String size overflow"); + } - RETURN_STRINGL(erealloc(str, q - str + 1), q - str, 0); + RETURN_STRINGL(erealloc(str, new_len + 1), new_len, 0); } /* }}} */ @@ -3500,7 +3509,7 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s char *source, *target; char *end; char c; - int newlen; + size_t newlen; if (!wlength) { wlength = strlen(what); @@ -3531,11 +3540,15 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s } *target = 0; newlen = target - new_str; + if (UNEXPECTED(newlen > INT_MAX)) { + efree(new_str); + zend_error(E_ERROR, "String size overflow"); + } if (target - new_str < length * 4) { new_str = erealloc(new_str, newlen + 1); } if (new_length) { - *new_length = newlen; + *new_length = (int)newlen; } if (should_free) { STR_FREE((char*)str); @@ -3587,6 +3600,9 @@ PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_f *target = 0; *new_length = target - new_str; + if (UNEXPECTED(*new_length < 0)) { + zend_error(E_ERROR, "String size overflow"); + } if (should_free) { STR_FREE(str); } @@ -4290,6 +4306,9 @@ PHP_FUNCTION(nl2br) size_t repl_len = is_xhtml ? (sizeof("
") - 1) : (sizeof("
") - 1); new_length = str_len + repl_cnt * repl_len; + if (UNEXPECTED(new_length > INT_MAX)) { + zend_error(E_ERROR, "String size overflow"); + } tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1); } diff --git a/ext/standard/url.c b/ext/standard/url.c index 27a216a5e0..fc3f080a41 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -65,27 +65,27 @@ PHPAPI char *php_replace_controlchars_ex(char *str, int len) { unsigned char *s = (unsigned char *)str; unsigned char *e = (unsigned char *)str + len; - + if (!str) { return (NULL); } - + while (s < e) { - + if (iscntrl(*s)) { *s='_'; - } + } s++; } - + return (str); -} +} /* }}} */ PHPAPI char *php_replace_controlchars(char *str) { return php_replace_controlchars_ex(str, strlen(str)); -} +} PHPAPI php_url *php_url_parse(char const *str) { @@ -99,7 +99,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) char port_buf[6]; php_url *ret = ecalloc(1, sizeof(php_url)); char const *s, *e, *p, *pp, *ue; - + s = str; ue = s + length; @@ -118,40 +118,40 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) } p++; } - + if (*(e + 1) == '\0') { /* only scheme is available */ ret->scheme = estrndup(s, (e - s)); php_replace_controlchars_ex(ret->scheme, (e - s)); goto end; } - /* + /* * certain schemas like mailto: and zlib: may not have any / after them * this check ensures we support those. */ if (*(e+1) != '/') { - /* check if the data we get is a port this allows us to + /* check if the data we get is a port this allows us to * correctly parse things like a.com:80 */ p = e + 1; while (isdigit(*p)) { p++; } - + if ((*p == '\0' || *p == '/') && (p - e) < 7) { goto parse_port; } - + ret->scheme = estrndup(s, (e-s)); php_replace_controlchars_ex(ret->scheme, (e - s)); - + length -= ++e - s; s = e; goto just_path; } else { ret->scheme = estrndup(s, (e-s)); php_replace_controlchars_ex(ret->scheme, (e - s)); - + if (*(e+2) == '/') { s = e + 3; if (!strncasecmp("file", ret->scheme, sizeof("file"))) { @@ -173,9 +173,9 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) length -= ++e - s; s = e; goto just_path; - } + } } - } + } } else if (e) { /* no scheme; starts with colon: look for port */ parse_port: p = e + 1; @@ -216,9 +216,9 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) ue = s + length; goto nohost; } - + e = ue; - + if (!(p = memchr(s, '/', (ue - s)))) { char *query, *fragment; @@ -238,14 +238,14 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) } } else { e = p; - } - + } + /* check for login and password */ if ((p = zend_memrchr(s, '@', (e-s)))) { if ((pp = memchr(s, ':', (p-s)))) { ret->user = estrndup(s, (pp-s)); php_replace_controlchars_ex(ret->user, (pp - s)); - + pp++; ret->pass = estrndup(pp, (p-pp)); php_replace_controlchars_ex(ret->pass, (p-pp)); @@ -253,14 +253,14 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) ret->user = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->user, (p-s)); } - + s = p + 1; } /* check for port */ if (*s == '[' && *(e-1) == ']') { - /* Short circuit portscan, - we're dealing with an + /* Short circuit portscan, + we're dealing with an IPv6 embedded address */ p = s; } else { @@ -294,11 +294,11 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) } } p--; - } + } } else { p = e; } - + /* check if we have a valid host, if we don't reject the string as url */ if ((p-s) < 1) { STR_FREE(ret->scheme); @@ -310,15 +310,15 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) ret->host = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->host, (p - s)); - + if (e == ue) { return ret; } - + s = e; - + nohost: - + if ((p = memchr(s, '?', (ue - s)))) { pp = strchr(s, '#'); @@ -330,14 +330,14 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) p = pp; goto label_parse; } - + if (p - s) { ret->path = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->path, (p - s)); - } - + } + if (pp) { - if (pp - ++p) { + if (pp - ++p) { ret->query = estrndup(p, (pp-p)); php_replace_controlchars_ex(ret->query, (pp - p)); } @@ -351,15 +351,15 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length) if (p - s) { ret->path = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->path, (p - s)); - } - + } + label_parse: p++; - + if (ue - p) { ret->fragment = estrndup(p, (ue-p)); php_replace_controlchars_ex(ret->fragment, (ue - p)); - } + } } else { ret->path = estrndup(s, (ue-s)); php_replace_controlchars_ex(ret->path, (ue - s)); @@ -441,7 +441,7 @@ PHP_FUNCTION(parse_url) add_assoc_string(return_value, "query", resource->query, 1); if (resource->fragment != NULL) add_assoc_string(return_value, "fragment", resource->fragment, 1); -done: +done: php_url_free(resource); } /* }}} */ @@ -489,7 +489,7 @@ PHPAPI char *php_url_encode(char const *s, int len, int *new_length) register unsigned char c; unsigned char *to, *start; unsigned char const *from, *end; - + from = (unsigned char *)s; end = (unsigned char *)s + len; start = to = (unsigned char *) safe_emalloc(3, len, 1); @@ -575,7 +575,7 @@ PHPAPI int php_url_decode(char *str, int len) if (*data == '+') { *dest = ' '; } - else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) + else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) { #ifndef CHARSET_EBCDIC *dest = (char) php_htoi(data + 1); @@ -625,6 +625,10 @@ PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length) if (new_length) { *new_length = y; } + if (UNEXPECTED(y > INT_MAX)) { + efree(str); + zend_error(E_ERROR, "String size overflow"); + } return ((char *) str); } /* }}} */ @@ -673,7 +677,7 @@ PHPAPI int php_raw_url_decode(char *str, int len) char *data = str; while (len--) { - if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) + if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) { #ifndef CHARSET_EBCDIC *dest = (char) php_htoi(data + 1); @@ -705,7 +709,7 @@ PHP_FUNCTION(get_headers) HashPosition pos; HashTable *hashT; long format = 0; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &url, &url_len, &format) == FAILURE) { return; } @@ -724,12 +728,12 @@ PHP_FUNCTION(get_headers) /* check for curl-wrappers that provide headers via a special "headers" element */ if (zend_hash_find(HASH_OF(stream->wrapperdata), "headers", sizeof("headers"), (void **)&h) != FAILURE && Z_TYPE_PP(h) == IS_ARRAY) { - /* curl-wrappers don't load data until the 1st read */ + /* curl-wrappers don't load data until the 1st read */ if (!Z_ARRVAL_PP(h)->nNumOfElements) { php_stream_getc(stream); } zend_hash_find(HASH_OF(stream->wrapperdata), "headers", sizeof("headers"), (void **)&h); - hashT = Z_ARRVAL_PP(h); + hashT = Z_ARRVAL_PP(h); } else { hashT = HASH_OF(stream->wrapperdata); } -- cgit v1.2.1 From 7245bff300d3fa8bacbef7897ff080a6f1c23eba Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 15 Jun 2016 21:58:26 -0700 Subject: Fix bug #72262 - do not overflow int --- ext/spl/spl_directory.c | 218 ++++++++++++++++++++++++------------------------ 1 file changed, 111 insertions(+), 107 deletions(-) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index e20a80ae77..7718fe42d7 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -79,9 +79,9 @@ static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */ if (intern->oth_handler && intern->oth_handler->dtor) { intern->oth_handler->dtor(intern TSRMLS_CC); } - + zend_object_std_dtor(&intern->std TSRMLS_CC); - + if (intern->_path) { efree(intern->_path); } @@ -98,7 +98,7 @@ static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */ } if (intern->u.dir.sub_path) { efree(intern->u.dir.sub_path); - } + } break; case SPL_FS_FILE: if (intern->u.file.stream) { @@ -134,13 +134,13 @@ static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */ } /* }}} */ /* {{{ spl_ce_dir_object_new */ -/* creates the object by - - allocating memory +/* creates the object by + - allocating memory - initializing the object members - storing the object - setting it's handlers - called from + called from - clone - new */ @@ -313,7 +313,7 @@ static int spl_filesystem_file_open(spl_filesystem_object *intern, int use_inclu /* avoid reference counting in debug mode, thus do it manually */ ZVAL_RESOURCE(&intern->u.file.zresource, php_stream_get_resource_id(intern->u.file.stream)); Z_SET_REFCOUNT(intern->u.file.zresource, 1); - + intern->u.file.delimiter = ','; intern->u.file.enclosure = '"'; intern->u.file.escape = '\\'; @@ -325,7 +325,7 @@ static int spl_filesystem_file_open(spl_filesystem_object *intern, int use_inclu /* {{{ spl_filesystem_object_clone */ /* Local zend_object_value creation (on stack) - Load the 'other' object + Load the 'other' object Create a new empty object (See spl_filesystem_object_new_ex) Open the directory Clone other members (properties) @@ -370,7 +370,7 @@ static zend_object_value spl_filesystem_object_clone(zval *zobject TSRMLS_DC) php_error_docref(NULL TSRMLS_CC, E_ERROR, "An object of class %s cannot be cloned", old_object->ce->name); break; } - + intern->file_class = source->file_class; intern->info_class = source->info_class; intern->oth = source->oth; @@ -389,7 +389,7 @@ static zend_object_value spl_filesystem_object_clone(zval *zobject TSRMLS_DC) void spl_filesystem_info_set_filename(spl_filesystem_object *intern, char *path, int len, int use_copy TSRMLS_DC) /* {{{ */ { char *p1, *p2; - + if (intern->file_name) { efree(intern->file_name); } @@ -413,7 +413,7 @@ void spl_filesystem_info_set_filename(spl_filesystem_object *intern, char *path, } else { intern->_path_len = 0; } - + if (intern->_path) { efree(intern->_path); } @@ -459,7 +459,7 @@ static spl_filesystem_object * spl_filesystem_object_create_info(spl_filesystem_ } else { spl_filesystem_info_set_filename(intern, file_path, file_path_len, use_copy TSRMLS_CC); } - + zend_restore_error_handling(&error_handling TSRMLS_CC); return intern; } /* }}} */ @@ -514,7 +514,7 @@ static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_fil return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC); Z_TYPE_P(return_value) = IS_OBJECT; - + spl_filesystem_object_get_file_name(source TSRMLS_CC); if (ce->constructor->common.scope != spl_ce_SplFileObject) { @@ -530,12 +530,12 @@ static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_fil intern->file_name_len = source->file_name_len; intern->_path = spl_filesystem_object_get_path(source, &intern->_path_len TSRMLS_CC); intern->_path = estrndup(intern->_path, intern->_path_len); - + intern->u.file.open_mode = "r"; intern->u.file.open_mode_len = 1; - - if (ht && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbr", - &intern->u.file.open_mode, &intern->u.file.open_mode_len, + + if (ht && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbr", + &intern->u.file.open_mode, &intern->u.file.open_mode_len, &use_include_path, &intern->u.file.zcontext) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); intern->u.file.open_mode = NULL; @@ -544,7 +544,7 @@ static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_fil Z_TYPE_P(return_value) = IS_NULL; return NULL; } - + if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); zval_dtor(return_value); @@ -553,7 +553,7 @@ static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_fil } } break; - case SPL_FS_DIR: + case SPL_FS_DIR: zend_restore_error_handling(&error_handling TSRMLS_CC); zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Operation not supported"); return NULL; @@ -617,7 +617,7 @@ static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp T if (intern->file_name) { pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "fileName", sizeof("fileName")-1, &pnlen TSRMLS_CC); spl_filesystem_object_get_path(intern, &path_len TSRMLS_CC); - + if (path_len && path_len < intern->file_name_len) { add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->file_name + path_len + 1, intern->file_name_len - (path_len + 1), 1); } else { @@ -665,13 +665,13 @@ static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp T zend_function *spl_filesystem_object_get_method_check(zval **object_ptr, char *method, int method_len, const struct _zend_literal *key TSRMLS_DC) /* {{{ */ { spl_filesystem_object *fsobj = zend_object_store_get_object(*object_ptr TSRMLS_CC); - + if (fsobj->u.dir.entry.d_name[0] == '\0' && fsobj->orig_path == NULL) { method = "_bad_state_ex"; method_len = sizeof("_bad_state_ex") - 1; key = NULL; } - + return zend_get_std_object_handlers()->get_method(object_ptr, method, method_len, key TSRMLS_CC); } /* }}} */ @@ -751,7 +751,7 @@ SPL_METHOD(DirectoryIterator, __construct) SPL_METHOD(DirectoryIterator, rewind) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -769,7 +769,7 @@ SPL_METHOD(DirectoryIterator, rewind) SPL_METHOD(DirectoryIterator, key) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -799,7 +799,7 @@ SPL_METHOD(DirectoryIterator, next) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); int skip_dots = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_SKIPDOTS); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -859,7 +859,7 @@ SPL_METHOD(DirectoryIterator, seek) SPL_METHOD(DirectoryIterator, valid) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -875,7 +875,7 @@ SPL_METHOD(SplFileInfo, getPath) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); char *path; int path_len; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -891,13 +891,13 @@ SPL_METHOD(SplFileInfo, getFilename) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); int path_len; - + if (zend_parse_parameters_none() == FAILURE) { return; } spl_filesystem_object_get_path(intern, &path_len TSRMLS_CC); - + if (path_len && path_len < intern->file_name_len) { RETURN_STRINGL(intern->file_name + path_len + 1, intern->file_name_len - (path_len + 1), 1); } else { @@ -911,7 +911,7 @@ SPL_METHOD(SplFileInfo, getFilename) SPL_METHOD(DirectoryIterator, getFilename) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1019,7 +1019,7 @@ SPL_METHOD(SplFileInfo, getBasename) RETURN_STRINGL(fname, flen, 0); } -/* }}}*/ +/* }}}*/ /* {{{ proto string DirectoryIterator::getBasename([string $suffix]) U Returns filename component of current dir entry */ @@ -1029,7 +1029,7 @@ SPL_METHOD(DirectoryIterator, getBasename) char *suffix = 0, *fname; int slen = 0; size_t flen; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) { return; } @@ -1065,7 +1065,7 @@ SPL_METHOD(SplFileInfo, getPathname) SPL_METHOD(FilesystemIterator, key) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1084,7 +1084,7 @@ SPL_METHOD(FilesystemIterator, key) SPL_METHOD(FilesystemIterator, current) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1107,7 +1107,7 @@ SPL_METHOD(FilesystemIterator, current) SPL_METHOD(DirectoryIterator, isDot) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1121,8 +1121,8 @@ SPL_METHOD(DirectoryIterator, isDot) /* zend_replace_error_handling() is used to throw exceptions in case the constructor fails. Here we use this to ensure the object has a valid directory resource. - - When the constructor gets called the object is already created + + When the constructor gets called the object is already created by the engine, so we must only call 'additional' initializations. */ SPL_METHOD(SplFileInfo, __construct) @@ -1140,11 +1140,11 @@ SPL_METHOD(SplFileInfo, __construct) } intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + spl_filesystem_info_set_filename(intern, path, len, 1 TSRMLS_CC); zend_restore_error_handling(&error_handling TSRMLS_CC); - + /* intern->type = SPL_FS_INFO; already set */ } /* }}} */ @@ -1249,7 +1249,7 @@ SPL_METHOD(SplFileInfo, getLinkTarget) int ret; char buff[MAXPATHLEN]; zend_error_handling error_handling; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1297,7 +1297,7 @@ SPL_METHOD(SplFileInfo, getRealPath) char buff[MAXPATHLEN]; char *filename; zend_error_handling error_handling; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1307,10 +1307,10 @@ SPL_METHOD(SplFileInfo, getRealPath) if (intern->type == SPL_FS_DIR && !intern->file_name && intern->u.dir.entry.d_name[0]) { spl_filesystem_object_get_file_name(intern TSRMLS_CC); } - + if (intern->orig_path) { filename = intern->orig_path; - } else { + } else { filename = intern->file_name; } @@ -1348,7 +1348,7 @@ SPL_METHOD(SplFileInfo, setFileClass) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = spl_ce_SplFileObject; zend_error_handling error_handling; - + zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { @@ -1366,7 +1366,7 @@ SPL_METHOD(SplFileInfo, setInfoClass) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = spl_ce_SplFileInfo; zend_error_handling error_handling; - + zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { @@ -1384,7 +1384,7 @@ SPL_METHOD(SplFileInfo, getFileInfo) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = intern->info_class; zend_error_handling error_handling; - + zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { @@ -1402,7 +1402,7 @@ SPL_METHOD(SplFileInfo, getPathInfo) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = intern->info_class; zend_error_handling error_handling; - + zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { @@ -1463,7 +1463,7 @@ SPL_METHOD(FilesystemIterator, rewind) SPL_METHOD(FilesystemIterator, getFlags) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1519,11 +1519,11 @@ SPL_METHOD(RecursiveDirectoryIterator, getChildren) spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); spl_filesystem_object *subdir; char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH; - + if (zend_parse_parameters_none() == FAILURE) { return; } - + spl_filesystem_object_get_file_name(intern TSRMLS_CC); MAKE_STD_ZVAL(zflags); @@ -1554,7 +1554,7 @@ SPL_METHOD(RecursiveDirectoryIterator, getChildren) SPL_METHOD(RecursiveDirectoryIterator, getSubPath) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1575,7 +1575,7 @@ SPL_METHOD(RecursiveDirectoryIterator, getSubPathname) char *sub_name; int len; char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1611,7 +1611,7 @@ SPL_METHOD(GlobIterator, __construct) SPL_METHOD(GlobIterator, count) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1666,7 +1666,7 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval iterator->current = object; } zval_add_ref(&object); - + return (zend_object_iterator*)iterator; } /* }}} */ @@ -1701,7 +1701,7 @@ static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC) static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) { spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter; - + *data = &iterator->current; } /* }}} */ @@ -1719,7 +1719,7 @@ static void spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zval * static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC) { spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter); - + object->u.dir.index++; spl_filesystem_dir_read(object TSRMLS_CC); if (object->file_name) { @@ -1733,7 +1733,7 @@ static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC) { spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter); - + object->u.dir.index = 0; if (object->u.dir.dirp) { php_stream_rewinddir(object->u.dir.dirp); @@ -1803,7 +1803,7 @@ static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRML { spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter; spl_filesystem_object *object = spl_filesystem_iterator_to_object(iterator); - + object->u.dir.index++; do { spl_filesystem_dir_read(object TSRMLS_CC); @@ -1824,7 +1824,7 @@ static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC) { spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter; spl_filesystem_object *object = spl_filesystem_iterator_to_object(iterator); - + object->u.dir.index = 0; if (object->u.dir.dirp) { php_stream_rewinddir(object->u.dir.dirp); @@ -1868,7 +1868,7 @@ zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zva iterator->intern.funcs = &spl_filesystem_tree_it_funcs; } zval_add_ref(&object); - + return (zend_object_iterator*)iterator; } /* }}} */ @@ -1924,7 +1924,7 @@ static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type TS /* {{{ declare method parameters */ /* supply a name and default to call by parameter */ -ZEND_BEGIN_ARG_INFO(arginfo_info___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_info___construct, 0) ZEND_ARG_INFO(0, file_name) ZEND_END_ARG_INFO() @@ -1983,11 +1983,11 @@ static const zend_function_entry spl_SplFileInfo_functions[] = { PHP_FE_END }; -ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) ZEND_ARG_INFO(0, path) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_dir_it_seek, 0) +ZEND_BEGIN_ARG_INFO(arginfo_dir_it_seek, 0) ZEND_ARG_INFO(0, position) ZEND_END_ARG_INFO(); @@ -2009,7 +2009,7 @@ static const zend_function_entry spl_DirectoryIterator_functions[] = { PHP_FE_END }; -ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir___construct, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir___construct, 0, 0, 1) ZEND_ARG_INFO(0, path) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() @@ -2058,7 +2058,7 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TS long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0; spl_filesystem_file_free_line(intern TSRMLS_CC); - + if (php_stream_eof(intern->u.file.stream)) { if (!silent) { zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name); @@ -2086,7 +2086,7 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TS line_len = strcspn(buf, "\r\n"); buf[line_len] = '\0'; } - + intern->u.file.current_line = buf; intern->u.file.current_line_len = line_len; } @@ -2107,7 +2107,7 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function zval ***params = (zval***)safe_emalloc(num_args, sizeof(zval**), 0); params[0] = &zresource_ptr; - + if (arg2) { params[1] = &arg2; } @@ -2133,7 +2133,7 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function fcic.object_ptr = NULL; result = zend_call_function(&fci, &fcic TSRMLS_CC); - + if (result == FAILURE) { RETVAL_FALSE; } else { @@ -2159,11 +2159,11 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, char escape, zval *return_value TSRMLS_DC) /* {{{ */ { int ret = SUCCESS; - + do { ret = spl_filesystem_file_read(intern, 1 TSRMLS_CC); } while (ret == SUCCESS && !intern->u.file.current_line_len && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_SKIP_EMPTY)); - + if (ret == SUCCESS) { size_t buf_len = intern->u.file.current_line_len; char *buf = estrndup(intern->u.file.current_line, buf_len); @@ -2237,7 +2237,7 @@ static int spl_filesystem_file_is_empty_line(spl_filesystem_object *intern TSRML if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) && zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 1) { zval ** first = Z_ARRVAL_P(intern->u.file.current_zval)->pListHead->pData; - + return Z_TYPE_PP(first) == IS_STRING && Z_STRLEN_PP(first) == 0; } return zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 0; @@ -2260,7 +2260,7 @@ static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object spl_filesystem_file_free_line(intern TSRMLS_CC); ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC); } - + return ret; } /* }}} */ @@ -2294,16 +2294,16 @@ SPL_METHOD(SplFileObject, __construct) intern->u.file.open_mode = NULL; intern->u.file.open_mode_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sbr!", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sbr!", &intern->file_name, &intern->file_name_len, - &intern->u.file.open_mode, &intern->u.file.open_mode_len, - &use_include_path, &intern->u.file.zcontext) == FAILURE) { + &intern->u.file.open_mode, &intern->u.file.open_mode_len, + &use_include_path, &intern->u.file.zcontext) == FAILURE) { intern->u.file.open_mode = NULL; intern->file_name = NULL; zend_restore_error_handling(&error_handling TSRMLS_CC); return; } - + if (intern->u.file.open_mode == NULL) { intern->u.file.open_mode = "r"; intern->u.file.open_mode_len = 1; @@ -2368,7 +2368,7 @@ SPL_METHOD(SplTempFileObject, __construct) intern->u.file.open_mode = "wb"; intern->u.file.open_mode_len = 1; intern->u.file.zcontext = NULL; - + if (spl_filesystem_file_open(intern, 0, 0 TSRMLS_CC) == SUCCESS) { intern->_path_len = 0; intern->_path = estrndup("", 0); @@ -2381,7 +2381,7 @@ SPL_METHOD(SplTempFileObject, __construct) SPL_METHOD(SplFileObject, rewind) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2394,7 +2394,7 @@ SPL_METHOD(SplFileObject, rewind) SPL_METHOD(SplFileObject, eof) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2407,7 +2407,7 @@ SPL_METHOD(SplFileObject, eof) SPL_METHOD(SplFileObject, valid) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2424,7 +2424,7 @@ SPL_METHOD(SplFileObject, valid) SPL_METHOD(SplFileObject, fgets) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2440,7 +2440,7 @@ SPL_METHOD(SplFileObject, fgets) SPL_METHOD(SplFileObject, current) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2461,7 +2461,7 @@ SPL_METHOD(SplFileObject, current) SPL_METHOD(SplFileObject, key) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2478,7 +2478,7 @@ SPL_METHOD(SplFileObject, key) SPL_METHOD(SplFileObject, next) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2530,7 +2530,7 @@ SPL_METHOD(SplFileObject, setMaxLineLen) zend_throw_exception_ex(spl_ce_DomainException, 0 TSRMLS_CC, "Maximum line length must be greater than or equal zero"); return; } - + intern->u.file.max_line_len = max_len; } /* }}} */ @@ -2539,7 +2539,7 @@ SPL_METHOD(SplFileObject, setMaxLineLen) SPL_METHOD(SplFileObject, getMaxLineLen) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2554,7 +2554,7 @@ SPL_METHOD(SplFileObject, hasChildren) if (zend_parse_parameters_none() == FAILURE) { return; } - + RETURN_FALSE; } /* }}} */ @@ -2585,7 +2585,7 @@ SPL_METHOD(SplFileObject, fgetcsv) char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure, escape = intern->u.file.escape; char *delim = NULL, *enclo = NULL, *esc = NULL; int d_len = 0, e_len = 0, esc_len = 0; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { switch(ZEND_NUM_ARGS()) { @@ -2627,7 +2627,7 @@ SPL_METHOD(SplFileObject, fputcsv) char *delim = NULL, *enclo = NULL, *esc = NULL; int d_len = 0, e_len = 0, esc_len = 0, ret; zval *fields = NULL; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|sss", &fields, &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { switch(ZEND_NUM_ARGS()) { @@ -2670,7 +2670,7 @@ SPL_METHOD(SplFileObject, setCsvControl) char delimiter = ',', enclosure = '"', escape='\\'; char *delim = NULL, *enclo = NULL, *esc = NULL; int d_len = 0, e_len = 0, esc_len = 0; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { switch(ZEND_NUM_ARGS()) { @@ -2713,7 +2713,7 @@ SPL_METHOD(SplFileObject, getCsvControl) char delimiter[2], enclosure[2]; array_init(return_value); - + delimiter[0] = intern->u.file.delimiter; delimiter[1] = '\0'; enclosure[0] = intern->u.file.enclosure; @@ -2742,7 +2742,7 @@ SPL_METHOD(SplFileObject, fflush) Return current file position */ SPL_METHOD(SplFileObject, ftell) { - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long ret = php_stream_tell(intern->u.file.stream); if (ret == -1) { @@ -2872,6 +2872,10 @@ SPL_METHOD(SplFileObject, fread) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0"); RETURN_FALSE; } + if (length > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be no more than %d", INT_MAX); + RETURN_FALSE; + } Z_STRVAL_P(return_value) = emalloc(length + 1); Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length); @@ -2892,7 +2896,7 @@ SPL_METHOD(SplFileObject, ftruncate) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long size; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) { return; } @@ -2901,7 +2905,7 @@ SPL_METHOD(SplFileObject, ftruncate) zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name); RETURN_FALSE; } - + RETURN_BOOL(0 == php_stream_truncate_set_size(intern->u.file.stream, size)); } /* }}} */ @@ -2911,17 +2915,17 @@ SPL_METHOD(SplFileObject, seek) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long line_pos; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) { return; } if (line_pos < 0) { zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't seek file %s to negative line %ld", intern->file_name, line_pos); - RETURN_FALSE; + RETURN_FALSE; } - + spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC); - + while(intern->u.file.current_line_num < line_pos) { if (spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC) == FAILURE) { break; @@ -2958,25 +2962,25 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fputcsv, 0, 0, 1) ZEND_ARG_INFO(0, escape) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_flock, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_flock, 0, 0, 1) ZEND_ARG_INFO(0, operation) ZEND_ARG_INFO(1, wouldblock) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fseek, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fseek, 0, 0, 1) ZEND_ARG_INFO(0, pos) ZEND_ARG_INFO(0, whence) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0) ZEND_ARG_INFO(0, allowable_tags) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 1, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 1, 0, 1) ZEND_ARG_INFO(0, format) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1) ZEND_ARG_INFO(0, str) ZEND_ARG_INFO(0, length) ZEND_END_ARG_INFO() @@ -2985,11 +2989,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fread, 0, 0, 1) ZEND_ARG_INFO(0, length) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_ftruncate, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_ftruncate, 0, 0, 1) ZEND_ARG_INFO(0, size) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_seek, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_seek, 0, 0, 1) ZEND_ARG_INFO(0, line_pos) ZEND_END_ARG_INFO() @@ -3078,7 +3082,7 @@ PHP_MINIT_FUNCTION(spl_directory) REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, FilesystemIterator, spl_filesystem_object_new, spl_RecursiveDirectoryIterator_functions); REGISTER_SPL_IMPLEMENTS(RecursiveDirectoryIterator, RecursiveIterator); - + memcpy(&spl_filesystem_object_check_handlers, &spl_filesystem_object_handlers, sizeof(zend_object_handlers)); spl_filesystem_object_check_handlers.get_method = spl_filesystem_object_get_method_check; @@ -3095,7 +3099,7 @@ PHP_MINIT_FUNCTION(spl_directory) REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_AHEAD", SPL_FILE_OBJECT_READ_AHEAD); REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "SKIP_EMPTY", SPL_FILE_OBJECT_SKIP_EMPTY); REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_CSV", SPL_FILE_OBJECT_READ_CSV); - + REGISTER_SPL_SUB_CLASS_EX(SplTempFileObject, SplFileObject, spl_filesystem_object_new_check, spl_SplTempFileObject_functions); return SUCCESS; } -- cgit v1.2.1 From 7722455726bec8c53458a32851d2a87982cf0eac Mon Sep 17 00:00:00 2001 From: Pierre Joye Date: Sat, 18 Jun 2016 20:15:10 +0200 Subject: Fixed #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow --- ext/gd/libgd/gd_gd2.c | 7 +++++++ ext/gd/tests/bug72339.gd | Bin 0 -> 67108882 bytes ext/gd/tests/bug72339.phpt | 11 +++++++++++ 3 files changed, 18 insertions(+) create mode 100644 ext/gd/tests/bug72339.gd create mode 100644 ext/gd/tests/bug72339.phpt diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c index 6726fee826..63e3aefc3f 100644 --- a/ext/gd/libgd/gd_gd2.c +++ b/ext/gd/libgd/gd_gd2.c @@ -138,11 +138,18 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in if (gd2_compressed(*fmt)) { nc = (*ncx) * (*ncy); GD2_DBG(php_gd_error("Reading %d chunk index entries", nc)); + if (overflow2(sidx, nc)) { + goto fail1; + } sidx = sizeof(t_chunk_info) * nc; if (sidx <= 0) { goto fail1; } cidx = gdCalloc(sidx, 1); + if (cidx == NULL) { + goto fail1; + } + for (i = 0; i < nc; i++) { if (gdGetInt(&cidx[i].offset, in) != 1) { gdFree(cidx); diff --git a/ext/gd/tests/bug72339.gd b/ext/gd/tests/bug72339.gd new file mode 100644 index 0000000000..0634c99005 Binary files /dev/null and b/ext/gd/tests/bug72339.gd differ diff --git a/ext/gd/tests/bug72339.phpt b/ext/gd/tests/bug72339.phpt new file mode 100644 index 0000000000..763ae71000 --- /dev/null +++ b/ext/gd/tests/bug72339.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecreatefromgd2(): gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully + in %sbug72339.php on line %d + +Warning: imagecreatefromgd2(): '%sbug72339.gd' is not a valid GD2 file in %sbug72339.php on line %d -- cgit v1.2.1 From e9ac8954be9f7d988189df44578d759ffdea3512 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 18 Jun 2016 21:04:33 -0700 Subject: Fix bug #72298 pass2_no_dither out-of-bounds access --- ext/gd/libgd/gd_topal.c | 14 +++++++------- ext/gd/tests/bug72298.phpt | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 ext/gd/tests/bug72298.phpt diff --git a/ext/gd/libgd/gd_topal.c b/ext/gd/libgd/gd_topal.c index b9cb928648..d8dda45cb9 100644 --- a/ext/gd/libgd/gd_topal.c +++ b/ext/gd/libgd/gd_topal.c @@ -43,7 +43,7 @@ * If it is not working, it's not Thomas G. Lane's fault. */ -/* +/* SETTING THIS ONE CAUSES STRIPED IMAGE to be done: solve this #define ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS @@ -152,7 +152,7 @@ * color space, and repeatedly splits the "largest" remaining box until we * have as many boxes as desired colors. Then the mean color in each * remaining box becomes one of the possible output colors. - * + * * The second pass over the image maps each input pixel to the closest output * color (optionally after applying a Floyd-Steinberg dithering correction). * This mapping is logically trivial, but making it go fast enough requires @@ -1320,16 +1320,16 @@ pass2_no_dither (j_decompress_ptr cinfo, #else r = gdTrueColorGetRed (*inptr); g = gdTrueColorGetGreen (*inptr); - /* + /* 2.0.24: inptr must not be incremented until after - transparency check, if any. Thanks to "Super Pikeman." + transparency check, if any. Thanks to "Super Pikeman." */ b = gdTrueColorGetBlue (*inptr); /* If the pixel is transparent, we assign it the palette index that * will later be added at the end of the palette as the transparent * index. */ - if ((oim->transparent >= 0) && (oim->transparent == *(inptr - 1))) + if ((oim->transparent >= 0) && (oim->transparent == *inptr)) { *outptr++ = nim->colorsTotal; inptr++; @@ -1795,7 +1795,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color } } else { nim = oim; - } + } if (!oim->trueColor) { /* (Almost) nothing to do! */ @@ -2004,7 +2004,7 @@ static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int color } /* Success! Get rid of the truecolor image data. */ - if (!cimP) { + if (!cimP) { oim->trueColor = 0; /* Junk the truecolor pixels */ for (i = 0; i < oim->sy; i++) diff --git a/ext/gd/tests/bug72298.phpt b/ext/gd/tests/bug72298.phpt new file mode 100644 index 0000000000..7fba241ed1 --- /dev/null +++ b/ext/gd/tests/bug72298.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #72298: pass2_no_dither out-of-bounds access +--SKIPIF-- + +--FILE-- + +DONE +--EXPECT-- +DONE \ No newline at end of file -- cgit v1.2.1 From 5b597a2e5b28e2d5a52fc1be13f425f08f47cb62 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 18 Jun 2016 21:48:39 -0700 Subject: Fix bug #72402: _php_mb_regex_ereg_replace_exec - double free --- ext/mbstring/php_mbregex.c | 65 ++++++++++++++++++++-------------------- ext/mbstring/tests/bug72402.phpt | 17 +++++++++++ 2 files changed, 49 insertions(+), 33 deletions(-) create mode 100644 ext/mbstring/tests/bug72402.phpt diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index d73c848350..6cdee23c3e 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -32,7 +32,7 @@ #include "ext/standard/info.h" #include "php_mbregex.h" #include "mbstring.h" - + #include "php_onig_compat.h" /* must come prior to the oniguruma header */ #include #undef UChar @@ -55,7 +55,7 @@ struct _zend_mb_regex_globals { #define MBREX(g) (MBSTRG(mb_regex_globals)->g) /* {{{ static void php_mb_regex_free_cache() */ -static void php_mb_regex_free_cache(php_mb_regex_t **pre) +static void php_mb_regex_free_cache(php_mb_regex_t **pre) { onig_free(*pre); } @@ -78,7 +78,7 @@ static int _php_mb_regex_globals_ctor(zend_mb_regex_globals *pglobals TSRMLS_DC) /* }}} */ /* {{{ _php_mb_regex_globals_dtor */ -static void _php_mb_regex_globals_dtor(zend_mb_regex_globals *pglobals TSRMLS_DC) +static void _php_mb_regex_globals_dtor(zend_mb_regex_globals *pglobals TSRMLS_DC) { zend_hash_destroy(&pglobals->ht_rc); } @@ -466,7 +466,7 @@ static php_mb_regex_t *php_mbregex_compile_pattern(const char *pattern, int patl retval = *rc; } out: - return retval; + return retval; } /* }}} */ @@ -483,7 +483,7 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT --len_left; *(p++) = 'i'; } - ++len_req; + ++len_req; } if ((option & ONIG_OPTION_EXTEND) != 0) { @@ -491,7 +491,7 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT --len_left; *(p++) = 'x'; } - ++len_req; + ++len_req; } if ((option & (ONIG_OPTION_MULTILINE | ONIG_OPTION_SINGLELINE)) == @@ -500,14 +500,14 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT --len_left; *(p++) = 'p'; } - ++len_req; + ++len_req; } else { if ((option & ONIG_OPTION_MULTILINE) != 0) { if (len_left > 0) { --len_left; *(p++) = 'm'; } - ++len_req; + ++len_req; } if ((option & ONIG_OPTION_SINGLELINE) != 0) { @@ -515,22 +515,22 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT --len_left; *(p++) = 's'; } - ++len_req; + ++len_req; } - } + } if ((option & ONIG_OPTION_FIND_LONGEST) != 0) { if (len_left > 0) { --len_left; *(p++) = 'l'; } - ++len_req; + ++len_req; } if ((option & ONIG_OPTION_FIND_NOT_EMPTY) != 0) { if (len_left > 0) { --len_left; *(p++) = 'n'; } - ++len_req; + ++len_req; } c = 0; @@ -566,7 +566,7 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT --len_left; *(p++) = '\0'; } - ++len_req; + ++len_req; if (len < len_req) { return len_req; } @@ -577,11 +577,11 @@ static size_t _php_mb_regex_get_option_string(char *str, size_t len, OnigOptionT /* {{{ _php_mb_regex_init_options */ static void -_php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, OnigSyntaxType **syntax, int *eval) +_php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, OnigSyntaxType **syntax, int *eval) { int n; char c; - int optm = 0; + int optm = 0; *syntax = ONIG_SYNTAX_RUBY; @@ -636,13 +636,13 @@ _php_mb_regex_init_options(const char *parg, int narg, OnigOptionType *option, O *syntax = ONIG_SYNTAX_POSIX_EXTENDED; break; case 'e': - if (eval != NULL) *eval = 1; + if (eval != NULL) *eval = 1; break; default: break; } } - if (option != NULL) *option|=optm; + if (option != NULL) *option|=optm; } } /* }}} */ @@ -860,11 +860,11 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp } else { /* FIXME: this code is not multibyte aware! */ convert_to_long_ex(arg_pattern_zval); - pat_buf[0] = (char)Z_LVAL_PP(arg_pattern_zval); + pat_buf[0] = (char)Z_LVAL_PP(arg_pattern_zval); pat_buf[1] = '\0'; arg_pattern = pat_buf; - arg_pattern_len = 1; + arg_pattern_len = 1; } /* create regex pattern buffer */ re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, options, MBREX(current_mbctype), syntax TSRMLS_CC); @@ -934,7 +934,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp } } } - + if (eval) { zval v; /* null terminate buffer */ @@ -953,32 +953,31 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp eval_buf.len = 0; zval_dtor(&v); } else if (is_callable) { - zval *retval_ptr; + zval *retval_ptr = NULL; zval **args[1]; zval *subpats; int i; - + MAKE_STD_ZVAL(subpats); array_init(subpats); - + for (i = 0; i < regs->num_regs; i++) { add_next_index_stringl(subpats, string + regs->beg[i], regs->end[i] - regs->beg[i], 1); - } - + } + args[0] = &subpats; /* null terminate buffer */ smart_str_0(&eval_buf); - + arg_replace_fci.param_count = 1; arg_replace_fci.params = args; arg_replace_fci.retval_ptr_ptr = &retval_ptr; - if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr) { + if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr && retval_ptr) { convert_to_string_ex(&retval_ptr); smart_str_appendl(&out_buf, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr)); eval_buf.len = 0; zval_ptr_dtor(&retval_ptr); } else { - efree(description); if (!EG(exception)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function"); } @@ -991,7 +990,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp pos = (OnigUChar *)string + n; } else { if (pos < string_lim) { - smart_str_appendl(&out_buf, pos, 1); + smart_str_appendl(&out_buf, pos, 1); } pos++; } @@ -1013,7 +1012,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp smart_str_free(&eval_buf); if (err <= -2) { - smart_str_free(&out_buf); + smart_str_free(&out_buf); RETVAL_FALSE; } else { smart_str_appendc(&out_buf, '\0'); @@ -1063,7 +1062,7 @@ PHP_FUNCTION(mb_split) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &arg_pattern, &arg_pattern_len, &string, &string_len, &count) == FAILURE) { RETURN_FALSE; - } + } if (count > 0) { count--; @@ -1317,7 +1316,7 @@ PHP_FUNCTION(mb_ereg_search_init) if (zend_parse_parameters(argc TSRMLS_CC, "z|ss", &arg_str, &arg_pattern, &arg_pattern_len, &arg_options, &arg_options_len) == FAILURE) { return; } - + if (argc > 1 && arg_pattern_len == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty pattern"); RETURN_FALSE; @@ -1416,7 +1415,7 @@ PHP_FUNCTION(mb_ereg_search_setpos) /* }}} */ /* {{{ php_mb_regex_set_options */ -static void _php_mb_regex_set_options(OnigOptionType options, OnigSyntaxType *syntax, OnigOptionType *prev_options, OnigSyntaxType **prev_syntax TSRMLS_DC) +static void _php_mb_regex_set_options(OnigOptionType options, OnigSyntaxType *syntax, OnigOptionType *prev_options, OnigSyntaxType **prev_syntax TSRMLS_DC) { if (prev_options != NULL) { *prev_options = MBREX(regex_default_options); diff --git a/ext/mbstring/tests/bug72402.phpt b/ext/mbstring/tests/bug72402.phpt new file mode 100644 index 0000000000..abb290bf4d --- /dev/null +++ b/ext/mbstring/tests/bug72402.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #72402: _php_mb_regex_ereg_replace_exec - double free +--SKIPIF-- + +--FILE-- + +DONE +--EXPECT-- +DONE \ No newline at end of file -- cgit v1.2.1 From b9ec171e7d25879d97473ca50197c4207420c276 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 18 Jun 2016 21:57:25 -0700 Subject: Fix bug #72407: NULL Pointer Dereference at _gdScaleVert --- ext/gd/libgd/gd_interpolation.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index 0961c08048..4fa23f0a14 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -1049,6 +1049,9 @@ static inline void _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_w } contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation); + if (contrib == NULL) { + return; + } /* scale each column */ for (u = 0; u < dst_width - 1; u++) { _gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib); -- cgit v1.2.1 From 3f627e580acfdaf0595ae3b115b8bec677f203ee Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jun 2016 21:26:33 -0700 Subject: Fixed ##72433: Use After Free Vulnerability in PHP's GC algorithm and unserialize --- Zend/tests/gc_024.phpt | 2 +- ext/spl/spl_array.c | 11 +++++++++++ ext/standard/tests/strings/bug72433.phpt | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/strings/bug72433.phpt diff --git a/Zend/tests/gc_024.phpt b/Zend/tests/gc_024.phpt index 9a2ceb88f5..ca78da63d3 100644 --- a/Zend/tests/gc_024.phpt +++ b/Zend/tests/gc_024.phpt @@ -13,5 +13,5 @@ var_dump(gc_collect_cycles()); echo "ok\n"; ?> --EXPECT-- -int(1) +int(2) ok diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index c89cf4994b..4e03c408c6 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -831,6 +831,16 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* } /* }}} */ +static HashTable *spl_array_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */ +{ + spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); + + *gc_data = &intern->array; + *gc_data_count = 1; + return zend_std_get_properties(object); +} +/* }}} */ + static zval *spl_array_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); @@ -1961,6 +1971,7 @@ PHP_MINIT_FUNCTION(spl_array) spl_handler_ArrayObject.get_properties = spl_array_get_properties; spl_handler_ArrayObject.get_debug_info = spl_array_get_debug_info; + spl_handler_ArrayObject.get_gc = spl_array_get_gc; spl_handler_ArrayObject.read_property = spl_array_read_property; spl_handler_ArrayObject.write_property = spl_array_write_property; spl_handler_ArrayObject.get_property_ptr_ptr = spl_array_get_property_ptr_ptr; diff --git a/ext/standard/tests/strings/bug72433.phpt b/ext/standard/tests/strings/bug72433.phpt new file mode 100644 index 0000000000..3a2c89701b --- /dev/null +++ b/ext/standard/tests/strings/bug72433.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #72433: Use After Free Vulnerability in PHP's GC algorithm and unserialize +--FILE-- + +--EXPECTF-- +array(3) { + [0]=> + *RECURSION* + [1]=> + *RECURSION* + [2]=> + object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + *RECURSION* + } +} -- cgit v1.2.1 From f6aef68089221c5ea047d4a74224ee3deead99a6 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jun 2016 21:35:22 -0700 Subject: Fix bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize --- ext/standard/tests/strings/bug72434.phpt | 33 ++++++++++++++++++++++++++++++++ ext/zip/php_zip.c | 9 +++++++++ 2 files changed, 42 insertions(+) create mode 100644 ext/standard/tests/strings/bug72434.phpt diff --git a/ext/standard/tests/strings/bug72434.phpt b/ext/standard/tests/strings/bug72434.phpt new file mode 100644 index 0000000000..1408b8f578 --- /dev/null +++ b/ext/standard/tests/strings/bug72434.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize +--SKIPIF-- + +--FILE-- + rc is 0 +$a = $unserialized_payload[1]; +// Increment the reference counter by 1 again -> rc is 1 +$b = $a; +// Trigger free of $free_me (referenced by $m[1]). +unset($b); +$fill_freed_space_1 = "filler_zval_1"; +$fill_freed_space_2 = "filler_zval_2"; +$fill_freed_space_3 = "filler_zval_3"; +$fill_freed_space_4 = "filler_zval_4"; +debug_zval_dump($unserialized_payload[1]); +?> +--EXPECTF-- +array(1) refcount(1){ + [0]=> + object(stdClass)#%d (0) refcount(3){ + } +} diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 99c293c6d7..57d060f4ff 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -1015,6 +1015,14 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend } /* }}} */ +static HashTable *php_zip_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */ +{ + *gc_data = NULL; + *gc_data_count = 0; + return zend_std_get_properties(object TSRMLS_CC); +} +/* }}} */ + static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */ { ze_zip_object *obj; @@ -2777,6 +2785,7 @@ static PHP_MINIT_FUNCTION(zip) zip_object_handlers.clone_obj = NULL; zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr; + zip_object_handlers.get_gc = php_zip_get_gc; zip_object_handlers.get_properties = php_zip_get_properties; zip_object_handlers.read_property = php_zip_read_property; zip_object_handlers.has_property = php_zip_has_property; -- cgit v1.2.1 From 6c5211a0cef0cc2854eaa387e0eb036e012904d0 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jun 2016 21:51:42 -0700 Subject: Fix bug #72455: Heap Overflow due to integer overflows --- ext/mcrypt/mcrypt.c | 92 +++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/ext/mcrypt/mcrypt.c b/ext/mcrypt/mcrypt.c index 194660d864..3cbb913414 100644 --- a/ext/mcrypt/mcrypt.c +++ b/ext/mcrypt/mcrypt.c @@ -44,7 +44,7 @@ static int le_mcrypt; -typedef struct _php_mcrypt { +typedef struct _php_mcrypt { MCRYPT td; zend_bool init; } php_mcrypt; @@ -292,7 +292,7 @@ ZEND_DECLARE_MODULE_GLOBALS(mcrypt) zend_module_entry mcrypt_module_entry = { STANDARD_MODULE_HEADER, - "mcrypt", + "mcrypt", mcrypt_functions, PHP_MINIT(mcrypt), PHP_MSHUTDOWN(mcrypt), NULL, NULL, @@ -376,7 +376,7 @@ ZEND_GET_MODULE(mcrypt) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mcryptind) == FAILURE) { \ return; \ } \ - ZEND_FETCH_RESOURCE (pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt); + ZEND_FETCH_RESOURCE (pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt); #define MCRYPT_GET_MODE_DIR_ARGS(DIRECTORY) \ char *dir = NULL; \ @@ -407,7 +407,7 @@ PHP_INI_END() static void php_mcrypt_module_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ { php_mcrypt *pm = (php_mcrypt *) rsrc->ptr; - if (pm) { + if (pm) { mcrypt_generic_deinit(pm->td); mcrypt_module_close(pm->td); efree(pm); @@ -548,7 +548,7 @@ PHP_MINFO_FUNCTION(mcrypt) /* {{{ */ smart_str_free(&tmp1); smart_str_free(&tmp2); php_info_print_table_end(); - + DISPLAY_INI_ENTRIES(); } /* }}} */ @@ -563,17 +563,17 @@ PHP_FUNCTION(mcrypt_module_open) int mode_len, mode_dir_len; MCRYPT td; php_mcrypt *pm; - + if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "ssss", &cipher, &cipher_len, &cipher_dir, &cipher_dir_len, &mode, &mode_len, &mode_dir, &mode_dir_len)) { return; } - + td = mcrypt_module_open ( cipher, cipher_dir_len > 0 ? cipher_dir : MCG(algorithms_dir), - mode, + mode, mode_dir_len > 0 ? mode_dir : MCG(modes_dir) ); @@ -600,7 +600,7 @@ PHP_FUNCTION(mcrypt_generic_init) int max_key_size, key_size, iv_size; php_mcrypt *pm; int result = 0; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &mcryptind, &key, &key_len, &iv, &iv_len) == FAILURE) { return; } @@ -679,7 +679,7 @@ PHP_FUNCTION(mcrypt_generic) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt); PHP_MCRYPT_INIT_CHECK @@ -692,6 +692,10 @@ PHP_FUNCTION(mcrypt_generic) if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */ block_size = mcrypt_enc_get_block_size(pm->td); data_size = (((data_len - 1) / block_size) + 1) * block_size; + if (data_size <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Integer overflow in data size"); + RETURN_FALSE; + } data_s = emalloc(data_size + 1); memset(data_s, 0, data_size); memcpy(data_s, data, data_len); @@ -701,7 +705,7 @@ PHP_FUNCTION(mcrypt_generic) memset(data_s, 0, data_size); memcpy(data_s, data, data_len); } - + mcrypt_generic(pm->td, data_s, data_size); data_s[data_size] = '\0'; @@ -720,11 +724,11 @@ PHP_FUNCTION(mdecrypt_generic) php_mcrypt *pm; char* data_s; int block_size, data_size; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pm, php_mcrypt * , &mcryptind, -1, "MCrypt", le_mcrypt); PHP_MCRYPT_INIT_CHECK @@ -737,6 +741,10 @@ PHP_FUNCTION(mdecrypt_generic) if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */ block_size = mcrypt_enc_get_block_size(pm->td); data_size = (((data_len - 1) / block_size) + 1) * block_size; + if (data_size <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Integer overflow in data size"); + RETURN_FALSE; + } data_s = emalloc(data_size + 1); memset(data_s, 0, data_size); memcpy(data_s, data, data_len); @@ -746,7 +754,7 @@ PHP_FUNCTION(mdecrypt_generic) memset(data_s, 0, data_size); memcpy(data_s, data, data_len); } - + mdecrypt_generic(pm->td, data_s, data_size); RETVAL_STRINGL(data_s, data_size, 1); @@ -760,7 +768,7 @@ PHP_FUNCTION(mcrypt_enc_get_supported_key_sizes) { int i, count = 0; int *key_sizes; - + MCRYPT_GET_TD_ARG array_init(return_value); @@ -829,7 +837,7 @@ PHP_FUNCTION(mcrypt_enc_is_block_algorithm) MCRYPT_GET_TD_ARG if (mcrypt_enc_is_block_algorithm(pm->td) == 1) { - RETURN_TRUE + RETURN_TRUE } else { RETURN_FALSE } @@ -908,7 +916,7 @@ PHP_FUNCTION(mcrypt_enc_get_modes_name) PHP_FUNCTION(mcrypt_module_self_test) { MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir); - + if (mcrypt_module_self_test(module, dir) == 0) { RETURN_TRUE; } else { @@ -922,7 +930,7 @@ PHP_FUNCTION(mcrypt_module_self_test) PHP_FUNCTION(mcrypt_module_is_block_algorithm_mode) { MCRYPT_GET_MODE_DIR_ARGS(modes_dir) - + if (mcrypt_module_is_block_algorithm_mode(module, dir) == 1) { RETURN_TRUE; } else { @@ -936,7 +944,7 @@ PHP_FUNCTION(mcrypt_module_is_block_algorithm_mode) PHP_FUNCTION(mcrypt_module_is_block_algorithm) { MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir) - + if (mcrypt_module_is_block_algorithm(module, dir) == 1) { RETURN_TRUE; } else { @@ -950,7 +958,7 @@ PHP_FUNCTION(mcrypt_module_is_block_algorithm) PHP_FUNCTION(mcrypt_module_is_block_mode) { MCRYPT_GET_MODE_DIR_ARGS(modes_dir) - + if (mcrypt_module_is_block_mode(module, dir) == 1) { RETURN_TRUE; } else { @@ -964,7 +972,7 @@ PHP_FUNCTION(mcrypt_module_is_block_mode) PHP_FUNCTION(mcrypt_module_get_algo_block_size) { MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir) - + RETURN_LONG(mcrypt_module_get_algo_block_size(module, dir)); } /* }}} */ @@ -974,7 +982,7 @@ PHP_FUNCTION(mcrypt_module_get_algo_block_size) PHP_FUNCTION(mcrypt_module_get_algo_key_size) { MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir); - + RETURN_LONG(mcrypt_module_get_algo_key_size(module, dir)); } /* }}} */ @@ -985,7 +993,7 @@ PHP_FUNCTION(mcrypt_module_get_supported_key_sizes) { int i, count = 0; int *key_sizes; - + MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir) array_init(return_value); @@ -1011,7 +1019,7 @@ PHP_FUNCTION(mcrypt_list_algorithms) &lib_dir, &lib_dir_len) == FAILURE) { return; } - + array_init(return_value); modules = mcrypt_list_algorithms(lib_dir, &count); @@ -1058,7 +1066,7 @@ PHP_FUNCTION(mcrypt_get_key_size) { char *cipher; char *module; - int cipher_len, module_len; + int cipher_len, module_len; char *cipher_dir_string; char *module_dir_string; MCRYPT td; @@ -1069,7 +1077,7 @@ PHP_FUNCTION(mcrypt_get_key_size) &cipher, &cipher_len, &module, &module_len) == FAILURE) { return; } - + td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string); if (td != MCRYPT_FAILED) { RETVAL_LONG(mcrypt_enc_get_key_size(td)); @@ -1087,7 +1095,7 @@ PHP_FUNCTION(mcrypt_get_block_size) { char *cipher; char *module; - int cipher_len, module_len; + int cipher_len, module_len; char *cipher_dir_string; char *module_dir_string; MCRYPT td; @@ -1098,7 +1106,7 @@ PHP_FUNCTION(mcrypt_get_block_size) &cipher, &cipher_len, &module, &module_len) == FAILURE) { return; } - + td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string); if (td != MCRYPT_FAILED) { RETVAL_LONG(mcrypt_enc_get_block_size(td)); @@ -1116,7 +1124,7 @@ PHP_FUNCTION(mcrypt_get_iv_size) { char *cipher; char *module; - int cipher_len, module_len; + int cipher_len, module_len; char *cipher_dir_string; char *module_dir_string; MCRYPT td; @@ -1127,7 +1135,7 @@ PHP_FUNCTION(mcrypt_get_iv_size) &cipher, &cipher_len, &module, &module_len) == FAILURE) { return; } - + td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string); if (td != MCRYPT_FAILED) { RETVAL_LONG(mcrypt_enc_get_iv_size(td)); @@ -1217,7 +1225,7 @@ static void php_mcrypt_do_crypt(char* cipher, const char *key, int key_len, cons } else { /* dertermine smallest supported key > length of requested key */ use_key_length = max_key_length; /* start with max key length */ for (i = 0; i < count; i++) { - if (key_length_sizes[i] >= key_len && + if (key_length_sizes[i] >= key_len && key_length_sizes[i] < use_key_length) { use_key_length = key_length_sizes[i]; @@ -1228,11 +1236,11 @@ static void php_mcrypt_do_crypt(char* cipher, const char *key, int key_len, cons memcpy(key_s, key, MIN(key_len, use_key_length)); } mcrypt_free (key_length_sizes); - + /* Check IV */ iv_s = NULL; iv_size = mcrypt_enc_get_iv_size (td); - + /* IV is required */ if (mcrypt_enc_mode_has_iv(td) == 1) { if (argc == 5) { @@ -1272,7 +1280,7 @@ static void php_mcrypt_do_crypt(char* cipher, const char *key, int key_len, cons } else { mdecrypt_generic(td, data_s, data_size); } - + RETVAL_STRINGL(data_s, data_size, 1); /* freeing vars */ @@ -1294,9 +1302,9 @@ PHP_FUNCTION(mcrypt_encrypt) zval **mode; char *cipher, *key, *data, *iv = NULL; int cipher_len, key_len, data_len, iv_len = 0; - + MCRYPT_GET_CRYPT_ARGS - + convert_to_string_ex(mode); php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, Z_STRVAL_PP(mode), iv, iv_len, ZEND_NUM_ARGS(), MCRYPT_ENCRYPT, return_value TSRMLS_CC); @@ -1312,7 +1320,7 @@ PHP_FUNCTION(mcrypt_decrypt) int cipher_len, key_len, data_len, iv_len = 0; MCRYPT_GET_CRYPT_ARGS - + convert_to_string_ex(mode); php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, Z_STRVAL_PP(mode), iv, iv_len, ZEND_NUM_ARGS(), MCRYPT_DECRYPT, return_value TSRMLS_CC); @@ -1326,7 +1334,7 @@ PHP_FUNCTION(mcrypt_ecb) zval **mode; char *cipher, *key, *data, *iv = NULL; int cipher_len, key_len, data_len, iv_len = 0; - + MCRYPT_GET_CRYPT_ARGS convert_to_long_ex(mode); @@ -1358,7 +1366,7 @@ PHP_FUNCTION(mcrypt_cfb) zval **mode; char *cipher, *key, *data, *iv = NULL; int cipher_len, key_len, data_len, iv_len = 0; - + MCRYPT_GET_CRYPT_ARGS convert_to_long_ex(mode); @@ -1374,7 +1382,7 @@ PHP_FUNCTION(mcrypt_ofb) zval **mode; char *cipher, *key, *data, *iv = NULL; int cipher_len, key_len, data_len, iv_len = 0; - + MCRYPT_GET_CRYPT_ARGS convert_to_long_ex(mode); @@ -1400,9 +1408,9 @@ PHP_FUNCTION(mcrypt_create_iv) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create an IV with a size of less than 1 or greater than %d", INT_MAX); RETURN_FALSE; } - + iv = ecalloc(size + 1, 1); - + if (source == RANDOM || source == URANDOM) { #if PHP_WIN32 /* random/urandom equivalent on Windows */ -- cgit v1.2.1 From 7f428cae88f1294052087e6729f1ecb924b8a18d Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jun 2016 22:13:31 -0700 Subject: fix build --- ext/spl/spl_array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 4e03c408c6..5cb7d34c6f 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -837,7 +837,7 @@ static HashTable *spl_array_get_gc(zval *object, zval ***gc_data, int *gc_data_c *gc_data = &intern->array; *gc_data_count = 1; - return zend_std_get_properties(object); + return zend_std_get_properties(object TSRMLS_CC); } /* }}} */ -- cgit v1.2.1 From 5f107ab8a66f8b36ac0c0b32e0231bf94e083c94 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 20 Jun 2016 22:54:55 -0700 Subject: fix tests --- ext/gd/libgd/gd_gd2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c index 63e3aefc3f..e954aafa68 100644 --- a/ext/gd/libgd/gd_gd2.c +++ b/ext/gd/libgd/gd_gd2.c @@ -138,7 +138,7 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in if (gd2_compressed(*fmt)) { nc = (*ncx) * (*ncy); GD2_DBG(php_gd_error("Reading %d chunk index entries", nc)); - if (overflow2(sidx, nc)) { + if (overflow2(sizeof(t_chunk_info), nc)) { goto fail1; } sidx = sizeof(t_chunk_info) * nc; -- cgit v1.2.1