Merge branch 'PHP-5.6' into PHP-7.0
authorChristoph M. Becker <cmbecker69@gmx.de>
Sat, 20 Aug 2016 00:07:28 +0000 (02:07 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Sat, 20 Aug 2016 00:14:49 +0000 (02:14 +0200)
1  2 
NEWS
ext/xml/xml.c

diff --cc NEWS
index 79949534f4066910d3402b84f066b7073a441816,013d85f84b13c5b8e64e0ccd636b3f447bffc010..6e6edcf1e90bf5e15760a319fb93986b8456bb14
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -35,28 -30,13 +35,29 @@@ PH
      specifying a sequence). (Pablo Santiago Sánchez, Matteo)
    . Fixed bug #72759 (Regression in pgo_pgsql). (Anatol)
  
 +- Reflection:
 +  . Fixed bug #72846 (getConstant for a array constant with constant values
 +    returns NULL/NFC/UKNOWN). (Laruence)
 +
 +- Session:
 +  . Fixed bug #72724 (PHP7: session-uploadprogress kills httpd). (Nikita)
 +
  - Standard:
 -  . Fixed bug #72823 (strtr out-of-bound access). (cmb)
 +  . Fixed bug #55451 (substr_compare NULL length interpreted as 0). (Lauri
 +    Kenttä)
    . Fixed bug #72278 (getimagesize returning FALSE on valid jpg). (cmb)
  
 +- Streams:
 +  . Fixed bug #72853 (stream_set_blocking doesn't work). (Laruence)
 +  . Fixed bug #72764 (ftps:// opendir wrapper data channel encryption fails
 +    with IIS FTP 7.5, 8.5). (vhuk)
 +
 +- Sysvshm:
 +  . Fixed bug #72858 (shm_attach null dereference). (Anatol)
 +
  - XML:
    . Fixed bug #72085 (SEGV on unknown address zif_xml_parse). (cmb)
+   . Fixed bug #72714 (_xml_startElementHandler() segmentation fault). (cmb)
  
  - ZIP:
    . Fixed bug #68302 (impossible to compile php with zip support). (cmb)
diff --cc ext/xml/xml.c
index b7c4baa1a160ed50f3a0be6deb35dc52dbe75ec1,5d5c2e4c1950124a9e2aa9b2d09d10aa89afae06..de1019499818d1275e598c19c6bde5f5d0f884c7
@@@ -725,46 -785,48 +729,46 @@@ void _xml_startElementHandler(void *use
        if (parser) {
                parser->level++;
  
 -              tag_name = _xml_decode_tag(parser, name);
 +              tag_name = _xml_decode_tag(parser, (const char *)name);
  
 -              if (parser->startElementHandler) {
 -                      args[0] = _xml_resource_zval(parser->index);
 -                      args[1] = _xml_string_zval(SKIP_TAGSTART((char *) tag_name));
 -                      MAKE_STD_ZVAL(args[2]);
 -                      array_init(args[2]);
 +              if (!Z_ISUNDEF(parser->startElementHandler)) {
 +                      ZVAL_COPY(&args[0], &parser->index);
-                       ZVAL_STRING(&args[1], ZSTR_VAL(tag_name) + parser->toffset);
++                      ZVAL_STRING(&args[1], SKIP_TAGSTART(ZSTR_VAL(tag_name)));
 +                      array_init(&args[2]);
  
                        while (attributes && *attributes) {
 -                              att = _xml_decode_tag(parser, attributes[0]);
 -                              val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
 +                              zval tmp;
  
 -                              add_assoc_stringl(args[2], att, val, val_len, 0);
 +                              att = _xml_decode_tag(parser, (const char *)attributes[0]);
 +                              val = xml_utf8_decode(attributes[1], strlen((char *)attributes[1]), parser->target_encoding);
  
 -                              attributes += 2;
 +                              ZVAL_STR(&tmp, val);
 +                              zend_symtable_update(Z_ARRVAL(args[2]), att, &tmp);
  
 -                              efree(att);
 -                      }
 +                              attributes += 2;
  
 -                      if ((retval = xml_call_handler(parser, parser->startElementHandler, parser->startElementPtr, 3, args))) {
 -                              zval_ptr_dtor(&retval);
 +                              zend_string_release(att);
                        }
 -              }
 +                      
 +                      xml_call_handler(parser, &parser->startElementHandler, parser->startElementPtr, 3, args, &retval);
 +                      zval_ptr_dtor(&retval);
 +              } 
  
 -              if (parser->data) {
 +              if (!Z_ISUNDEF(parser->data)) {
                        if (parser->level <= XML_MAXLEVEL)  {
 -                              zval *tag, *atr;
 +                              zval tag, atr;
                                int atcnt = 0;
  
 -                              MAKE_STD_ZVAL(tag);
 -                              MAKE_STD_ZVAL(atr);
 -
 -                              array_init(tag);
 -                              array_init(atr);
 +                              array_init(&tag);
 +                              array_init(&atr);
  
 -                              _xml_add_to_info(parser,SKIP_TAGSTART((char *) tag_name));
 +                              _xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset);
  
-                               add_assoc_string(&tag, "tag", ZSTR_VAL(tag_name) + parser->toffset); /* cast to avoid gcc-warning */
 -                              add_assoc_string(tag,"tag",SKIP_TAGSTART((char *) tag_name),1);
 -                              add_assoc_string(tag,"type","open",1);
 -                              add_assoc_long(tag,"level",parser->level);
++                              add_assoc_string(&tag, "tag", SKIP_TAGSTART(ZSTR_VAL(tag_name))); /* cast to avoid gcc-warning */
 +                              add_assoc_string(&tag, "type", "open");
 +                              add_assoc_long(&tag, "level", parser->level);
  
 -                              parser->ltags[parser->level-1] = estrdup(tag_name);
 +                              parser->ltags[parser->level-1] = estrdup(ZSTR_VAL(tag_name));
                                parser->lastwasopen = 1;
  
                                attributes = (const XML_Char **) attrs;
  void _xml_endElementHandler(void *userData, const XML_Char *name)
  {
        xml_parser *parser = (xml_parser *)userData;
 -      char *tag_name;
 +      zend_string *tag_name;
  
        if (parser) {
 -              zval *retval, *args[2];
 +              zval retval, args[2];
  
 -              tag_name = _xml_decode_tag(parser, name);
 +              tag_name = _xml_decode_tag(parser, (const char *)name);
  
 -              if (parser->endElementHandler) {
 -                      args[0] = _xml_resource_zval(parser->index);
 -                      args[1] = _xml_string_zval(SKIP_TAGSTART((char *) tag_name));
 +              if (!Z_ISUNDEF(parser->endElementHandler)) {
 +                      ZVAL_COPY(&args[0], &parser->index);
-                       ZVAL_STRING(&args[1], ZSTR_VAL(tag_name) + parser->toffset);
++                      ZVAL_STRING(&args[1], SKIP_TAGSTART(ZSTR_VAL(tag_name)));
  
 -                      if ((retval = xml_call_handler(parser, parser->endElementHandler, parser->endElementPtr, 2, args))) {
 -                              zval_ptr_dtor(&retval);
 -                      }
 -              }
 +                      xml_call_handler(parser, &parser->endElementHandler, parser->endElementPtr, 2, args, &retval);
 +                      zval_ptr_dtor(&retval);
 +              } 
  
 -              if (parser->data) {
 -                      zval *tag;
 +              if (!Z_ISUNDEF(parser->data)) {
 +                      zval tag;
  
                        if (parser->lastwasopen) {
 -                              add_assoc_string(*(parser->ctag),"type","complete",1);
 +                              add_assoc_string(parser->ctag, "type", "complete");
                        } else {
 -                              MAKE_STD_ZVAL(tag);
 -
 -                              array_init(tag);
 -
 -                              _xml_add_to_info(parser,SKIP_TAGSTART((char *) tag_name));
 -
 -                              add_assoc_string(tag,"tag",SKIP_TAGSTART((char *) tag_name),1);
 -                              add_assoc_string(tag,"type","close",1);
 -                              add_assoc_long(tag,"level",parser->level);
 -
 -                              zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
 +                              array_init(&tag);
 +                                
 +                              _xml_add_to_info(parser, ZSTR_VAL(tag_name) + parser->toffset);
 +
-                               add_assoc_string(&tag, "tag", ZSTR_VAL(tag_name) + parser->toffset); /* cast to avoid gcc-warning */
++                              add_assoc_string(&tag, "tag", SKIP_TAGSTART(ZSTR_VAL(tag_name))); /* cast to avoid gcc-warning */
 +                              add_assoc_string(&tag, "type", "close");
 +                              add_assoc_long(&tag, "level", parser->level);
 +                                
 +                              zend_hash_next_index_insert(Z_ARRVAL(parser->data), &tag);
                        }
  
                        parser->lastwasopen = 0;
@@@ -918,22 -987,24 +922,22 @@@ void _xml_characterDataHandler(void *us
                                                                }
                                                        }
                                                }
 -                                      }
 +                                              break;
 +                                      } ZEND_HASH_FOREACH_END();
  
                                        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);
+                                               _xml_add_to_info(parser,SKIP_TAGSTART(parser->ltags[parser->level-1]));
  
-                                               add_assoc_string(&tag, "tag", parser->ltags[parser->level-1] + parser->toffset);
 -                                              add_assoc_string(tag,"tag",SKIP_TAGSTART(parser->ltags[parser->level-1]),1);
 -                                              add_assoc_string(tag,"value",decoded_value,0);
 -                                              add_assoc_string(tag,"type","cdata",1);
 -                                              add_assoc_long(tag,"level",parser->level);
++                                              add_assoc_string(&tag, "tag", SKIP_TAGSTART(parser->ltags[parser->level-1]));
 +                                              add_assoc_str(&tag, "value", decoded_value);
 +                                              add_assoc_string(&tag, "type", "cdata");
 +                                              add_assoc_long(&tag, "level", parser->level);
  
 -                                              zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
 +                                              zend_hash_next_index_insert(Z_ARRVAL(parser->data), &tag);
                                        } else if (parser->level == (XML_MAXLEVEL + 1)) {
 -                                              TSRMLS_FETCH();
 -                                              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated");
 +                                                                                      php_error_docref(NULL, E_WARNING, "Maximum depth exceeded - Results truncated");
                                        }
                                }
                        } else {
@@@ -1604,7 -1636,11 +1608,11 @@@ PHP_FUNCTION(xml_parser_set_option
                        break;
                case PHP_XML_OPTION_SKIP_TAGSTART:
                        convert_to_long_ex(val);
 -                      parser->toffset = Z_LVAL_PP(val);
 +                      parser->toffset = Z_LVAL_P(val);
+                       if (parser->toffset < 0) {
+                               php_error_docref(NULL TSRMLS_CC, E_NOTICE, "tagstart ignored");
+                               parser->toffset = 0;
+                       }
                        break;
                case PHP_XML_OPTION_SKIP_WHITE:
                        convert_to_long_ex(val);