From f9a699f6c3aa7acea922242a0f14731f6b829742 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Fri, 23 Sep 2016 16:02:50 +0200 Subject: [PATCH] Fixed bug #73037 SoapServer reports Bad Request when gzipped (cherry picked from commit 410c68788ae4826807e8ced3f4a02e676142b22a) --- ext/soap/soap.c | 2 + ext/soap/tests/bug73037.phpt | 196 +++++++++++++++++++++++++++++++++++ main/streams/streams.c | 2 +- 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 ext/soap/tests/bug73037.phpt diff --git a/ext/soap/soap.c b/ext/soap/soap.c index f0e26bf19d0..f79d84c8a1f 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1598,6 +1598,8 @@ PHP_METHOD(SoapServer, handle) if (zf) { php_stream_filter_append(&SG(request_info).request_body->readfilters, zf); + SG(request_info).request_body->flags &= ~PHP_STREAM_FLAG_NO_BUFFER; + } else { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Can't uncompress compressed request"); return; diff --git a/ext/soap/tests/bug73037.phpt b/ext/soap/tests/bug73037.phpt new file mode 100644 index 00000000000..bb90538b9bb --- /dev/null +++ b/ext/soap/tests/bug73037.phpt @@ -0,0 +1,196 @@ +--TEST-- +Bug #73037 SoapServer reports Bad Request when gzipped, var 0 +--SKIPIF-- + +--FILE-- + + Empire Burlesque + Bob Dylan + USA + Columbia + 10.90 + 1985 + "; + + $begin = ''; + $end = ''; + + $min = strlen($begin) + strlen($piece) + strlen($end); + $max = $max < $min ? $min : $max; + + $data = $begin; + $data .= $piece; + while (strlen($data) + strlen($end) < $max) { + /* Randomize a bit, taking gzip in account. */ + $tmp = str_replace( + array( + "Empire Burlesque", + "Bob Dylan", + ), + array( + md5(uniqid()), + sha1(uniqid()), + ), + $piece + ); + + if (strlen($begin) + strlen($tmp) + strlen($end) > $max) { + break; + } + + $data .= $tmp; + } + $data .= $end; + + return $data; +} + +$code = <<<'PHP' +$s = new SoapServer(NULL, array('uri' => 'http://here')); +$s->setObject(new stdclass()); +$s->handle(); +PHP; + +$router = "bug73037_server.php"; +file_put_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . $router, ''); + +$host = "localhost"; +$port = "8965"; +$desc = array( + 0 => STDIN, + 1 => STDOUT, + 2 => STDERR, +); +/*$desc = array( + array("pipe", "r"), + array("pipe", "w"), + array("pipe", "w") +);*/ +if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = getenv('TEST_PHP_EXECUTABLE') . " -t " . dirname(__FILE__) . " -S $host:$port"; + $handle = proc_open($cmd, $desc, $pipes, dirname(__FILE__), NULL, array("bypass_shell" => true, "suppress_errors" => true)); +} else { + $cmd = getenv('TEST_PHP_EXECUTABLE') . " -t " . dirname(__FILE__) . " -S $host:$port 2>/dev/null"; + $handle = proc_open($cmd, $desc, $pipes, dirname(__FILE__)); +} +//echo stream_get_contents($pipes[1]), "\n", stream_get_contents($pipes[2]); + +foreach (array(1024-1, 1024*8-3, 1024*9+1, 1024*16-1, 1024*32-5, 1024*64+3, 1024*128-7) as $k => $i) { + echo "Iteration $k\n\n"; + + /* with and without compression */ + foreach (array(false, true) as $b) { + $data = get_data($i); + if ($b) { + $data = gzencode($data); + } + $len = strlen($data); + + //echo "len=$len\n"; + + $hdrs = <<"); + if (false === $pos) { + echo $out; + goto cleanup; + } + $pos0 = $pos + strlen(""); + $pos = strpos($out, ""); + if (false === $pos) { + echo $out; + goto cleanup; + } + $len = $pos - $pos0; + echo substr($out, $pos0, $len); + } + +cleanup: + fclose($fp); + + echo "\n\n"; + } +} + +proc_terminate($handle); + +?> +==DONE== +--CLEAN-- + +--EXPECT-- +Iteration 0 + +Function 'CATALOG' doesn't exist + +Function 'CATALOG' doesn't exist + +Iteration 1 + +Function 'CATALOG' doesn't exist + +Function 'CATALOG' doesn't exist + +Iteration 2 + +Function 'CATALOG' doesn't exist + +Function 'CATALOG' doesn't exist + +Iteration 3 + +Function 'CATALOG' doesn't exist + +Function 'CATALOG' doesn't exist + +Iteration 4 + +Function 'CATALOG' doesn't exist + +Function 'CATALOG' doesn't exist + +Iteration 5 + +Function 'CATALOG' doesn't exist + +Function 'CATALOG' doesn't exist + +Iteration 6 + +Function 'CATALOG' doesn't exist + +Function 'CATALOG' doesn't exist + +==DONE== diff --git a/main/streams/streams.c b/main/streams/streams.c index 4e00cd1be39..4446f9ecd58 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1289,7 +1289,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_ } break; case SEEK_SET: - if (offset > stream->position && + if (offset >= stream->position && offset <= stream->position + stream->writepos - stream->readpos) { stream->readpos += offset - stream->position; stream->position = offset;