]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-5.6' into PHP-7.0
authorAnatol Belski <ab@php.net>
Wed, 27 Apr 2016 09:45:29 +0000 (11:45 +0200)
committerAnatol Belski <ab@php.net>
Wed, 27 Apr 2016 09:45:29 +0000 (11:45 +0200)
* 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

1  2 
ext/bcmath/bcmath.c
ext/exif/exif.c
ext/intl/grapheme/grapheme_string.c
ext/xml/xml.c

index fd14050f05600486fd997b0c8b84c3b28b462dc0,ea2c38e418e126ee8dcd5a6b875f7aca818fe0c1..7100367faac1f1f021c3ef5961b134a050e1127c
@@@ -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/exif/exif.c
Simple merge
index f42ba7e69ecc084aefa8860f61e0f02e374ebc53,3ba9b515240d31c9566090ff9a7c78e55efb4d7d..5687e3e260719e31b7edf7517922f7264f4b8fa5
@@@ -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;
        }
  
        /* 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 ) {
 -              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);
+               int32_t noffset = offset >= 0 ? offset : haystack_len + offset;
 +              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 439d9df082e38a1887238a263e83e94e7a2d41c4,0850f0c605d28d45a3ff5452b5a1fc1145aa3ac9..6c5c9e39b25a0cac18a4247c73b6805e68e0f3da
@@@ -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);