From: Anatol Belski Date: Wed, 27 Apr 2016 09:45:29 +0000 (+0200) Subject: Merge branch 'PHP-5.6' into PHP-7.0 X-Git-Tag: php-7.0.7RC1~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=33d41da3474729486d6bbb7fb13e1b697356481e;p=php Merge branch 'PHP-5.6' into PHP-7.0 * PHP-5.6: Fix memory leak Fix bug #72099: xml_parse_into_struct segmentation fault 5.5.36 now Fix bug #72094 - Out of bounds heap read access in exif header processing Fix bug #72093: bcpowmod accepts negative scale and corrupts _one_ definition Fix bug #72061 - Out-of-bounds reads in zif_grapheme_stripos with negative offset Fix for bug #71912 (libgd: signedness vulnerability) Typo in NEWS --- 33d41da3474729486d6bbb7fb13e1b697356481e diff --cc ext/bcmath/bcmath.c index fd14050f05,ea2c38e418..7100367faa --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@@ -296,17 -311,18 +313,18 @@@ PHP_FUNCTION(bcmul } if (argc == 3) { - scale = (int) ((int)scale_param < 0) ? 0 : scale_param; + scale = (int) ((int)scale_param < 0 ? 0 : scale_param); } - bc_init_num(&first TSRMLS_CC); - bc_init_num(&second TSRMLS_CC); - bc_init_num(&result TSRMLS_CC); - php_str2num(&first, left TSRMLS_CC); - php_str2num(&second, right TSRMLS_CC); - bc_multiply (first, second, &result, scale TSRMLS_CC); + bc_init_num(&first); + bc_init_num(&second); + bc_init_num(&result); + php_str2num(&first, left); + php_str2num(&second, right); + bc_multiply (first, second, &result, scale); if (result->n_scale > scale) { + result = split_bc_num(result); result->n_scale = scale; } @@@ -333,24 -351,27 +351,25 @@@ PHP_FUNCTION(bcdiv } if (argc == 3) { - scale = (int) ((int)scale_param < 0) ? 0 : scale_param; + scale = (int) ((int)scale_param < 0 ? 0 : scale_param); } - bc_init_num(&first TSRMLS_CC); - bc_init_num(&second TSRMLS_CC); - bc_init_num(&result TSRMLS_CC); - php_str2num(&first, left TSRMLS_CC); - php_str2num(&second, right TSRMLS_CC); + bc_init_num(&first); + bc_init_num(&second); + bc_init_num(&result); + php_str2num(&first, left); + php_str2num(&second, right); - switch (bc_divide(first, second, &result, scale TSRMLS_CC)) { + switch (bc_divide(first, second, &result, scale)) { case 0: /* OK */ if (result->n_scale > scale) { + result = split_bc_num(result); result->n_scale = scale; } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + RETVAL_STR(bc_num2str(result)); break; case -1: /* division by zero */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero"); + php_error_docref(NULL, E_WARNING, "Division by zero"); break; } @@@ -451,17 -477,18 +470,18 @@@ PHP_FUNCTION(bcpow } if (argc == 3) { - scale = (int) ((int)scale_param < 0) ? 0 : scale_param; + scale = (int) ((int)scale_param < 0 ? 0 : scale_param); } - bc_init_num(&first TSRMLS_CC); - bc_init_num(&second TSRMLS_CC); - bc_init_num(&result TSRMLS_CC); - php_str2num(&first, left TSRMLS_CC); - php_str2num(&second, right TSRMLS_CC); - bc_raise (first, second, &result, scale TSRMLS_CC); + bc_init_num(&first); + bc_init_num(&second); + bc_init_num(&result); + php_str2num(&first, left); + php_str2num(&second, right); + bc_raise (first, second, &result, scale); if (result->n_scale > scale) { + result = split_bc_num(result); result->n_scale = scale; } @@@ -488,19 -517,22 +508,20 @@@ PHP_FUNCTION(bcsqrt } if (argc == 2) { - scale = (int) ((int)scale_param < 0) ? 0 : scale_param; + scale = (int) ((int)scale_param < 0 ? 0 : scale_param); } - bc_init_num(&result TSRMLS_CC); - php_str2num(&result, left TSRMLS_CC); + bc_init_num(&result); + php_str2num(&result, left); - if (bc_sqrt (&result, scale TSRMLS_CC) != 0) { + if (bc_sqrt (&result, scale) != 0) { if (result->n_scale > scale) { + result = split_bc_num(result); result->n_scale = scale; } - Z_STRVAL_P(return_value) = bc_num2str(result); - Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); - Z_TYPE_P(return_value) = IS_STRING; + RETVAL_STR(bc_num2str(result)); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Square root of negative number"); + php_error_docref(NULL, E_WARNING, "Square root of negative number"); } bc_free_num(&result); diff --cc ext/intl/grapheme/grapheme_string.c index f42ba7e69e,3ba9b51524..5687e3e260 --- a/ext/intl/grapheme/grapheme_string.c +++ b/ext/intl/grapheme/grapheme_string.c @@@ -106,16 -108,18 +106,16 @@@ PHP_FUNCTION(grapheme_strlen Find position of first occurrence of a string within another */ PHP_FUNCTION(grapheme_strpos) { - unsigned char *haystack, *needle; - int haystack_len, needle_len; - unsigned char *found; - long loffset = 0; + char *haystack, *needle; + size_t haystack_len, needle_len; + const char *found; + zend_long loffset = 0; - int32_t offset = 0; + int32_t offset = 0, noffset = 0; - int ret_pos; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", (char **)&haystack, &haystack_len, (char **)&needle, &needle_len, &loffset) == FAILURE) { + zend_long ret_pos; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|l", &haystack, &haystack_len, &needle, &needle_len, &loffset) == FAILURE) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "grapheme_strpos: unable to parse input param", 0 TSRMLS_CC ); - + "grapheme_strpos: unable to parse input param", 0 ); RETURN_FALSE; } @@@ -138,7 -147,7 +139,7 @@@ /* quick check to see if the string might be there * I realize that 'offset' is 'grapheme count offset' but will work in spite of that */ - found = php_memnstr(haystack + offset, needle, needle_len, haystack + haystack_len); - found = (unsigned char *)php_memnstr((char *)haystack + noffset, (char *)needle, needle_len, (char *)haystack + haystack_len); ++ found = php_memnstr(haystack + noffset, needle, needle_len, haystack + haystack_len); /* if it isn't there the we are done */ if (!found) { @@@ -196,15 -212,16 +197,16 @@@ PHP_FUNCTION(grapheme_stripos } - is_ascii = ( grapheme_ascii_check(haystack, haystack_len) >= 0 ); + is_ascii = ( grapheme_ascii_check((unsigned char*)haystack, haystack_len) >= 0 ); if ( is_ascii ) { + int32_t noffset = offset >= 0 ? offset : haystack_len + offset; - needle_dup = (unsigned char *)estrndup((char *)needle, needle_len); - php_strtolower((char *)needle_dup, needle_len); - haystack_dup = (unsigned char *)estrndup((char *)haystack, haystack_len); - php_strtolower((char *)haystack_dup, haystack_len); + needle_dup = estrndup(needle, needle_len); + php_strtolower(needle_dup, needle_len); + haystack_dup = estrndup(haystack, haystack_len); + php_strtolower(haystack_dup, haystack_len); - found = php_memnstr(haystack_dup + offset, needle_dup, needle_len, haystack_dup + haystack_len); - found = (unsigned char*) php_memnstr((char *)haystack_dup + noffset, (char *)needle_dup, needle_len, (char *)haystack_dup + haystack_len); ++ found = php_memnstr(haystack_dup + noffset, needle_dup, needle_len, haystack_dup + haystack_len); efree(haystack_dup); efree(needle_dup); diff --cc ext/xml/xml.c index 439d9df082,0850f0c605..6c5c9e39b2 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@@ -394,10 -419,10 +394,10 @@@ static void _xml_xmlchar_zval(const XML /* }}} */ /* {{{ xml_parser_dtor() */ -static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void xml_parser_dtor(zend_resource *rsrc) { xml_parser *parser = (xml_parser *)rsrc->ptr; - + if (parser->parser) { XML_ParserFree(parser->parser); } @@@ -887,41 -949,45 +887,41 @@@ void _xml_characterDataHandler(void *us } if (doprint || (! parser->skipwhite)) { if (parser->lastwasopen) { - zval **myval; - + zval *myval; + /* check if the current tag already has a value - if yes append to that! */ - if (zend_hash_find(Z_ARRVAL_PP(parser->ctag),"value",sizeof("value"),(void **) &myval) == SUCCESS) { - int newlen = Z_STRLEN_PP(myval) + decoded_len; - Z_STRVAL_PP(myval) = erealloc(Z_STRVAL_PP(myval),newlen+1); - strncpy(Z_STRVAL_PP(myval) + Z_STRLEN_PP(myval), decoded_value, decoded_len + 1); - Z_STRLEN_PP(myval) += decoded_len; - efree(decoded_value); + if ((myval = zend_hash_str_find(Z_ARRVAL_P(parser->ctag), "value", sizeof("value") - 1))) { + int newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value); + Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0); + strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value), + ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1); + zend_string_release(decoded_value); } else { - add_assoc_string(*(parser->ctag),"value",decoded_value,0); + add_assoc_str(parser->ctag, "value", decoded_value); } - + } else { - zval *tag; - zval **curtag, **mytype, **myval; - HashPosition hpos=NULL; - - zend_hash_internal_pointer_end_ex(Z_ARRVAL_P(parser->data), &hpos); - - if (hpos && (zend_hash_get_current_data_ex(Z_ARRVAL_P(parser->data), (void **) &curtag, &hpos) == SUCCESS)) { - if (zend_hash_find(Z_ARRVAL_PP(curtag),"type",sizeof("type"),(void **) &mytype) == SUCCESS) { - if (!strcmp(Z_STRVAL_PP(mytype), "cdata")) { - if (zend_hash_find(Z_ARRVAL_PP(curtag),"value",sizeof("value"),(void **) &myval) == SUCCESS) { - int newlen = Z_STRLEN_PP(myval) + decoded_len; - Z_STRVAL_PP(myval) = erealloc(Z_STRVAL_PP(myval),newlen+1); - strncpy(Z_STRVAL_PP(myval) + Z_STRLEN_PP(myval), decoded_value, decoded_len + 1); - Z_STRLEN_PP(myval) += decoded_len; - efree(decoded_value); + zval tag; + zval *curtag, *mytype, *myval; + + ZEND_HASH_REVERSE_FOREACH_VAL(Z_ARRVAL(parser->data), curtag) { + if ((mytype = zend_hash_str_find(Z_ARRVAL_P(curtag),"type", sizeof("type") - 1))) { + if (!strcmp(Z_STRVAL_P(mytype), "cdata")) { + if ((myval = zend_hash_str_find(Z_ARRVAL_P(curtag), "value", sizeof("value") - 1))) { + int newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value); + Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0); + strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value), + ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1); + zend_string_release(decoded_value); return; } } } - } + break; + } ZEND_HASH_FOREACH_END(); - if (parser->level <= XML_MAXLEVEL) { + if (parser->level <= XML_MAXLEVEL && parser->level > 0) { - MAKE_STD_ZVAL(tag); - - array_init(tag); + array_init(&tag); _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset); @@@ -1184,10 -1256,11 +1184,10 @@@ PHP_FUNCTION(xml_set_object /* please leave this commented - or ask thies@thieso.net before doing it (again) */ /* #ifdef ZEND_ENGINE_2 - zval_add_ref(&parser->object); + zval_add_ref(&parser->object); #endif */ - ALLOC_ZVAL(parser->object); - MAKE_COPY_ZVAL(&mythis, parser->object); + ZVAL_COPY(&parser->object, mythis); RETVAL_TRUE; } @@@ -1425,24 -1472,22 +1425,24 @@@ PHP_FUNCTION(xml_parse_into_struct return; } - if (info) { - zval_dtor(*info); - array_init(*info); + if (info) { + zval_ptr_dtor(info); + array_init(info); } - ZEND_FETCH_RESOURCE(parser,xml_parser *, &pind, -1, "XML Parser", le_xml_parser); - - zval_dtor(*xdata); - array_init(*xdata); + if ((parser = (xml_parser *)zend_fetch_resource(Z_RES_P(pind), "XML Parser", le_xml_parser)) == NULL) { + RETURN_FALSE; + } - parser->data = *xdata; + zval_ptr_dtor(xdata); + array_init(xdata); + ZVAL_COPY_VALUE(&parser->data, xdata); + if (info) { - parser->info = *info; + ZVAL_COPY_VALUE(&parser->info, info); } - + parser->level = 0; parser->ltags = safe_emalloc(XML_MAXLEVEL, sizeof(char *), 0);