]> granicus.if.org Git - php/commitdiff
Fixed bug #76675
authorPedro Magalhães <pmmaga@php.net>
Wed, 16 Jan 2019 00:33:03 +0000 (00:33 +0000)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 18 Jan 2019 11:04:25 +0000 (12:04 +0100)
Leave a reference to the resource in the php_curl.

NEWS
ext/curl/multi.c
ext/curl/tests/bug76675.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 967afa21a0666b7e8bebd775e2821a70b996e9d7..d337e7f3c88a5a6a5c0dbdb16b24b83c6dc317a7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ PHP                                                                        NEWS
 - Core:
   . Fixed bug #77339 (__callStatic may get incorrect arguments). (Dmitry)
 
+- Curl:
+  . Fixed bug #76675 (Segfault with H2 server push). (Pedro Magalhães)
+
 - GD:
   . Fixed bug #73281 (imagescale(…, IMG_BILINEAR_FIXED) can cause black border).
     (cmb)
index 3afe8ac413b41c95d03ca1e7a9b536d53678ed5e..073a6b3688bac6add7cdc685a29b001864515970 100644 (file)
@@ -509,6 +509,7 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
        Z_ADDREF_P(pz_parent_ch);
 
        res = zend_register_resource(ch, le_curl);
+       ch->res = res;
        ZVAL_RES(&pz_ch, res);
 
        size_t i;
diff --git a/ext/curl/tests/bug76675.phpt b/ext/curl/tests/bug76675.phpt
new file mode 100644 (file)
index 0000000..5e60c5c
--- /dev/null
@@ -0,0 +1,53 @@
+--TEST--
+Bug #76675 (Segfault with H2 server push write/writeheader handlers)
+--SKIPIF--
+<?php
+include 'skipif.inc';
+if (getenv("SKIP_ONLINE_TESTS")) {
+       die("skip online test");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x073d00) {
+       exit("skip: test may crash with curl < 7.61.0");
+}
+?>
+--FILE--
+<?php
+$transfers = 1;
+$callback = function($parent, $passed) use (&$transfers) {
+    curl_setopt($passed, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
+        echo "Received ".strlen($data);
+        return strlen($data);
+    });
+       $transfers++;
+       return CURL_PUSH_OK;
+};
+$mh = curl_multi_init();
+curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
+curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, $callback);
+$ch = curl_init();
+curl_setopt($ch, CURLOPT_URL, 'https://http2.golang.org/serverpush');
+curl_setopt($ch, CURLOPT_HTTP_VERSION, 3);
+curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
+curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+curl_multi_add_handle($mh, $ch);
+$active = null;
+do {
+    $status = curl_multi_exec($mh, $active);
+    do {
+        $info = curl_multi_info_read($mh);
+        if (false !== $info && $info['msg'] == CURLMSG_DONE) {
+            $handle = $info['handle'];
+            if ($handle !== null) {
+                $transfers--;
+                curl_multi_remove_handle($mh, $handle);
+                curl_close($handle);
+            }
+        }
+    } while ($info);
+} while ($transfers);
+curl_multi_close($mh);
+?>
+--EXPECTREGEX--
+(Received \d+)+