]> granicus.if.org Git - php/commitdiff
Update and integrate openssl client proxy test
authorJakub Zelenka <bukka@php.net>
Wed, 16 Jan 2019 18:14:30 +0000 (18:14 +0000)
committerJakub Zelenka <bukka@php.net>
Fri, 25 Jan 2019 14:09:55 +0000 (14:09 +0000)
ext/openssl/tests/ServerClientProxyTestCase.inc [deleted file]
ext/openssl/tests/ServerClientTestCase.inc
ext/openssl/tests/bug77390.phpt [moved from ext/openssl/tests/non_blocking_eof.phpt with 71% similarity]

diff --git a/ext/openssl/tests/ServerClientProxyTestCase.inc b/ext/openssl/tests/ServerClientProxyTestCase.inc
deleted file mode 100644 (file)
index c55159f..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-const WORKER_ARGV_VALUE = 'RUN_WORKER';
-
-function phpt_notify($worker = null)
-{
-       ServerClientProxyTestCase::getInstance()->notify($worker);
-}
-
-function phpt_wait($worker = null)
-{
-       ServerClientProxyTestCase::getInstance()->wait($worker);
-}
-
-/**
- * This is a singleton to let the wait/notify functions work
- * I know it's horrible, but it's a means to an end
- */
-class ServerClientProxyTestCase
-{
-       private $isWorker = false;
-
-       private $workerHandles = [];
-
-       private $workerStdIn = [];
-
-       private $workerStdOut = [];
-
-       private static $instance;
-
-       public static function getInstance($isWorker = false)
-       {
-               if (!isset(self::$instance)) {
-                       self::$instance = new self($isWorker);
-               }
-
-               return self::$instance;
-       }
-
-       public function __construct($isWorker = false)
-       {
-               if (!isset(self::$instance)) {
-                       self::$instance = $this;
-               }
-
-               $this->isWorker = $isWorker;
-       }
-
-       private function spawnWorkerProcess($worker, $code)
-       {
-               if (defined("PHP_WINDOWS_VERSION_MAJOR")) {
-                               $ini = php_ini_loaded_file();
-                               $cmd = sprintf('%s %s "%s" %s', PHP_BINARY, $ini ? "-n -c $ini" : "", __FILE__, WORKER_ARGV_VALUE);
-               } else {
-                               $cmd = sprintf('%s "%s" %s %s', PHP_BINARY, __FILE__, WORKER_ARGV_VALUE, $worker);
-               }
-               $this->workerHandle[$worker] = proc_open($cmd, [['pipe', 'r'], ['pipe', 'w'], STDERR], $pipes);
-               $this->workerStdIn[$worker] = $pipes[0];
-               $this->workerStdOut[$worker] = $pipes[1];
-
-               fwrite($this->workerStdIn[$worker], $code . "\n---\n");
-       }
-
-       private function cleanupWorkerProcess($worker)
-       {
-               fclose($this->workerStdIn[$worker]);
-               fclose($this->workerStdOut[$worker]);
-               proc_close($this->workerHandle[$worker]);
-       }
-
-       private function stripPhpTagsFromCode($code)
-       {
-               return preg_replace('/^\s*<\?(?:php)?|\?>\s*$/i', '', $code);
-       }
-
-       public function runWorker()
-       {
-               $code = '';
-
-               while (1) {
-                       $line = fgets(STDIN);
-
-                       if (trim($line) === "---") {
-                               break;
-                       }
-
-                       $code .= $line;
-               }
-
-               eval($code);
-       }
-
-       public function run($testCode, array $workerCodes)
-       {
-               foreach ($workerCodes as $worker => $code) {
-                       $this->spawnWorkerProcess($worker, $this->stripPhpTagsFromCode($code));
-               }
-               eval($this->stripPhpTagsFromCode($testCode));
-               foreach ($workerCodes as $worker => $code) {
-                       $this->cleanupWorkerProcess($worker);
-               }
-       }
-
-       public function wait($worker)
-       {
-               fgets($this->isWorker ? STDIN : $this->workerStdOut[$worker]);
-       }
-
-       public function notify($worker)
-       {
-               fwrite($this->isWorker ? STDOUT : $this->workerStdIn[$worker], "\n");
-       }
-}
-
-if (isset($argv[1]) && $argv[1] === WORKER_ARGV_VALUE) {
-       ServerClientProxyTestCase::getInstance(true)->runWorker();
-}
index f0e40fa53545faefaed502bd17e46fb0737dd081..4bad3c2995aeff38126128dc5fcb0f70bd00f200 100644 (file)
@@ -2,14 +2,16 @@
 
 const WORKER_ARGV_VALUE = 'RUN_WORKER';
 
-function phpt_notify()
+const WORKER_DEFAULT_NAME = 'server';
+
+function phpt_notify($worker = WORKER_DEFAULT_NAME)
 {
-    ServerClientTestCase::getInstance()->notify();
+    ServerClientTestCase::getInstance()->notify($worker);
 }
 
-function phpt_wait()
+function phpt_wait($worker = WORKER_DEFAULT_NAME)
 {
-    ServerClientTestCase::getInstance()->wait();
+    ServerClientTestCase::getInstance()->wait($worker);
 }
 
 /**
@@ -20,11 +22,11 @@ class ServerClientTestCase
 {
     private $isWorker = false;
 
-    private $workerHandle;
+    private $workerHandle = [];
 
-    private $workerStdIn;
+    private $workerStdIn = [];
 
-    private $workerStdOut;
+    private $workerStdOut = [];
 
     private static $instance;
 
@@ -46,26 +48,41 @@ class ServerClientTestCase
         $this->isWorker = $isWorker;
     }
 
-    private function spawnWorkerProcess($code)
+    private function spawnWorkerProcess($worker, $code)
     {
         if (defined("PHP_WINDOWS_VERSION_MAJOR")) {
-                $ini = php_ini_loaded_file();
-                $cmd = sprintf('%s %s "%s" %s', PHP_BINARY, $ini ? "-n -c $ini" : "", __FILE__, WORKER_ARGV_VALUE);
+            $ini = php_ini_loaded_file();
+            $cmd = sprintf(
+                '%s %s "%s" %s',
+                PHP_BINARY, $ini ? "-n -c $ini" : "",
+                __FILE__,
+                WORKER_ARGV_VALUE
+            );
         } else {
-                $cmd = sprintf('%s "%s" %s', PHP_BINARY, __FILE__, WORKER_ARGV_VALUE);
+            $cmd = sprintf(
+                '%s "%s" %s %s',
+                PHP_BINARY,
+                __FILE__,
+                WORKER_ARGV_VALUE,
+                $worker
+            );
         }
-        $this->workerHandle = proc_open($cmd, [['pipe', 'r'], ['pipe', 'w'], STDERR], $pipes);
-        $this->workerStdIn = $pipes[0];
-        $this->workerStdOut = $pipes[1];
-
-        fwrite($this->workerStdIn, $code . "\n---\n");
+        $this->workerHandle[$worker] = proc_open(
+            $cmd,
+            [['pipe', 'r'], ['pipe', 'w'], STDERR],
+            $pipes
+        );
+        $this->workerStdIn[$worker] = $pipes[0];
+        $this->workerStdOut[$worker] = $pipes[1];
+
+        fwrite($this->workerStdIn[$worker], $code . "\n---\n");
     }
 
-    private function cleanupWorkerProcess()
+    private function cleanupWorkerProcess($worker)
     {
-        fclose($this->workerStdIn);
-        fclose($this->workerStdOut);
-        proc_close($this->workerHandle);
+        fclose($this->workerStdIn[$worker]);
+        fclose($this->workerStdOut[$worker]);
+        proc_close($this->workerHandle[$worker]);
     }
 
     private function stripPhpTagsFromCode($code)
@@ -90,21 +107,28 @@ class ServerClientTestCase
         eval($code);
     }
 
-    public function run($proc1Code, $proc2Code)
+    public function run($masterCode, $workerCode)
     {
-        $this->spawnWorkerProcess($this->stripPhpTagsFromCode($proc2Code));
-        eval($this->stripPhpTagsFromCode($proc1Code));
-        $this->cleanupWorkerProcess();
+        if (!is_array($workerCode)) {
+            $workerCode = [WORKER_DEFAULT_NAME => $workerCode];
+        }
+        foreach ($workerCode as $worker => $code) {
+            $this->spawnWorkerProcess($worker, $this->stripPhpTagsFromCode($code));
+        }
+        eval($this->stripPhpTagsFromCode($masterCode));
+        foreach ($workerCode as $worker => $code) {
+            $this->cleanupWorkerProcess($worker);
+        }
     }
 
-    public function wait()
+    public function wait($worker)
     {
-        fgets($this->isWorker ? STDIN : $this->workerStdOut);
+        fgets($this->isWorker ? STDIN : $this->workerStdOut[$worker]);
     }
 
-    public function notify()
+    public function notify($worker)
     {
-        fwrite($this->isWorker ? STDOUT : $this->workerStdIn, "\n");
+        fwrite($this->isWorker ? STDOUT : $this->workerStdIn[$worker], "\n");
     }
 }
 
similarity index 71%
rename from ext/openssl/tests/non_blocking_eof.phpt
rename to ext/openssl/tests/bug77390.phpt
index 86b3815153e1687ad6a8cae7022836829426ec4a..d746a5d4aac1b606ecd456f8817f1af2729c14c2 100644 (file)
@@ -1,5 +1,5 @@
 --TEST--
-php_stream_eof() should not block on SSL non-blocking streams when packets are fragmented
+Bug #76705: feof might hang on TLS streams in case of fragmented TLS records
 --SKIPIF--
 <?php
 if (!extension_loaded("openssl")) die("skip openssl not loaded");
@@ -7,9 +7,12 @@ if (!function_exists("proc_open")) die("skip no proc_open");
 ?>
 --FILE--
 <?php
+$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug77390.pem.tmp';
+$cacertFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug77390-ca.pem.tmp';
 
+$peerName = 'bug77390';
 $clientCode = <<<'CODE'
-       $context = stream_context_create(['ssl' => ['verify_peer' => false, 'peer_name' => 'bug54992.local']]);
+       $context = stream_context_create(['ssl' => ['verify_peer' => false, 'peer_name' => '%s']]);
 
        phpt_wait('server');
        phpt_notify('proxy');
@@ -32,9 +35,10 @@ $clientCode = <<<'CODE'
        phpt_notify('server');
        phpt_notify('proxy');
 CODE;
+$clientCode = sprintf($clientCode, $peerName);
 
 $serverCode = <<<'CODE'
-       $context = stream_context_create(['ssl' => ['local_cert' => __DIR__ . '/bug54992.pem']]);
+       $context = stream_context_create(['ssl' => ['local_cert' => '%s']]);
 
        $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
        $fp = stream_socket_server("ssl://127.0.0.1:10011", $errornum, $errorstr, $flags, $context);
@@ -46,6 +50,7 @@ $serverCode = <<<'CODE'
        phpt_wait();
        fclose($conn);
 CODE;
+$serverCode = sprintf($serverCode, $certFile);
 
 $proxyCode = <<<'CODE'
        phpt_wait();
@@ -87,12 +92,22 @@ $proxyCode = <<<'CODE'
        phpt_wait();
 CODE;
 
-include 'ServerClientProxyTestCase.inc';
-ServerClientProxyTestCase::getInstance()->run($clientCode, [
+include 'CertificateGenerator.inc';
+$certificateGenerator = new CertificateGenerator();
+$certificateGenerator->saveCaCert($cacertFile);
+$certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile);
+
+include 'ServerClientTestCase.inc';
+ServerClientTestCase::getInstance()->run($clientCode, [
        'server' => $serverCode,
        'proxy' => $proxyCode,
 ]);
 ?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug77390.pem.tmp');
+@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug77390-ca.pem.tmp');
+?>
 --EXPECT--
 string(0) ""
 string(0) ""