mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-09 10:10:50 +00:00
Compare commits
1
Commits
php-5.5.13
...
php-5.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79f14997b4 |
No files matched your search
Executable
+30
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Bug #36006 (Problem with $this in __destruct())
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Person {
|
||||
public $dad;
|
||||
public function __destruct() {
|
||||
$this->dad = null; /* no segfault if this is commented out */
|
||||
}
|
||||
}
|
||||
|
||||
class Dad extends Person {
|
||||
public $son;
|
||||
public function __construct() {
|
||||
$this->son = new Person;
|
||||
$this->son->dad = $this; /* no segfault if this is commented out */
|
||||
}
|
||||
public function __destruct() {
|
||||
$this->son = null;
|
||||
parent::__destruct(); /* segfault here */
|
||||
}
|
||||
}
|
||||
|
||||
$o = new Dad;
|
||||
unset($o);
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #36037 (heredoc adds extra line number)
|
||||
--FILE--
|
||||
<?php
|
||||
echo __LINE__, "\n";
|
||||
$x=<<<XXX
|
||||
123
|
||||
YYY;
|
||||
XXX;
|
||||
echo __LINE__, "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
2
|
||||
7
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Bug #36071 (Engine Crash related with 'clone')
|
||||
--INI--
|
||||
error_reporting=4095
|
||||
--FILE--
|
||||
<?php
|
||||
$a = clone 0;
|
||||
$a[0]->b = 0;
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: __clone method called on non-object in %sbug36071.php on line 2
|
||||
ok
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #36268 (Object destructors called even after fatal errors)
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
function __destruct() {
|
||||
echo "Ha!\n";
|
||||
}
|
||||
}
|
||||
$x = new Foo();
|
||||
bar();
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Call to undefined function bar() in %sbug36268.php on line 8
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #36303 (foreach on error_zval produces segfault)
|
||||
--FILE--
|
||||
<?php
|
||||
$x="test";
|
||||
foreach($x->a->b as &$v) {
|
||||
}
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Invalid argument supplied for foreach() in %sbug36303.php on line 3
|
||||
ok
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
Bug #36513 (comment will be outputed in last line)
|
||||
--FILE--
|
||||
<?php
|
||||
function test($s) {
|
||||
echo "'".trim(str_replace(" ", " ", htmlspecialchars_decode(strip_tags(highlight_string($s,1)))))."'\n";
|
||||
}
|
||||
|
||||
eval('echo "1";//2');
|
||||
eval('echo 3; //{ 4?>5');
|
||||
echo "\n";
|
||||
|
||||
//test('<?php echo "1";//');
|
||||
test('<?php echo "1";//2');
|
||||
test('<?php echo "1";//22');
|
||||
test('<?php echo 3; // 4 ?>5');
|
||||
?>
|
||||
--EXPECT--
|
||||
135
|
||||
'<?php echo "1";//2'
|
||||
'<?php echo "1";//22'
|
||||
'<?php echo 3; // 4 ?>5'
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #36568 (memory_limit has no effect)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!function_exists('memory_get_usage')) die('skip PHP is configured without memory_limit');
|
||||
?>
|
||||
--INI--
|
||||
memory_limit=16M
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("memory_limit", "32M");
|
||||
echo ini_get("memory_limit");
|
||||
?>
|
||||
--EXPECT--
|
||||
32M
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #37046 (foreach breaks static scope)
|
||||
--FILE--
|
||||
<?php
|
||||
function s() {
|
||||
static $storage = array(array('x', 'y'));
|
||||
return $storage[0];
|
||||
}
|
||||
|
||||
foreach (s() as $k => $function) {
|
||||
echo "op1 $k\n";
|
||||
if ($k == 0) {
|
||||
foreach (s() as $k => $function) {
|
||||
echo "op2 $k\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
op1 0
|
||||
op2 0
|
||||
op2 1
|
||||
op1 1
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #37138 (__autoload tries to load callback'ed self and parent)
|
||||
--FILE--
|
||||
<?php
|
||||
function __autoload ($CN) {var_dump ($CN);}
|
||||
class st {
|
||||
public static function e () {echo ("EHLO\n");}
|
||||
public static function e2 () {call_user_func (array ('self', 'e'));}
|
||||
}
|
||||
class stch extends st {
|
||||
public static function g () {call_user_func (array ('parent', 'e'));}
|
||||
}
|
||||
st::e ();
|
||||
st::e2 ();
|
||||
stch::g ();
|
||||
?>
|
||||
--EXPECT--
|
||||
EHLO
|
||||
EHLO
|
||||
EHLO
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
zend_strtod() leaks on big doubles
|
||||
--INI--
|
||||
precision=14
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump("1139932690.21688500" - "1139932790.21688500");
|
||||
var_dump("1139932690000.21688500" - "331139932790.21688500");
|
||||
var_dump("339932690.21688500" - "4564645646456463461139932790.21688500");
|
||||
var_dump("123123139932690.21688500" - "11399327900000000.21688500");
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
float(-100)
|
||||
float(808792757210)
|
||||
float(-4.5646456464565E+27)
|
||||
float(-11276204760067000)
|
||||
Done
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
Bug #34272 (empty array onto COM object blows up)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("com_dotnet")) print "skip COM/.Net support not present"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
|
||||
try {
|
||||
$dict = new COM("Scripting.Dictionary");
|
||||
$dict->add('foo', array());
|
||||
print sizeof($dict['foo'])."\n";
|
||||
$dict->add('bar', array(23));
|
||||
print sizeof($dict['bar'])." \n";
|
||||
} catch (Exception $e) {
|
||||
print $e;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
0
|
||||
1
|
||||
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Bug #36224 (date(DATE_ATOM) gives wrong resulsts)
|
||||
--FILE--
|
||||
<?php
|
||||
date_default_timezone_set("Europe/Oslo");
|
||||
|
||||
echo date(DATE_ATOM, strtotime('2006-01-31T19:23:56Z')) . "\n";
|
||||
echo date(DATE_ATOM, strtotime('2006-01-31T19:23:56')) . "\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
2006-01-31T20:23:56+01:00
|
||||
2006-01-31T19:23:56+01:00
|
||||
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #36510 (strtotime() fails to parse date strings with tabs)
|
||||
--FILE--
|
||||
<?php
|
||||
date_default_timezone_set("UTC");
|
||||
|
||||
$t = 1140973388;
|
||||
|
||||
var_dump(strtotime("-2 hours", $t));
|
||||
var_dump(strtotime("-2\thours", $t));
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1140966188)
|
||||
int(1140966188)
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #36599 (DATE_W3C format constant incorrect).
|
||||
--FILE--
|
||||
<?php
|
||||
date_default_timezone_set("UTC");
|
||||
|
||||
echo date( DATE_ATOM, strtotime( "2006-03-03 08:47:55" ) ), "\n";
|
||||
echo date( DATE_W3C, strtotime( "2006-03-03 08:47:55" ) ), "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
2006-03-03T08:47:55+00:00
|
||||
2006-03-03T08:47:55+00:00
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #36988 (mktime freezes on long numbers)
|
||||
--INI--
|
||||
date.timezone=GMT
|
||||
--FILE--
|
||||
<?php
|
||||
$start = microtime(true);
|
||||
$a = mktime(1, 1, 1, 1, 1, 11111111111);
|
||||
echo (microtime(true) - $start) < 1 ? "smaller than one second" : "more than a second";
|
||||
?>
|
||||
--EXPECT--
|
||||
smaller than one second
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #37017 (strtotime fails before 13:00:00 with some time zones identifiers).
|
||||
--INI--
|
||||
date.timezone=GMT
|
||||
--FILE--
|
||||
<?php
|
||||
echo strtotime("2006-05-12 13:00:01 America/New_York"), "\n";
|
||||
echo strtotime("2006-05-12 13:00:00 America/New_York"), "\n";
|
||||
echo strtotime("2006-05-12 12:59:59 America/New_York"), "\n";
|
||||
echo strtotime("2006-05-12 12:59:59 GMT"), "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
1147453201
|
||||
1147453200
|
||||
1147453199
|
||||
1147438799
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
Bug #36436 DBA problem with Berkeley DB4
|
||||
--SKIPIF--
|
||||
<?php
|
||||
$handler = 'db4';
|
||||
require_once('skipif.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$handler = 'db4';
|
||||
require_once('test.inc');
|
||||
|
||||
$db = dba_popen($db_filename, 'c', 'db4');
|
||||
|
||||
dba_insert('X', 'XYZ', $db);
|
||||
dba_insert('Y', '123', $db);
|
||||
|
||||
var_dump($db, dba_fetch('X', $db));
|
||||
|
||||
var_dump(dba_firstkey($db));
|
||||
var_dump(dba_nextkey($db));
|
||||
|
||||
dba_close($db);
|
||||
unlink($db_filename);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
resource(%d) of type (dba persistent)
|
||||
string(3) "XYZ"
|
||||
string(1) "X"
|
||||
string(1) "Y"
|
||||
===DONE===
|
||||
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Bug #36756: (DOMDocument::removeChild corrupts node)
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* Node is preserved from removeChild */
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadXML('<root><child/></root>');
|
||||
$xpath = new DOMXpath($dom);
|
||||
$node = $xpath->query('/root')->item(0);
|
||||
echo $node->nodeName . "\n";
|
||||
$dom->removeChild($GLOBALS['dom']->firstChild);
|
||||
echo "nodeType: " . $node->nodeType . "\n";
|
||||
|
||||
/* Node gets destroyed during removeChild */
|
||||
$dom->loadXML('<root><child/></root>');
|
||||
$xpath = new DOMXpath($dom);
|
||||
$node = $xpath->query('//child')->item(0);
|
||||
echo $node->nodeName . "\n";
|
||||
$GLOBALS['dom']->removeChild($GLOBALS['dom']->firstChild);
|
||||
|
||||
echo "nodeType: " . $node->nodeType . "\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
root
|
||||
nodeType: 1
|
||||
child
|
||||
|
||||
Warning: Couldn't fetch DOMElement. Node no longer exists in %sbug36756.php on line %d
|
||||
|
||||
Notice: Undefined property: DOMElement::$nodeType in %sbug36756.php on line %d
|
||||
nodeType:
|
||||
@@ -0,0 +1,99 @@
|
||||
--TEST--
|
||||
Test 7: DTD tests
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml = <<< EOXML
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE courses [
|
||||
<!ELEMENT courses (course+)>
|
||||
<!ELEMENT course (title, description, temp*)>
|
||||
<!ATTLIST course cid ID #REQUIRED>
|
||||
<!ELEMENT title (#PCDATA)>
|
||||
<!ELEMENT description (#PCDATA)>
|
||||
<!ELEMENT temp (#PCDATA)>
|
||||
<!ATTLIST temp vid ID #REQUIRED>
|
||||
<!ENTITY test 'http://www.hpl.hp.com/semweb/2003/query_tester#'>
|
||||
<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
||||
<!NOTATION GIF PUBLIC "-" "image/gif">
|
||||
<!ENTITY myimage PUBLIC "-" "mypicture.gif" NDATA GIF>
|
||||
]>
|
||||
<courses>
|
||||
<course cid="c1">
|
||||
<title>Basic Languages</title>
|
||||
<description>Introduction to Languages</description>
|
||||
</course>
|
||||
<course cid="c6">
|
||||
<title>French I</title>
|
||||
<description>Introduction to French</description>
|
||||
<temp vid="c7">
|
||||
</temp>
|
||||
</course>
|
||||
</courses>
|
||||
EOXML;
|
||||
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadXML($xml);
|
||||
|
||||
$dtd = $dom->doctype;
|
||||
|
||||
/* Notation Tests */
|
||||
$nots = $dtd->notations;
|
||||
|
||||
$length = $nots->length;
|
||||
echo "Length: ".$length."\n";
|
||||
|
||||
foreach ($nots AS $key=>$node) {
|
||||
echo "Key $key: ".$node->nodeName." (".$node->systemId.") (".$node->publicId.")\n";
|
||||
}
|
||||
print "\n";
|
||||
for($x=0; $x < $length; $x++) {
|
||||
echo "Index $x: ".$nots->item($x)->nodeName." (".$nots->item($x)->systemId.") (".$nots->item($x)->publicId.")\n";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
$node = $nots->getNamedItem('xxx');
|
||||
var_dump($node);
|
||||
|
||||
echo "\n";
|
||||
/* Entity Decl Tests */
|
||||
$ents = $dtd->entities;
|
||||
$length = $ents->length;
|
||||
echo "Length: ".$length."\n";
|
||||
foreach ($ents AS $key=>$node) {
|
||||
echo "Key: $key Name: ".$node->nodeName."\n";
|
||||
}
|
||||
echo "\n";
|
||||
for($x=0; $x < $length; $x++) {
|
||||
echo "Index $x: ".$ents->item($x)->nodeName."\n";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
$node = $ents->item(3);
|
||||
var_dump($node);
|
||||
$node = $ents->getNamedItem('xxx');
|
||||
var_dump($node);
|
||||
|
||||
|
||||
--EXPECT--
|
||||
Length: 1
|
||||
Key GIF: GIF (image/gif) (-)
|
||||
|
||||
Index 0: GIF (image/gif) (-)
|
||||
|
||||
NULL
|
||||
|
||||
Length: 3
|
||||
Key: test Name: test
|
||||
Key: rdf Name: rdf
|
||||
Key: myimage Name: myimage
|
||||
|
||||
Index 0: test
|
||||
Index 1: rdf
|
||||
Index 2: myimage
|
||||
|
||||
NULL
|
||||
NULL
|
||||
@@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
Bug #36697 (TrueColor transparency with GIF palette output).
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) {
|
||||
die("skip gd extension not available\n");
|
||||
}
|
||||
if (!GD_BUNDLED) {
|
||||
die('skip external GD libraries may fail');
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$dest = dirname(__FILE__) . "/36697.gif";
|
||||
|
||||
$im = imagecreatetruecolor(192, 36);
|
||||
$trans_color = imagecolorallocate($im, 255, 0, 0);
|
||||
$color = imagecolorallocate($im, 255, 255, 255);
|
||||
imagecolortransparent($im, $trans_color);
|
||||
imagefilledrectangle($im, 0,0, 192,36, $trans_color);
|
||||
$c = imagecolorat($im, 191,35);
|
||||
imagegif($im, $dest);
|
||||
imagedestroy($im);
|
||||
$im = imagecreatefromgif($dest);
|
||||
$c = imagecolorat($im, 191, 35);
|
||||
$colors = imagecolorsforindex($im, $c);
|
||||
echo $colors['red'] . ' ' . $colors['green'] . ' ' . $colors['blue'];
|
||||
@unlink($dest);
|
||||
?>
|
||||
--EXPECT--
|
||||
255 0 0
|
||||
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
bug #36420 (segfault when access result->num_rows after calling result->close())
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
include "connect.inc";
|
||||
$mysqli = mysqli_connect($host, $user, $passwd);
|
||||
|
||||
$result = $mysqli->query('select 1');
|
||||
|
||||
$result->close();
|
||||
echo $result->num_rows;
|
||||
|
||||
$mysqli->close();
|
||||
echo $result->num_rows;
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: main(): Couldn't fetch mysqli_result in %s on line %d
|
||||
|
||||
Warning: main(): Couldn't fetch mysqli_result in %s on line %d
|
||||
Done
|
||||
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
bug #36745 : LOAD DATA LOCAL INFILE doesn't return correct error message
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
include ("connect.inc");
|
||||
|
||||
/*** test mysqli_connect 127.0.0.1 ***/
|
||||
$mysql = mysqli_connect($host, $user, $passwd, "test");
|
||||
|
||||
$mysql->query("DROP TABLE IF EXISTS litest");
|
||||
$mysql->query("CREATE TABLE litest (a VARCHAR(20))");
|
||||
|
||||
$mysql->query("LOAD DATA LOCAL INFILE 'filenotfound' INTO TABLE litest");
|
||||
var_dump($mysql->error);
|
||||
|
||||
$mysql->close();
|
||||
printf("Done");
|
||||
?>
|
||||
--EXPECT--
|
||||
string(31) "Can't find file 'filenotfound'."
|
||||
Done
|
||||
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
bug #36802 : crashes with mysql_init
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class my_mysqli extends mysqli {
|
||||
function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
include "connect.inc";
|
||||
|
||||
|
||||
$mysql = mysqli_init();
|
||||
|
||||
/* following operations should not work */
|
||||
$x[0] = @$mysql->set_charset('utf8');
|
||||
$x[1] = @$mysql->query("SELECT 'foo' FROM DUAL");
|
||||
|
||||
/* following operations should work */
|
||||
$x[2] = ($mysql->client_version > 0);
|
||||
$x[3] = $mysql->errno;
|
||||
$mysql->close();
|
||||
|
||||
|
||||
|
||||
var_dump($x);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(4) {
|
||||
[0]=>
|
||||
NULL
|
||||
[1]=>
|
||||
NULL
|
||||
[2]=>
|
||||
bool(true)
|
||||
[3]=>
|
||||
int(0)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
bind LONG field
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require dirname(__FILE__)."/connect.inc";
|
||||
|
||||
$stmt = oci_parse($c, "create table phptestlng( id number(10), fileimage long)");
|
||||
oci_execute($stmt);
|
||||
|
||||
$stmt = oci_parse ($c, "insert into phptestlng (id, fileimage) values (:id, :fileimage)");
|
||||
$i=1;
|
||||
$fileimage = file_get_contents( dirname(__FILE__)."/test.gif");
|
||||
|
||||
oci_bind_by_name( $stmt, ":id", $i, -1);
|
||||
oci_bind_by_name( $stmt, ":fileimage", $fileimage, -1, SQLT_LNG);
|
||||
oci_execute($stmt, OCI_DEFAULT);
|
||||
oci_commit($c);
|
||||
|
||||
$stmt = oci_parse($c, "SELECT fileimage FROM phptestlng");
|
||||
oci_execute($stmt);
|
||||
|
||||
$row = oci_fetch_row($stmt);
|
||||
var_dump(md5($row[0]));
|
||||
var_dump(strlen($row[0]));
|
||||
|
||||
$stmt = oci_parse($c, "drop table phptestlng");
|
||||
oci_execute($stmt);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(32) "d04e7036e2f4221abc88fd14e960a45b"
|
||||
int(2523)
|
||||
Done
|
||||
@@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
bind LONG RAW field
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require dirname(__FILE__)."/connect.inc";
|
||||
|
||||
$stmt = oci_parse($c, "create table phptestlngraw( id number(10), fileimage long raw)");
|
||||
oci_execute($stmt);
|
||||
|
||||
$stmt = oci_parse ($c, "insert into phptestlngraw (id, fileimage) values (:id, :fileimage)");
|
||||
$i=1;
|
||||
$fileimage = file_get_contents( dirname(__FILE__)."/test.gif");
|
||||
|
||||
oci_bind_by_name( $stmt, ":id", $i, -1);
|
||||
oci_bind_by_name( $stmt, ":fileimage", $fileimage, -1, SQLT_LBI);
|
||||
oci_execute($stmt, OCI_DEFAULT);
|
||||
oci_commit($c);
|
||||
|
||||
$stmt = oci_parse($c, "SELECT fileimage FROM phptestlngraw");
|
||||
oci_execute($stmt);
|
||||
|
||||
$row = oci_fetch_row($stmt);
|
||||
var_dump(md5($row[0]));
|
||||
var_dump(strlen($row[0]));
|
||||
|
||||
$stmt = oci_parse($c, "drop table phptestlngraw");
|
||||
oci_execute($stmt);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(32) "614fcbba1effb7caa27ef0ef25c27fcf"
|
||||
int(2523)
|
||||
Done
|
||||
@@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
bind RAW field
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require dirname(__FILE__)."/connect.inc";
|
||||
|
||||
$stmt = oci_parse($c, "create table phptestrawtable( id number(10), fileimage raw(1000))");
|
||||
oci_execute($stmt);
|
||||
|
||||
$stmt = oci_parse ($c, "insert into phptestrawtable (id, fileimage) values (:id, :fileimage)");
|
||||
$i=1;
|
||||
$fileimage = file_get_contents( dirname(__FILE__)."/test.gif");
|
||||
$fileimage = substr($fileimage, 0, 300);
|
||||
|
||||
oci_bind_by_name( $stmt, ":id", $i, -1);
|
||||
oci_bind_by_name( $stmt, ":fileimage", $fileimage, -1, SQLT_BIN);
|
||||
oci_execute($stmt, OCI_DEFAULT);
|
||||
oci_commit($c);
|
||||
|
||||
$stmt = oci_parse($c, "SELECT fileimage FROM phptestrawtable");
|
||||
oci_execute($stmt);
|
||||
|
||||
$row = oci_fetch_row($stmt);
|
||||
var_dump(md5($row[0]));
|
||||
var_dump(strlen($row[0]));
|
||||
|
||||
$stmt = oci_parse($c, "drop table phptestrawtable");
|
||||
oci_execute($stmt);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(32) "88b274d7a257ac6f70435b83abd4e26e"
|
||||
int(300)
|
||||
Done
|
||||
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
bug #36010 (Crash when executing SQL statment with lob parameter twice)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require dirname(__FILE__).'/connect.inc';
|
||||
|
||||
function f($conn)
|
||||
{
|
||||
$sql = "begin :p_clob := 'lob string'; end;";
|
||||
$stid = oci_parse($conn, $sql);
|
||||
$clob = oci_new_descriptor($conn, OCI_D_LOB);
|
||||
oci_bind_by_name($stid, ":p_clob", $clob, -1, OCI_B_CLOB);
|
||||
$r = oci_execute($stid, OCI_DEFAULT);
|
||||
}
|
||||
|
||||
f($c);
|
||||
f($c);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
||||
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #36096 (oci_result() returns garbage after oci_fetch() failed)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require dirname(__FILE__)."/connect.inc";
|
||||
|
||||
$sql = "SELECT 'ABC' FROM DUAL WHERE 1<>1";
|
||||
$stmt = oci_parse($c, $sql);
|
||||
|
||||
if(oci_execute($stmt, OCI_COMMIT_ON_SUCCESS)){
|
||||
var_dump(oci_fetch($stmt));
|
||||
var_dump(oci_result($stmt, 1));
|
||||
var_dump(oci_field_name($stmt, 1));
|
||||
var_dump(oci_field_type($stmt, 1));
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(false)
|
||||
string(5) "'ABC'"
|
||||
string(4) "CHAR"
|
||||
Done
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,466 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2005 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains a PCRE private debugging function for printing out the
|
||||
internal form of a compiled regular expression, along with some supporting
|
||||
local functions. This source file is used in two places:
|
||||
|
||||
(1) It is #included by pcre_compile.c when it is compiled in debugging mode
|
||||
(DEBUG defined in pcre_internal.h). It is not included in production compiles.
|
||||
|
||||
(2) It is always #included by pcretest.c, which can be asked to print out a
|
||||
compiled regex for debugging purposes. */
|
||||
|
||||
|
||||
static const char *OP_names[] = { OP_NAME_LIST };
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Print single- or multi-byte character *
|
||||
*************************************************/
|
||||
|
||||
static int
|
||||
print_char(FILE *f, uschar *ptr, BOOL utf8)
|
||||
{
|
||||
int c = *ptr;
|
||||
|
||||
if (!utf8 || (c & 0xc0) != 0xc0)
|
||||
{
|
||||
if (isprint(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
int a = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
|
||||
int s = 6*a;
|
||||
c = (c & _pcre_utf8_table3[a]) << s;
|
||||
for (i = 1; i <= a; i++)
|
||||
{
|
||||
/* This is a check for malformed UTF-8; it should only occur if the sanity
|
||||
check has been turned off. Rather than swallow random bytes, just stop if
|
||||
we hit a bad one. Print it with \X instead of \x as an indication. */
|
||||
|
||||
if ((ptr[i] & 0xc0) != 0x80)
|
||||
{
|
||||
fprintf(f, "\\X{%x}", c);
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
/* The byte is OK */
|
||||
|
||||
s -= 6;
|
||||
c |= (ptr[i] & 0x3f) << s;
|
||||
}
|
||||
if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c);
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Find Unicode property name *
|
||||
*************************************************/
|
||||
|
||||
static const char *
|
||||
get_ucpname(int ptype, int pvalue)
|
||||
{
|
||||
#ifdef SUPPORT_UCP
|
||||
int i;
|
||||
for (i = _pcre_utt_size; i >= 0; i--)
|
||||
{
|
||||
if (ptype == _pcre_utt[i].type && pvalue == _pcre_utt[i].value) break;
|
||||
}
|
||||
return (i >= 0)? _pcre_utt[i].name : "??";
|
||||
#else
|
||||
ptype = ptype; /* Avoid compiler warning */
|
||||
pvalue = pvalue;
|
||||
return "??";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Print compiled regex *
|
||||
*************************************************/
|
||||
|
||||
/* Make this function work for a regex with integers either byte order.
|
||||
However, we assume that what we are passed is a compiled regex. */
|
||||
|
||||
static void
|
||||
pcre_printint(pcre *external_re, FILE *f)
|
||||
{
|
||||
real_pcre *re = (real_pcre *)external_re;
|
||||
uschar *codestart, *code;
|
||||
BOOL utf8;
|
||||
|
||||
unsigned int options = re->options;
|
||||
int offset = re->name_table_offset;
|
||||
int count = re->name_count;
|
||||
int size = re->name_entry_size;
|
||||
|
||||
if (re->magic_number != MAGIC_NUMBER)
|
||||
{
|
||||
offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff);
|
||||
count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff);
|
||||
size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff);
|
||||
options = ((options << 24) & 0xff000000) |
|
||||
((options << 8) & 0x00ff0000) |
|
||||
((options >> 8) & 0x0000ff00) |
|
||||
((options >> 24) & 0x000000ff);
|
||||
}
|
||||
|
||||
code = codestart = (uschar *)re + offset + count * size;
|
||||
utf8 = (options & PCRE_UTF8) != 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
uschar *ccode;
|
||||
int c;
|
||||
int extra = 0;
|
||||
|
||||
fprintf(f, "%3d ", (int)(code - codestart));
|
||||
|
||||
if (*code >= OP_BRA)
|
||||
{
|
||||
if (*code - OP_BRA > EXTRACT_BASIC_MAX)
|
||||
fprintf(f, "%3d Bra extra\n", GET(code, 1));
|
||||
else
|
||||
fprintf(f, "%3d Bra %d\n", GET(code, 1), *code - OP_BRA);
|
||||
code += _pcre_OP_lengths[OP_BRA];
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(*code)
|
||||
{
|
||||
case OP_END:
|
||||
fprintf(f, " %s\n", OP_names[*code]);
|
||||
fprintf(f, "------------------------------------------------------------------\n");
|
||||
return;
|
||||
|
||||
case OP_OPT:
|
||||
fprintf(f, " %.2x %s", code[1], OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_CHAR:
|
||||
{
|
||||
fprintf(f, " ");
|
||||
do
|
||||
{
|
||||
code++;
|
||||
code += 1 + print_char(f, code, utf8);
|
||||
}
|
||||
while (*code == OP_CHAR);
|
||||
fprintf(f, "\n");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_CHARNC:
|
||||
{
|
||||
fprintf(f, " NC ");
|
||||
do
|
||||
{
|
||||
code++;
|
||||
code += 1 + print_char(f, code, utf8);
|
||||
}
|
||||
while (*code == OP_CHARNC);
|
||||
fprintf(f, "\n");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_KETRMAX:
|
||||
case OP_KETRMIN:
|
||||
case OP_ALT:
|
||||
case OP_KET:
|
||||
case OP_ASSERT:
|
||||
case OP_ASSERT_NOT:
|
||||
case OP_ASSERTBACK:
|
||||
case OP_ASSERTBACK_NOT:
|
||||
case OP_ONCE:
|
||||
case OP_COND:
|
||||
case OP_REVERSE:
|
||||
fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_BRANUMBER:
|
||||
printf("%3d %s", GET2(code, 1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_CREF:
|
||||
if (GET2(code, 1) == CREF_RECURSE)
|
||||
fprintf(f, " Cond recurse");
|
||||
else
|
||||
fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_STAR:
|
||||
case OP_MINSTAR:
|
||||
case OP_PLUS:
|
||||
case OP_MINPLUS:
|
||||
case OP_QUERY:
|
||||
case OP_MINQUERY:
|
||||
case OP_TYPESTAR:
|
||||
case OP_TYPEMINSTAR:
|
||||
case OP_TYPEPLUS:
|
||||
case OP_TYPEMINPLUS:
|
||||
case OP_TYPEQUERY:
|
||||
case OP_TYPEMINQUERY:
|
||||
fprintf(f, " ");
|
||||
if (*code >= OP_TYPESTAR)
|
||||
{
|
||||
fprintf(f, "%s", OP_names[code[1]]);
|
||||
if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
|
||||
{
|
||||
fprintf(f, " %s ", get_ucpname(code[2], code[3]));
|
||||
extra = 2;
|
||||
}
|
||||
}
|
||||
else extra = print_char(f, code+1, utf8);
|
||||
fprintf(f, "%s", OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_EXACT:
|
||||
case OP_UPTO:
|
||||
case OP_MINUPTO:
|
||||
fprintf(f, " ");
|
||||
extra = print_char(f, code+3, utf8);
|
||||
fprintf(f, "{");
|
||||
if (*code != OP_EXACT) fprintf(f, ",");
|
||||
fprintf(f, "%d}", GET2(code,1));
|
||||
if (*code == OP_MINUPTO) fprintf(f, "?");
|
||||
break;
|
||||
|
||||
case OP_TYPEEXACT:
|
||||
case OP_TYPEUPTO:
|
||||
case OP_TYPEMINUPTO:
|
||||
fprintf(f, " %s", OP_names[code[3]]);
|
||||
if (code[3] == OP_PROP || code[3] == OP_NOTPROP)
|
||||
{
|
||||
fprintf(f, " %s ", get_ucpname(code[4], code[5]));
|
||||
extra = 2;
|
||||
}
|
||||
fprintf(f, "{");
|
||||
if (*code != OP_TYPEEXACT) fprintf(f, "0,");
|
||||
fprintf(f, "%d}", GET2(code,1));
|
||||
if (*code == OP_TYPEMINUPTO) fprintf(f, "?");
|
||||
break;
|
||||
|
||||
case OP_NOT:
|
||||
if (isprint(c = code[1])) fprintf(f, " [^%c]", c);
|
||||
else fprintf(f, " [^\\x%02x]", c);
|
||||
break;
|
||||
|
||||
case OP_NOTSTAR:
|
||||
case OP_NOTMINSTAR:
|
||||
case OP_NOTPLUS:
|
||||
case OP_NOTMINPLUS:
|
||||
case OP_NOTQUERY:
|
||||
case OP_NOTMINQUERY:
|
||||
if (isprint(c = code[1])) fprintf(f, " [^%c]", c);
|
||||
else fprintf(f, " [^\\x%02x]", c);
|
||||
fprintf(f, "%s", OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_NOTEXACT:
|
||||
case OP_NOTUPTO:
|
||||
case OP_NOTMINUPTO:
|
||||
if (isprint(c = code[3])) fprintf(f, " [^%c]{", c);
|
||||
else fprintf(f, " [^\\x%02x]{", c);
|
||||
if (*code != OP_NOTEXACT) fprintf(f, "0,");
|
||||
fprintf(f, "%d}", GET2(code,1));
|
||||
if (*code == OP_NOTMINUPTO) fprintf(f, "?");
|
||||
break;
|
||||
|
||||
case OP_RECURSE:
|
||||
fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_REF:
|
||||
fprintf(f, " \\%d", GET2(code,1));
|
||||
ccode = code + _pcre_OP_lengths[*code];
|
||||
goto CLASS_REF_REPEAT;
|
||||
|
||||
case OP_CALLOUT:
|
||||
fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2),
|
||||
GET(code, 2 + LINK_SIZE));
|
||||
break;
|
||||
|
||||
case OP_PROP:
|
||||
case OP_NOTPROP:
|
||||
fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1], code[2]));
|
||||
break;
|
||||
|
||||
/* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in
|
||||
having this code always here, and it makes it less messy without all those
|
||||
#ifdefs. */
|
||||
|
||||
case OP_CLASS:
|
||||
case OP_NCLASS:
|
||||
case OP_XCLASS:
|
||||
{
|
||||
int i, min, max;
|
||||
BOOL printmap;
|
||||
|
||||
fprintf(f, " [");
|
||||
|
||||
if (*code == OP_XCLASS)
|
||||
{
|
||||
extra = GET(code, 1);
|
||||
ccode = code + LINK_SIZE + 1;
|
||||
printmap = (*ccode & XCL_MAP) != 0;
|
||||
if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^");
|
||||
}
|
||||
else
|
||||
{
|
||||
printmap = TRUE;
|
||||
ccode = code + 1;
|
||||
}
|
||||
|
||||
/* Print a bit map */
|
||||
|
||||
if (printmap)
|
||||
{
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if ((ccode[i/8] & (1 << (i&7))) != 0)
|
||||
{
|
||||
int j;
|
||||
for (j = i+1; j < 256; j++)
|
||||
if ((ccode[j/8] & (1 << (j&7))) == 0) break;
|
||||
if (i == '-' || i == ']') fprintf(f, "\\");
|
||||
if (isprint(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i);
|
||||
if (--j > i)
|
||||
{
|
||||
if (j != i + 1) fprintf(f, "-");
|
||||
if (j == '-' || j == ']') fprintf(f, "\\");
|
||||
if (isprint(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j);
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
ccode += 32;
|
||||
}
|
||||
|
||||
/* For an XCLASS there is always some additional data */
|
||||
|
||||
if (*code == OP_XCLASS)
|
||||
{
|
||||
int ch;
|
||||
while ((ch = *ccode++) != XCL_END)
|
||||
{
|
||||
if (ch == XCL_PROP)
|
||||
{
|
||||
int ptype = *ccode++;
|
||||
int pvalue = *ccode++;
|
||||
fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
|
||||
}
|
||||
else if (ch == XCL_NOTPROP)
|
||||
{
|
||||
int ptype = *ccode++;
|
||||
int pvalue = *ccode++;
|
||||
fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
|
||||
}
|
||||
else
|
||||
{
|
||||
ccode += 1 + print_char(f, ccode, TRUE);
|
||||
if (ch == XCL_RANGE)
|
||||
{
|
||||
fprintf(f, "-");
|
||||
ccode += 1 + print_char(f, ccode, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Indicate a non-UTF8 class which was created by negation */
|
||||
|
||||
fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : "");
|
||||
|
||||
/* Handle repeats after a class or a back reference */
|
||||
|
||||
CLASS_REF_REPEAT:
|
||||
switch(*ccode)
|
||||
{
|
||||
case OP_CRSTAR:
|
||||
case OP_CRMINSTAR:
|
||||
case OP_CRPLUS:
|
||||
case OP_CRMINPLUS:
|
||||
case OP_CRQUERY:
|
||||
case OP_CRMINQUERY:
|
||||
fprintf(f, "%s", OP_names[*ccode]);
|
||||
extra += _pcre_OP_lengths[*ccode];
|
||||
break;
|
||||
|
||||
case OP_CRRANGE:
|
||||
case OP_CRMINRANGE:
|
||||
min = GET2(ccode,1);
|
||||
max = GET2(ccode,3);
|
||||
if (max == 0) fprintf(f, "{%d,}", min);
|
||||
else fprintf(f, "{%d,%d}", min, max);
|
||||
if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
|
||||
extra += _pcre_OP_lengths[*ccode];
|
||||
break;
|
||||
|
||||
/* Do nothing if it's not a repeat; this code stops picky compilers
|
||||
warning about the lack of a default code path. */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Anything else is just an item with no data*/
|
||||
|
||||
default:
|
||||
fprintf(f, " %s", OP_names[*code]);
|
||||
break;
|
||||
}
|
||||
|
||||
code += _pcre_OP_lengths[*code] + extra;
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* End of pcre_printint.src */
|
||||
@@ -0,0 +1,175 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2006 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains code for searching the table of Unicode character
|
||||
properties. */
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
#include "ucp.h" /* Category definitions */
|
||||
#include "ucpinternal.h" /* Internal table details */
|
||||
#include "ucptable.c" /* The table itself */
|
||||
|
||||
|
||||
/* Table to translate from particular type value to the general value. */
|
||||
|
||||
static int ucp_gentype[] = {
|
||||
ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
|
||||
ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
|
||||
ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
|
||||
ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
|
||||
ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
|
||||
ucp_P, ucp_P, /* Ps, Po */
|
||||
ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
|
||||
ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Search table and return type *
|
||||
*************************************************/
|
||||
|
||||
/* Three values are returned: the category is ucp_C, ucp_L, etc. The detailed
|
||||
character type is ucp_Lu, ucp_Nd, etc. The script is ucp_Latin, etc.
|
||||
|
||||
Arguments:
|
||||
c the character value
|
||||
type_ptr the detailed character type is returned here
|
||||
script_ptr the script is returned here
|
||||
|
||||
Returns: the character type category
|
||||
*/
|
||||
|
||||
int
|
||||
_pcre_ucp_findprop(const int c, int *type_ptr, int *script_ptr)
|
||||
{
|
||||
int bot = 0;
|
||||
int top = sizeof(ucp_table)/sizeof(cnode);
|
||||
int mid;
|
||||
|
||||
/* The table is searched using a binary chop. You might think that using
|
||||
intermediate variables to hold some of the common expressions would speed
|
||||
things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
|
||||
makes things a lot slower. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (top <= bot)
|
||||
{
|
||||
*type_ptr = ucp_Cn;
|
||||
*script_ptr = ucp_Common;
|
||||
return ucp_C;
|
||||
}
|
||||
mid = (bot + top) >> 1;
|
||||
if (c == (ucp_table[mid].f0 & f0_charmask)) break;
|
||||
if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
|
||||
else
|
||||
{
|
||||
if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
|
||||
c <= (ucp_table[mid].f0 & f0_charmask) +
|
||||
(ucp_table[mid].f1 & f1_rangemask)) break;
|
||||
bot = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found an entry in the table. Set the script and detailed type values, and
|
||||
return the general type. */
|
||||
|
||||
*script_ptr = (ucp_table[mid].f0 & f0_scriptmask) >> f0_scriptshift;
|
||||
*type_ptr = (ucp_table[mid].f1 & f1_typemask) >> f1_typeshift;
|
||||
|
||||
return ucp_gentype[*type_ptr];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Search table and return other case *
|
||||
*************************************************/
|
||||
|
||||
/* If the given character is a letter, and there is another case for the
|
||||
letter, return the other case. Otherwise, return -1.
|
||||
|
||||
Arguments:
|
||||
c the character value
|
||||
|
||||
Returns: the other case or -1 if none
|
||||
*/
|
||||
|
||||
int
|
||||
_pcre_ucp_othercase(const int c)
|
||||
{
|
||||
int bot = 0;
|
||||
int top = sizeof(ucp_table)/sizeof(cnode);
|
||||
int mid, offset;
|
||||
|
||||
/* The table is searched using a binary chop. You might think that using
|
||||
intermediate variables to hold some of the common expressions would speed
|
||||
things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
|
||||
makes things a lot slower. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (top <= bot) return -1;
|
||||
mid = (bot + top) >> 1;
|
||||
if (c == (ucp_table[mid].f0 & f0_charmask)) break;
|
||||
if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
|
||||
else
|
||||
{
|
||||
if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
|
||||
c <= (ucp_table[mid].f0 & f0_charmask) +
|
||||
(ucp_table[mid].f1 & f1_rangemask)) break;
|
||||
bot = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found an entry in the table. Return -1 for a range entry. Otherwise return
|
||||
the other case if there is one, else -1. */
|
||||
|
||||
if ((ucp_table[mid].f0 & f0_rangeflag) != 0) return -1;
|
||||
|
||||
offset = ucp_table[mid].f1 & f1_casemask;
|
||||
if ((offset & f1_caseneg) != 0) offset |= f1_caseneg;
|
||||
return (offset == 0)? -1 : c + offset;
|
||||
}
|
||||
|
||||
|
||||
/* End of pcre_ucp_searchfuncs.c */
|
||||
@@ -0,0 +1,171 @@
|
||||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: Sanjay Ghemawat
|
||||
|
||||
#ifndef _PCRECPPARG_H
|
||||
#define _PCRECPPARG_H
|
||||
|
||||
#include <stdlib.h> // for NULL
|
||||
#include <string>
|
||||
|
||||
namespace pcrecpp {
|
||||
|
||||
class StringPiece;
|
||||
|
||||
// Hex/Octal/Binary?
|
||||
|
||||
// Special class for parsing into objects that define a ParseFrom() method
|
||||
template <class T>
|
||||
class _RE_MatchObject {
|
||||
public:
|
||||
static inline bool Parse(const char* str, int n, void* dest) {
|
||||
T* object = reinterpret_cast<T*>(dest);
|
||||
return object->ParseFrom(str, n);
|
||||
}
|
||||
};
|
||||
|
||||
class Arg {
|
||||
public:
|
||||
// Empty constructor so we can declare arrays of Arg
|
||||
Arg();
|
||||
|
||||
// Constructor specially designed for NULL arguments
|
||||
Arg(void*);
|
||||
|
||||
typedef bool (*Parser)(const char* str, int n, void* dest);
|
||||
|
||||
// Type-specific parsers
|
||||
#define PCRE_MAKE_PARSER(type,name) \
|
||||
Arg(type* p) : arg_(p), parser_(name) { } \
|
||||
Arg(type* p, Parser parser) : arg_(p), parser_(parser) { }
|
||||
|
||||
|
||||
PCRE_MAKE_PARSER(char, parse_char);
|
||||
PCRE_MAKE_PARSER(unsigned char, parse_uchar);
|
||||
PCRE_MAKE_PARSER(short, parse_short);
|
||||
PCRE_MAKE_PARSER(unsigned short, parse_ushort);
|
||||
PCRE_MAKE_PARSER(int, parse_int);
|
||||
PCRE_MAKE_PARSER(unsigned int, parse_uint);
|
||||
PCRE_MAKE_PARSER(long, parse_long);
|
||||
PCRE_MAKE_PARSER(unsigned long, parse_ulong);
|
||||
#if 1
|
||||
PCRE_MAKE_PARSER(long long, parse_longlong);
|
||||
#endif
|
||||
#if 1
|
||||
PCRE_MAKE_PARSER(unsigned long long, parse_ulonglong);
|
||||
#endif
|
||||
PCRE_MAKE_PARSER(float, parse_float);
|
||||
PCRE_MAKE_PARSER(double, parse_double);
|
||||
PCRE_MAKE_PARSER(std::string, parse_string);
|
||||
PCRE_MAKE_PARSER(StringPiece, parse_stringpiece);
|
||||
|
||||
#undef PCRE_MAKE_PARSER
|
||||
|
||||
// Generic constructor
|
||||
template <class T> Arg(T*, Parser parser);
|
||||
// Generic constructor template
|
||||
template <class T> Arg(T* p)
|
||||
: arg_(p), parser_(_RE_MatchObject<T>::Parse) {
|
||||
}
|
||||
|
||||
// Parse the data
|
||||
bool Parse(const char* str, int n) const;
|
||||
|
||||
private:
|
||||
void* arg_;
|
||||
Parser parser_;
|
||||
|
||||
static bool parse_null (const char* str, int n, void* dest);
|
||||
static bool parse_char (const char* str, int n, void* dest);
|
||||
static bool parse_uchar (const char* str, int n, void* dest);
|
||||
static bool parse_float (const char* str, int n, void* dest);
|
||||
static bool parse_double (const char* str, int n, void* dest);
|
||||
static bool parse_string (const char* str, int n, void* dest);
|
||||
static bool parse_stringpiece (const char* str, int n, void* dest);
|
||||
|
||||
#define PCRE_DECLARE_INTEGER_PARSER(name) \
|
||||
private: \
|
||||
static bool parse_ ## name(const char* str, int n, void* dest); \
|
||||
static bool parse_ ## name ## _radix( \
|
||||
const char* str, int n, void* dest, int radix); \
|
||||
public: \
|
||||
static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \
|
||||
static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \
|
||||
static bool parse_ ## name ## _cradix(const char* str, int n, void* dest)
|
||||
|
||||
PCRE_DECLARE_INTEGER_PARSER(short);
|
||||
PCRE_DECLARE_INTEGER_PARSER(ushort);
|
||||
PCRE_DECLARE_INTEGER_PARSER(int);
|
||||
PCRE_DECLARE_INTEGER_PARSER(uint);
|
||||
PCRE_DECLARE_INTEGER_PARSER(long);
|
||||
PCRE_DECLARE_INTEGER_PARSER(ulong);
|
||||
PCRE_DECLARE_INTEGER_PARSER(longlong);
|
||||
PCRE_DECLARE_INTEGER_PARSER(ulonglong);
|
||||
|
||||
#undef PCRE_DECLARE_INTEGER_PARSER
|
||||
};
|
||||
|
||||
inline Arg::Arg() : arg_(NULL), parser_(parse_null) { }
|
||||
inline Arg::Arg(void* p) : arg_(p), parser_(parse_null) { }
|
||||
|
||||
inline bool Arg::Parse(const char* str, int n) const {
|
||||
return (*parser_)(str, n, arg_);
|
||||
}
|
||||
|
||||
// This part of the parser, appropriate only for ints, deals with bases
|
||||
#define MAKE_INTEGER_PARSER(type, name) \
|
||||
inline Arg Hex(type* ptr) { \
|
||||
return Arg(ptr, Arg::parse_ ## name ## _hex); } \
|
||||
inline Arg Octal(type* ptr) { \
|
||||
return Arg(ptr, Arg::parse_ ## name ## _octal); } \
|
||||
inline Arg CRadix(type* ptr) { \
|
||||
return Arg(ptr, Arg::parse_ ## name ## _cradix); }
|
||||
|
||||
MAKE_INTEGER_PARSER(short, short);
|
||||
MAKE_INTEGER_PARSER(unsigned short, ushort);
|
||||
MAKE_INTEGER_PARSER(int, int);
|
||||
MAKE_INTEGER_PARSER(unsigned int, uint);
|
||||
MAKE_INTEGER_PARSER(long, long);
|
||||
MAKE_INTEGER_PARSER(unsigned long, ulong);
|
||||
#if 1
|
||||
MAKE_INTEGER_PARSER(long long, longlong);
|
||||
#endif
|
||||
#if 1
|
||||
MAKE_INTEGER_PARSER(unsigned long long, ulonglong);
|
||||
#endif
|
||||
|
||||
#undef PCRE_IS_SET
|
||||
#undef PCRE_SET_OR_CLEAR
|
||||
#undef MAKE_INTEGER_PARSER
|
||||
|
||||
} // namespace pcrecpp
|
||||
|
||||
|
||||
#endif /* _PCRECPPARG_H */
|
||||
@@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
PDO Common: PHP Bug #35671: binding by name breakage
|
||||
--SKIPIF--
|
||||
<?php # vim:ft=php
|
||||
if (!extension_loaded('pdo')) die('skip');
|
||||
$dir = getenv('REDIR_TEST_DIR');
|
||||
if (false == $dir) die('skip no driver');
|
||||
require_once $dir . 'pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/');
|
||||
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
|
||||
$db = PDOTest::factory();
|
||||
|
||||
$db->exec('CREATE TABLE test (field1 VARCHAR(32), field2 VARCHAR(32), field3 VARCHAR(32))');
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$insert = $db->prepare("insert into test (field1, field2, field3) values (:value1, :value2, :value3)");
|
||||
|
||||
$parm = array(
|
||||
":value1" => 15,
|
||||
":value2" => 20,
|
||||
":value3" => 25
|
||||
);
|
||||
|
||||
$insert->execute($parm);
|
||||
$insert = null;
|
||||
|
||||
var_dump($db->query("SELECT * from test")->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
array(3) {
|
||||
["field1"]=>
|
||||
string(2) "15"
|
||||
["field2"]=>
|
||||
string(2) "20"
|
||||
["field3"]=>
|
||||
string(2) "25"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #36727 (segfault in bindValue() when no parameters are defined)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM child');
|
||||
var_dump($stmt->bindValue(':test', 1, PDO::PARAM_INT));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
Done
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
--TEST--
|
||||
Bug #36625 (pg_trace() does not work)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require_once('config.inc');
|
||||
|
||||
$dbh = @pg_connect($conn_str);
|
||||
if (!$dbh) {
|
||||
die ('Could not connect to the server');
|
||||
}
|
||||
|
||||
$tracefile = dirname(__FILE__) . '/trace.tmp';
|
||||
|
||||
@unlink($tracefile);
|
||||
var_dump(file_exists($tracefile));
|
||||
|
||||
pg_trace($tracefile, 'w', $dbh);
|
||||
$res = pg_query($dbh, 'select 1');
|
||||
var_dump($res);
|
||||
pg_close($dbh);
|
||||
|
||||
$found = 0;
|
||||
function search_trace_file($line)
|
||||
{
|
||||
if (strpos($line, '"select 1"') !== false || strpos($line, "'select 1'") !== false) {
|
||||
$GLOBALS['found']++;
|
||||
}
|
||||
}
|
||||
|
||||
$trace = file($tracefile);
|
||||
array_walk($trace, 'search_trace_file');
|
||||
var_dump($found > 0);
|
||||
var_dump(file_exists($tracefile));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--CLEAN--
|
||||
<?php unlink($tracefile); ?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
resource(%d) of type (pgsql result)
|
||||
bool(true)
|
||||
bool(true)
|
||||
===DONE===
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
--TEST--
|
||||
ReflectionClass::newInstance[Args]
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('reflection') or die('skip'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test($class)
|
||||
{
|
||||
echo "====>$class\n";
|
||||
try
|
||||
{
|
||||
$ref = new ReflectionClass($class);
|
||||
}
|
||||
catch (ReflectionException $e)
|
||||
{
|
||||
var_dump($e->getMessage());
|
||||
return; // only here
|
||||
}
|
||||
|
||||
echo "====>newInstance()\n";
|
||||
try
|
||||
{
|
||||
var_dump($ref->newInstance());
|
||||
}
|
||||
catch (ReflectionException $e)
|
||||
{
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
echo "====>newInstance(25)\n";
|
||||
try
|
||||
{
|
||||
var_dump($ref->newInstance(25));
|
||||
}
|
||||
catch (ReflectionException $e)
|
||||
{
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
echo "====>newInstance(25, 42)\n";
|
||||
try
|
||||
{
|
||||
var_dump($ref->newInstance(25, 42));
|
||||
}
|
||||
catch (ReflectionException $e)
|
||||
{
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function __autoload($class)
|
||||
{
|
||||
echo __FUNCTION__ . "($class)\n";
|
||||
}
|
||||
|
||||
test('Class_does_not_exist');
|
||||
|
||||
Class NoCtor
|
||||
{
|
||||
}
|
||||
|
||||
test('NoCtor');
|
||||
|
||||
Class WithCtor
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
}
|
||||
|
||||
test('WithCtor');
|
||||
|
||||
Class WithCtorWithArgs
|
||||
{
|
||||
function __construct($arg)
|
||||
{
|
||||
echo __METHOD__ . "($arg)\n";
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
}
|
||||
|
||||
test('WithCtorWithArgs');
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
|
||||
====>Class_does_not_exist
|
||||
__autoload(Class_does_not_exist)
|
||||
string(41) "Class Class_does_not_exist does not exist"
|
||||
====>NoCtor
|
||||
====>newInstance()
|
||||
object(NoCtor)#%d (0) {
|
||||
}
|
||||
====>newInstance(25)
|
||||
string(86) "Class NoCtor does not have a constructor, so you cannot pass any constructor arguments"
|
||||
====>newInstance(25, 42)
|
||||
string(86) "Class NoCtor does not have a constructor, so you cannot pass any constructor arguments"
|
||||
|
||||
====>WithCtor
|
||||
====>newInstance()
|
||||
WithCtor::__construct()
|
||||
array(0) {
|
||||
}
|
||||
object(WithCtor)#%d (0) {
|
||||
}
|
||||
====>newInstance(25)
|
||||
WithCtor::__construct()
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(25)
|
||||
}
|
||||
object(WithCtor)#%d (0) {
|
||||
}
|
||||
====>newInstance(25, 42)
|
||||
WithCtor::__construct()
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(25)
|
||||
[1]=>
|
||||
int(42)
|
||||
}
|
||||
object(WithCtor)#%d (0) {
|
||||
}
|
||||
|
||||
====>WithCtorWithArgs
|
||||
====>newInstance()
|
||||
|
||||
Warning: Missing argument 1 for WithCtorWithArgs::__construct() in %s007.php on line %d
|
||||
|
||||
Notice: Undefined variable: arg in %s007.php on line %d
|
||||
WithCtorWithArgs::__construct()
|
||||
array(0) {
|
||||
}
|
||||
object(WithCtorWithArgs)#%d (0) {
|
||||
}
|
||||
====>newInstance(25)
|
||||
WithCtorWithArgs::__construct(25)
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(25)
|
||||
}
|
||||
object(WithCtorWithArgs)#%d (0) {
|
||||
}
|
||||
====>newInstance(25, 42)
|
||||
WithCtorWithArgs::__construct(25)
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(25)
|
||||
[1]=>
|
||||
int(42)
|
||||
}
|
||||
object(WithCtorWithArgs)#%d (0) {
|
||||
}
|
||||
|
||||
===DONE===
|
||||
@@ -0,0 +1,41 @@
|
||||
--TEST--
|
||||
Reflection Bug #29986 (Class constants won't work with predefined constants when using ReflectionClass)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('reflection') or die('skip'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class just_constants
|
||||
{
|
||||
const BOOLEAN_CONSTANT = true;
|
||||
const NULL_CONSTANT = null;
|
||||
const STRING_CONSTANT = 'This is a string';
|
||||
const INTEGER_CONSTANT = 1000;
|
||||
const FLOAT_CONSTANT = 3.14159265;
|
||||
}
|
||||
|
||||
Reflection::export(new ReflectionClass('just_constants'));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Class [ <user> class just_constants ] {
|
||||
@@ %s
|
||||
|
||||
- Constants [5] {
|
||||
Constant [ boolean BOOLEAN_CONSTANT ] { }
|
||||
Constant [ null NULL_CONSTANT ] { }
|
||||
Constant [ string STRING_CONSTANT ] { }
|
||||
Constant [ integer INTEGER_CONSTANT ] { }
|
||||
Constant [ double FLOAT_CONSTANT ] { }
|
||||
}
|
||||
|
||||
- Static properties [0] {
|
||||
}
|
||||
|
||||
- Static methods [0] {
|
||||
}
|
||||
|
||||
- Properties [0] {
|
||||
}
|
||||
|
||||
- Methods [0] {
|
||||
}
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
Reflection Bug #36308 (ReflectionProperty::getDocComment() does not reflect extended class commentary)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('reflection') or die('skip'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class Base {
|
||||
/** Base comment block */
|
||||
public $foo = 'bar';
|
||||
}
|
||||
|
||||
class Extended extends Base {
|
||||
/** Extended commentary */
|
||||
public $foo = 'zim';
|
||||
}
|
||||
|
||||
$reflect = new ReflectionClass('Extended');
|
||||
$props = $reflect->getProperties();
|
||||
echo $props[0]->getDocComment();
|
||||
?>
|
||||
--EXPECT--
|
||||
/** Extended commentary */
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Reflection Bug #36337 (ReflectionProperty fails to return correct visibility)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('reflection') or die('skip'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
abstract class enum {
|
||||
protected $_values;
|
||||
|
||||
public function __construct() {
|
||||
$property = new ReflectionProperty(get_class($this),'_values');
|
||||
var_dump($property->isProtected());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final class myEnum extends enum {
|
||||
public $_values = array(
|
||||
0 => 'No value',
|
||||
);
|
||||
}
|
||||
|
||||
$x = new myEnum();
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
Done
|
||||
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Reflection Bug #36434 (Properties from parent class fail to indetify their true origin)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('reflection') or die('skip'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class ancester
|
||||
{
|
||||
public $ancester = 0;
|
||||
function ancester()
|
||||
{
|
||||
return $this->ancester;
|
||||
}
|
||||
}
|
||||
class foo extends ancester
|
||||
{
|
||||
public $bar = "1";
|
||||
function foo()
|
||||
{
|
||||
return $this->bar;
|
||||
}
|
||||
}
|
||||
|
||||
$r = new ReflectionClass('foo');
|
||||
foreach ($r->GetProperties() as $p)
|
||||
{
|
||||
echo $p->getName(). " ". $p->getDeclaringClass()->getName()."\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bar foo
|
||||
ancester ancester
|
||||
Executable
+209
@@ -0,0 +1,209 @@
|
||||
--TEST--
|
||||
ReflectionParameter::getClass(), getDeclaringClass(), getDeclaringFunction()
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('reflection') or die('skip'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test($nix, Array $ar, &$ref, stdClass $std, NonExistingClass $na, stdClass &$opt = NULL, $def = "FooBar")
|
||||
{
|
||||
}
|
||||
|
||||
class test
|
||||
{
|
||||
function test($nix, Array $ar, &$ref, stdClass $std, NonExistingClass $na, stdClass $opt = NULL, $def = "FooBar")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function check_params_decl_func($r, $f)
|
||||
{
|
||||
$c = $r->$f();
|
||||
echo $f . ': ' . ($c ? ($c instanceof ReflectionMethod ? $c->class . '::' : '') . $c->name : 'NULL') . "()\n";
|
||||
}
|
||||
|
||||
function check_params_decl_class($r, $f)
|
||||
{
|
||||
$c = $r->$f();
|
||||
echo $f . ': ' . ($c ? $c->name : 'NULL') . "\n";
|
||||
}
|
||||
|
||||
function check_params_func($r, $f)
|
||||
{
|
||||
echo $f . ': ';
|
||||
$v = $r->$f();
|
||||
var_dump($v);
|
||||
}
|
||||
|
||||
function check_params($r)
|
||||
{
|
||||
echo "#####" . ($r instanceof ReflectionMethod ? $r->class . '::' : '') . $r->name . "()#####\n";
|
||||
$i = 0;
|
||||
foreach($r->getParameters() as $p)
|
||||
{
|
||||
echo "===" . $i . "===\n";
|
||||
$i++;
|
||||
check_params_func($p, 'getName');
|
||||
check_params_func($p, 'isPassedByReference');
|
||||
try
|
||||
{
|
||||
check_params_decl_class($p, 'getClass');
|
||||
}
|
||||
catch(ReflectionException $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
check_params_decl_class($p, 'getDeclaringClass');
|
||||
// check_params_decl_func($p, 'getDeclaringFunction');
|
||||
check_params_func($p, 'isArray');
|
||||
check_params_func($p, 'allowsNull');
|
||||
check_params_func($p, 'isOptional');
|
||||
check_params_func($p, 'isDefaultValueAvailable');
|
||||
if ($p->isOptional())
|
||||
{
|
||||
check_params_func($p, 'getDefaultValue');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check_params(new ReflectionFunction('test'));
|
||||
|
||||
check_params(new ReflectionMethod('test::test'));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
#####test()#####
|
||||
===0===
|
||||
getName: string(3) "nix"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: NULL
|
||||
getDeclaringClass: NULL
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===1===
|
||||
getName: string(2) "ar"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: NULL
|
||||
getDeclaringClass: NULL
|
||||
isArray: bool(true)
|
||||
allowsNull: bool(false)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===2===
|
||||
getName: string(3) "ref"
|
||||
isPassedByReference: bool(true)
|
||||
getClass: NULL
|
||||
getDeclaringClass: NULL
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===3===
|
||||
getName: string(3) "std"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: stdClass
|
||||
getDeclaringClass: NULL
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(false)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===4===
|
||||
getName: string(2) "na"
|
||||
isPassedByReference: bool(false)
|
||||
Class NonExistingClass does not exist
|
||||
getDeclaringClass: NULL
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(false)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===5===
|
||||
getName: string(3) "opt"
|
||||
isPassedByReference: bool(true)
|
||||
getClass: stdClass
|
||||
getDeclaringClass: NULL
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(true)
|
||||
isDefaultValueAvailable: bool(true)
|
||||
getDefaultValue: NULL
|
||||
===6===
|
||||
getName: string(3) "def"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: NULL
|
||||
getDeclaringClass: NULL
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(true)
|
||||
isDefaultValueAvailable: bool(true)
|
||||
getDefaultValue: string(6) "FooBar"
|
||||
#####test::test()#####
|
||||
===0===
|
||||
getName: string(3) "nix"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: NULL
|
||||
getDeclaringClass: test
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===1===
|
||||
getName: string(2) "ar"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: NULL
|
||||
getDeclaringClass: test
|
||||
isArray: bool(true)
|
||||
allowsNull: bool(false)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===2===
|
||||
getName: string(3) "ref"
|
||||
isPassedByReference: bool(true)
|
||||
getClass: NULL
|
||||
getDeclaringClass: test
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===3===
|
||||
getName: string(3) "std"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: stdClass
|
||||
getDeclaringClass: test
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(false)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===4===
|
||||
getName: string(2) "na"
|
||||
isPassedByReference: bool(false)
|
||||
Class NonExistingClass does not exist
|
||||
getDeclaringClass: test
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(false)
|
||||
isOptional: bool(false)
|
||||
isDefaultValueAvailable: bool(false)
|
||||
===5===
|
||||
getName: string(3) "opt"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: stdClass
|
||||
getDeclaringClass: test
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(true)
|
||||
isDefaultValueAvailable: bool(true)
|
||||
getDefaultValue: NULL
|
||||
===6===
|
||||
getName: string(3) "def"
|
||||
isPassedByReference: bool(false)
|
||||
getClass: NULL
|
||||
getDeclaringClass: test
|
||||
isArray: bool(false)
|
||||
allowsNull: bool(true)
|
||||
isOptional: bool(true)
|
||||
isDefaultValueAvailable: bool(true)
|
||||
getDefaultValue: string(6) "FooBar"
|
||||
===DONE===
|
||||
@@ -0,0 +1,41 @@
|
||||
--TEST--
|
||||
bug #31454 (Incorrect adding PHPSESSID to links, which contains \r\n)
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
error_reporting(E_ALL);
|
||||
|
||||
ini_set('session.use_trans_sid', 1);
|
||||
ini_set('session.use_cookies', 0);
|
||||
ini_set('session.name', 'sid');
|
||||
|
||||
session_start();
|
||||
|
||||
# Do not remove \r from this tests, they are essential!
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug #36459 Incorrect adding PHPSESSID to links, which contains \r\n</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>See source html code</p>
|
||||
<a href="/b2w/www/ru/adm/pages/?action=prev&rec_id=8&pid=2"
|
||||
style="font: normal 11pt Times New Roman">incorrect link</a><br />
|
||||
<br />
|
||||
<a href="/b2w/www/ru/adm/pages/?action=prev&rec_id=8&pid=2" style="font: normal 11pt Times New Roman">correct link</a>
|
||||
</body>
|
||||
</html>
|
||||
--EXPECTF--
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug #36459 Incorrect adding PHPSESSID to links, which contains \r\n</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>See source html code</p>
|
||||
<a href="/b2w/www/ru/adm/pages/?action=prev&rec_id=8&pid=2&sid=%s"
|
||||
style="font: normal 11pt Times New Roman">incorrect link</a><br />
|
||||
<br />
|
||||
<a href="/b2w/www/ru/adm/pages/?action=prev&rec_id=8&pid=2&sid=%s" style="font: normal 11pt Times New Roman">correct link</a>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
SimpleXML: foreach
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$sxe = simplexml_load_string(<<<EOF
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE sxe SYSTEM "notfound.dtd">
|
||||
<sxe id="elem1">
|
||||
Plain text.
|
||||
<elem1 attr1='first'>Bla bla 1.<!-- comment --><elem2>
|
||||
Here we have some text data.
|
||||
</elem2></elem1>
|
||||
<elem11 attr2='second'>Bla bla 2.</elem11>
|
||||
</sxe>
|
||||
EOF
|
||||
);
|
||||
var_dump($sxe->children());
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
object(SimpleXMLElement)#%d (3) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["id"]=>
|
||||
string(5) "elem1"
|
||||
}
|
||||
["elem1"]=>
|
||||
string(10) "Bla bla 1."
|
||||
["elem11"]=>
|
||||
string(10) "Bla bla 2."
|
||||
}
|
||||
===DONE===
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
SimpleXML: getName()
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml =<<<EOF
|
||||
<people>
|
||||
<person>Jane</person>
|
||||
</people>
|
||||
EOF;
|
||||
|
||||
function traverse_xml($xml, $pad = '')
|
||||
{
|
||||
$name = $xml->getName();
|
||||
echo "$pad<$name";
|
||||
foreach($xml->attributes() as $attr => $value)
|
||||
{
|
||||
echo " $attr=\"$value\"";
|
||||
}
|
||||
echo ">" . trim($xml) . "\n";
|
||||
foreach($xml->children() as $node)
|
||||
{
|
||||
traverse_xml($node, $pad.' ');
|
||||
}
|
||||
echo $pad."</$name>\n";
|
||||
}
|
||||
|
||||
|
||||
$people = simplexml_load_string($xml);
|
||||
traverse_xml($people);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
<people>
|
||||
<person>Jane
|
||||
</person>
|
||||
</people>
|
||||
===DONE===
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
--TEST--
|
||||
SimpleXML: Adding an elements
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml =<<<EOF
|
||||
<people></people>
|
||||
EOF;
|
||||
|
||||
function traverse_xml($xml, $pad = '')
|
||||
{
|
||||
$name = $xml->getName();
|
||||
echo "$pad<$name";
|
||||
foreach($xml->attributes() as $attr => $value)
|
||||
{
|
||||
echo " $attr=\"$value\"";
|
||||
}
|
||||
echo ">" . trim($xml) . "\n";
|
||||
foreach($xml->children() as $node)
|
||||
{
|
||||
traverse_xml($node, $pad.' ');
|
||||
}
|
||||
echo $pad."</$name>\n";
|
||||
}
|
||||
|
||||
|
||||
$people = simplexml_load_string($xml);
|
||||
traverse_xml($people);
|
||||
$people->person = 'Joe';
|
||||
$people->person['gender'] = 'male';
|
||||
traverse_xml($people);
|
||||
$people->person = 'Jane';
|
||||
traverse_xml($people);
|
||||
$people->person['gender'] = 'female';
|
||||
$people->person[1] = 'Joe';
|
||||
$people->person[1]['gender'] = 'male';
|
||||
traverse_xml($people);
|
||||
$people->person[3] = 'Minni-me';
|
||||
$people->person[2]['gender'] = 'male';
|
||||
traverse_xml($people);
|
||||
$people->person[3]['gender'] = 'error';
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
<people>
|
||||
</people>
|
||||
<people>
|
||||
<person gender="male">Joe
|
||||
</person>
|
||||
</people>
|
||||
<people>
|
||||
<person gender="male">Jane
|
||||
</person>
|
||||
</people>
|
||||
<people>
|
||||
<person gender="female">Jane
|
||||
</person>
|
||||
<person gender="male">Joe
|
||||
</person>
|
||||
</people>
|
||||
|
||||
Warning: main(): Cannot add element person number 3 when only 2 such elements exist in %s027.php on line %d
|
||||
<people>
|
||||
<person gender="female">Jane
|
||||
</person>
|
||||
<person gender="male">Joe
|
||||
</person>
|
||||
<person gender="male">Minni-me
|
||||
</person>
|
||||
</people>
|
||||
|
||||
Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in %s027.php on line %d
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
SimpleXML: Adding an elements without text
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml =<<<EOF
|
||||
<people></people>
|
||||
EOF;
|
||||
|
||||
function traverse_xml($xml, $pad = '')
|
||||
{
|
||||
$name = $xml->getName();
|
||||
echo "$pad<$name";
|
||||
foreach($xml->attributes() as $attr => $value)
|
||||
{
|
||||
echo " $attr=\"$value\"";
|
||||
}
|
||||
echo ">" . trim($xml) . "\n";
|
||||
foreach($xml->children() as $node)
|
||||
{
|
||||
traverse_xml($node, $pad.' ');
|
||||
}
|
||||
echo $pad."</$name>\n";
|
||||
}
|
||||
|
||||
|
||||
$people = simplexml_load_string($xml);
|
||||
traverse_xml($people);
|
||||
$people->person['name'] = 'John';
|
||||
traverse_xml($people);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
<people>
|
||||
</people>
|
||||
<people>
|
||||
<person name="John">
|
||||
</person>
|
||||
</people>
|
||||
===DONE===
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
SimpleXML: foreach and count
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml =<<<EOF
|
||||
<people>
|
||||
<person name="Joe"/>
|
||||
<person name="John">
|
||||
<children>
|
||||
<person name="Joe"/>
|
||||
</children>
|
||||
</person>
|
||||
<person name="Jane"/>
|
||||
</people>
|
||||
EOF;
|
||||
|
||||
$people = simplexml_load_string($xml);
|
||||
|
||||
foreach($people as $person)
|
||||
{
|
||||
var_dump((string)$person['name']);
|
||||
var_dump(count($people));
|
||||
var_dump(count($person));
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
string(3) "Joe"
|
||||
int(3)
|
||||
int(0)
|
||||
string(4) "John"
|
||||
int(3)
|
||||
int(1)
|
||||
string(4) "Jane"
|
||||
int(3)
|
||||
int(0)
|
||||
===DONE===
|
||||
@@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
SimpleXML: isset and unset by offset
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml =<<<EOF
|
||||
<root s:att1="b" att1="a"
|
||||
xmlns:s="urn::test" xmlns:t="urn::test-t">
|
||||
<child1>test</child1>
|
||||
<child1>test 2</child1>
|
||||
<s:child3 />
|
||||
</root>
|
||||
EOF;
|
||||
|
||||
$sxe = simplexml_load_string($xml);
|
||||
|
||||
echo $sxe->child1[0]."\n";
|
||||
echo $sxe->child1[1]."\n\n";
|
||||
|
||||
var_dump(isset($sxe->child1[1]));
|
||||
unset($sxe->child1[1]);
|
||||
var_dump(isset($sxe->child1[1]));
|
||||
echo "\n";
|
||||
|
||||
$atts = $sxe->attributes("urn::test");
|
||||
var_dump(isset($atts[0]));
|
||||
unset($atts[0]);
|
||||
var_dump(isset($atts[0]));
|
||||
var_dump(isset($atts[TRUE]));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
test
|
||||
test 2
|
||||
|
||||
bool(true)
|
||||
bool(false)
|
||||
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -0,0 +1,57 @@
|
||||
--TEST--
|
||||
SimpleXML: addChild and addAttribute
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml =<<<EOF
|
||||
<root s:att1="b" att1="a"
|
||||
xmlns:s="urn::test" xmlns:t="urn::test-t">
|
||||
<child1>test</child1>
|
||||
<child1>test 2</child1>
|
||||
<s:child3 />
|
||||
</root>
|
||||
EOF;
|
||||
|
||||
$sxe = simplexml_load_string($xml);
|
||||
|
||||
/* Add new attribute in a new namespace */
|
||||
$sxe->addAttribute('v:att11', 'xxx', 'urn::test-v');
|
||||
|
||||
/* Try to add attribute again -> display warning as method is for new Attr only */
|
||||
$sxe->addAttribute('v:att11', 'xxx', 'urn::test-v');
|
||||
|
||||
/* Add new attribute w/o namespace */
|
||||
$sxe->addAttribute('att2', 'no-ns');
|
||||
|
||||
$d = $sxe->attributes();
|
||||
/* Try to add element to attribute -> display warning and do not add */
|
||||
$d->addChild('m:test', 'myval', 'urn::test');
|
||||
|
||||
|
||||
/* Test adding elements in various configurations */
|
||||
$sxe->addChild('m:test1', 'myval', 'urn::test');
|
||||
|
||||
/* New namespace test */
|
||||
$n = $sxe->addChild('m:test2', 'myval', 'urn::testnew');
|
||||
|
||||
$sxe->addChild('test3', 'myval', 'urn::testnew');
|
||||
$sxe->addChild('test4', 'myval');
|
||||
|
||||
/* Does not add prefix here although name is valid (but discouraged) - change behavior? */
|
||||
$sxe->addChild('s:test5', 'myval');
|
||||
|
||||
echo $sxe->asXML();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Warning: SimpleXMLElement::addAttribute(): Attribute already exists in %s031.php on line %d
|
||||
|
||||
Warning: SimpleXMLElement::addChild(): Cannot add element to attributes in %s031.php on line %d
|
||||
<?xml version="1.0"?>
|
||||
<root xmlns:s="urn::test" xmlns:t="urn::test-t" xmlns:v="urn::test-v" s:att1="b" att1="a" v:att11="xxx" att2="no-ns">
|
||||
<child1>test</child1>
|
||||
<child1>test 2</child1>
|
||||
<s:child3/>
|
||||
<s:test1>myval</s:test1><m:test2 xmlns:m="urn::testnew">myval</m:test2><test3 xmlns="urn::testnew">myval</test3><test4>myval</test4><test5>myval</test5></root>
|
||||
===DONE===
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
SimpleXML: comparing instances
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$xml =<<<EOF
|
||||
<people>
|
||||
<person name="Joe"/>
|
||||
<person name="John">
|
||||
<children>
|
||||
<person name="Joe"/>
|
||||
</children>
|
||||
</person>
|
||||
<person name="Jane"/>
|
||||
</people>
|
||||
EOF;
|
||||
|
||||
$xml1 =<<<EOF
|
||||
<people>
|
||||
<person name="John">
|
||||
<children>
|
||||
<person name="Joe"/>
|
||||
</children>
|
||||
</person>
|
||||
<person name="Jane"/>
|
||||
</people>
|
||||
EOF;
|
||||
|
||||
|
||||
$people = simplexml_load_string($xml);
|
||||
$people1 = simplexml_load_string($xml);
|
||||
$people2 = simplexml_load_string($xml1);
|
||||
|
||||
var_dump($people1 == $people);
|
||||
var_dump($people2 == $people);
|
||||
var_dump($people2 == $people1);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
===DONE===
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
--TEST--
|
||||
SimpleXML: casting instances
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("simplexml")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$xml =<<<EOF
|
||||
<people>
|
||||
test
|
||||
<person name="Joe"/>
|
||||
<person name="John">
|
||||
<children>
|
||||
<person name="Joe"/>
|
||||
</children>
|
||||
</person>
|
||||
<person name="Jane"/>
|
||||
</people>
|
||||
EOF;
|
||||
|
||||
$foo = simplexml_load_string( "<foo />" );
|
||||
$people = simplexml_load_string($xml);
|
||||
|
||||
var_dump((bool)$foo);
|
||||
var_dump((bool)$people);
|
||||
var_dump((int)$foo);
|
||||
var_dump((int)$people);
|
||||
var_dump((double)$foo);
|
||||
var_dump((double)$people);
|
||||
var_dump((string)$foo);
|
||||
var_dump((string)$people);
|
||||
var_dump((array)$foo);
|
||||
var_dump((array)$people);
|
||||
var_dump((object)$foo);
|
||||
var_dump((object)$people);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
bool(true)
|
||||
int(0)
|
||||
int(0)
|
||||
float(0)
|
||||
float(0)
|
||||
string(0) ""
|
||||
string(15) "
|
||||
test
|
||||
|
||||
|
||||
|
||||
"
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
["person"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(3) "Joe"
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
object(SimpleXMLElement)#%d (2) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(4) "John"
|
||||
}
|
||||
["children"]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["person"]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(3) "Joe"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[2]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(4) "Jane"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
object(SimpleXMLElement)#%d (0) {
|
||||
}
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["person"]=>
|
||||
array(3) {
|
||||
[0]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(3) "Joe"
|
||||
}
|
||||
}
|
||||
[1]=>
|
||||
object(SimpleXMLElement)#%d (2) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(4) "John"
|
||||
}
|
||||
["children"]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["person"]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(3) "Joe"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[2]=>
|
||||
object(SimpleXMLElement)#%d (1) {
|
||||
["@attributes"]=>
|
||||
array(1) {
|
||||
["name"]=>
|
||||
string(4) "Jane"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
===DONE===
|
||||
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Bug #36611 (assignment to SimpleXML object attribute changes argument type to string)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$xml_str = <<<EOD
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<c_fpobel >
|
||||
<pos >
|
||||
<pos/>
|
||||
</pos>
|
||||
</c_fpobel>
|
||||
EOD;
|
||||
|
||||
$xml = simplexml_load_string ($xml_str) ;
|
||||
|
||||
$val = 1;
|
||||
|
||||
var_dump($val);
|
||||
$obj->pos["act_idx"] = $val;
|
||||
var_dump($val) ;
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(1)
|
||||
Done
|
||||
Executable
+139
@@ -0,0 +1,139 @@
|
||||
--TEST--
|
||||
Bug #36226 SOAP Inconsistent handling when passing potential arrays.
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--INI--
|
||||
soap.wsdl_cache_enabled=0
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("soap.wsdl_cache_enabled",0);
|
||||
$timestamp = "2005-11-08T11:22:07+03:00";
|
||||
$wsdl = dirname(__FILE__)."/bug35142.wsdl";
|
||||
|
||||
function PostEvents($x) {
|
||||
var_dump($x);
|
||||
exit();
|
||||
return $x;
|
||||
}
|
||||
|
||||
class TestSoapClient extends SoapClient {
|
||||
|
||||
function __construct($wsdl, $options) {
|
||||
parent::__construct($wsdl, $options);
|
||||
$this->server = new SoapServer($wsdl, $options);
|
||||
$this->server->addFunction('PostEvents');
|
||||
}
|
||||
|
||||
function __doRequest($request, $location, $action, $version) {
|
||||
echo "$request\n";
|
||||
$this->server->handle($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$soapClient = new TestSoapClient($wsdl,
|
||||
array('trace' => 1, 'exceptions' => 0,
|
||||
'classmap' => array('logOnEvent' => 'LogOnEvent',
|
||||
'logOffEvent' => 'LogOffEvent',
|
||||
'events' => 'IVREvents'),
|
||||
'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
|
||||
|
||||
$logOnEvent = new LogOnEvent(34567, $timestamp);
|
||||
$logOffEvents[] = new LogOffEvent(34567, $timestamp, "Smoked");
|
||||
$logOffEvents[] = new LogOffEvent(34568, $timestamp, "SmokeFree");
|
||||
$ivrEvents = new IVREvents("1.0", 101, 12345, 'IVR', $logOnEvent, $logOffEvents);
|
||||
|
||||
$result = $soapClient->PostEvents($ivrEvents);
|
||||
|
||||
class LogOffEvent {
|
||||
public $audienceMemberId;
|
||||
public $timestamp;
|
||||
public $smokeStatus;
|
||||
public $callInitiator;
|
||||
|
||||
function __construct($audienceMemberId, $timestamp, $smokeStatus) {
|
||||
$this->audienceMemberId = $audienceMemberId;
|
||||
$this->timestamp = $timestamp;
|
||||
$this->smokeStatus = $smokeStatus;
|
||||
$this->callInitiator = "IVR";
|
||||
}
|
||||
}
|
||||
|
||||
class LogOnEvent {
|
||||
public $audienceMemberId;
|
||||
public $timestamp;
|
||||
|
||||
function __construct($audienceMemberId, $timestamp) {
|
||||
$this->audienceMemberId = $audienceMemberId;
|
||||
$this->timestamp = $timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
class IVREvents {
|
||||
public $version;
|
||||
public $activityId;
|
||||
public $messageId;
|
||||
public $source;
|
||||
public $logOnEvent;
|
||||
public $logOffEvent;
|
||||
|
||||
function __construct($version, $activityId, $messageId, $source, $logOnEvent=NULL, $logOffEvent=NULL) {
|
||||
$this->version = $version;
|
||||
$this->activityId = $activityId;
|
||||
$this->messageId = $messageId;
|
||||
$this->source = $source;
|
||||
$this->logOnEvent = $logOnEvent;
|
||||
$this->logOffEvent = $logOffEvent;
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testurl/Message"><SOAP-ENV:Body><ns1:ivrEvents version="1.0" activityId="101" messageId="12345" source="IVR"><ns1:logOffEvent audienceMemberId="34567" timestamp="2005-11-08T11:22:07+03:00" smokeStatus="Smoked" callInitiator="IVR"/><ns1:logOffEvent audienceMemberId="34568" timestamp="2005-11-08T11:22:07+03:00" smokeStatus="SmokeFree" callInitiator="IVR"/><ns1:logOnEvent audienceMemberId="34567" timestamp="2005-11-08T11:22:07+03:00"/></ns1:ivrEvents></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
|
||||
object(IVREvents)#%d (6) {
|
||||
["version"]=>
|
||||
string(3) "1.0"
|
||||
["activityId"]=>
|
||||
int(101)
|
||||
["messageId"]=>
|
||||
int(12345)
|
||||
["source"]=>
|
||||
string(3) "IVR"
|
||||
["logOnEvent"]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
object(LogOnEvent)#10 (2) {
|
||||
["audienceMemberId"]=>
|
||||
int(34567)
|
||||
["timestamp"]=>
|
||||
string(25) "2005-11-08T11:22:07+03:00"
|
||||
}
|
||||
}
|
||||
["logOffEvent"]=>
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(LogOffEvent)#%d (4) {
|
||||
["audienceMemberId"]=>
|
||||
int(34567)
|
||||
["timestamp"]=>
|
||||
string(25) "2005-11-08T11:22:07+03:00"
|
||||
["smokeStatus"]=>
|
||||
string(6) "Smoked"
|
||||
["callInitiator"]=>
|
||||
string(3) "IVR"
|
||||
}
|
||||
[1]=>
|
||||
object(LogOffEvent)#%d (4) {
|
||||
["audienceMemberId"]=>
|
||||
int(34568)
|
||||
["timestamp"]=>
|
||||
string(25) "2005-11-08T11:22:07+03:00"
|
||||
["smokeStatus"]=>
|
||||
string(9) "SmokeFree"
|
||||
["callInitiator"]=>
|
||||
string(3) "IVR"
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
--TEST--
|
||||
Bug #36575 (Incorrect complex type instantiation with hierarchies)
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--INI--
|
||||
soap.wsdl_cache_enabled=0
|
||||
--FILE--
|
||||
<?php
|
||||
abstract class CT_A1 {
|
||||
public $var1;
|
||||
}
|
||||
|
||||
class CT_A2 extends CT_A1 {
|
||||
public $var2;
|
||||
}
|
||||
|
||||
class CT_A3 extends CT_A2 {
|
||||
public $var3;
|
||||
}
|
||||
|
||||
// returns A2 in WSDL
|
||||
function test( $a1 ) {
|
||||
$a3 = new CT_A3();
|
||||
$a3->var1 = $a1->var1;
|
||||
$a3->var2 = "var two";
|
||||
$a3->var3 = "var three";
|
||||
return $a3;
|
||||
}
|
||||
|
||||
$classMap = array("A1" => "CT_A1", "A2" => "CT_A2", "A3" => "CT_A3");
|
||||
|
||||
$client = new SoapClient(dirname(__FILE__)."/bug36575.wsdl", array("trace" => 1, "exceptions" => 0, "classmap" => $classMap));
|
||||
$a2 = new CT_A2();
|
||||
$a2->var1 = "one";
|
||||
$a2->var2 = "two";
|
||||
$client->test($a2);
|
||||
|
||||
$soapRequest = $client->__getLastRequest();
|
||||
|
||||
echo $soapRequest;
|
||||
|
||||
$server = new SoapServer(dirname(__FILE__)."/bug36575.wsdl", array("classmap" => $classMap));
|
||||
$server->addFunction("test");
|
||||
$server->handle($soapRequest);
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:test.soap#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="urn:test.soap.types#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test><a1 xsi:type="ns2:A2"><var1 xsi:type="xsd:string">one</var1><var2 xsi:type="xsd:string">two</var2></a1></ns1:test></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:test.soap#" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="urn:test.soap.types#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:testResponse><result xsi:type="ns2:A3"><var1 xsi:type="xsd:string">one</var1><var2 xsi:type="xsd:string">var two</var2><var3 xsi:type="xsd:string">var three</var3></result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
ok
|
||||
Executable
+87
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<definitions name="shoppingcart"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns:tns="urn:test.soap#" targetNamespace="urn:test.soap#"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:types="urn:test.soap.types#">
|
||||
<!-- all datatypes will be imported to namespace types: -->
|
||||
<types>
|
||||
<xs:schema
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:tns="urn:test.soap.types#"
|
||||
targetNamespace="urn:test.soap.types#">
|
||||
|
||||
<xs:complexType name="A1">
|
||||
<xs:all>
|
||||
<xs:element name="var1" type="xs:string" nillable="true"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="A2">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="tns:A1">
|
||||
<xs:all>
|
||||
<xs:element name="var2" type="xs:string" nillable="true"/>
|
||||
</xs:all>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="A3">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="tns:A2">
|
||||
<xs:all>
|
||||
<xs:element name="var3" type="xs:string" nillable="true"/>
|
||||
</xs:all>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
</xs:schema>
|
||||
</types>
|
||||
|
||||
<message name="test-request">
|
||||
<part name="a1" type="types:A1"/>
|
||||
</message>
|
||||
<message name="test-response">
|
||||
<part name="result" type="types:A2"/>
|
||||
</message>
|
||||
|
||||
<portType name="catalog-porttype">
|
||||
<operation name="test" parameterOrder="a1">
|
||||
<input name="test-request" message="tns:test-request"/>
|
||||
<output name="test-response" message="tns:test-response"/>
|
||||
</operation>
|
||||
</portType>
|
||||
|
||||
<!-- @type doesn't like tns: -->
|
||||
<binding name="catalog-binding" type="tns:catalog-porttype">
|
||||
<soap:binding style="rpc"
|
||||
transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||
|
||||
<operation name="test">
|
||||
<soap:operation soapAction="urn:test.soap#test"/>
|
||||
<input>
|
||||
<soap:body use="encoded" namespace="urn:test.soap#"
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
|
||||
</input>
|
||||
<output>
|
||||
<soap:body use="encoded" namespace="urn:test.soap#"
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
|
||||
</output>
|
||||
</operation>
|
||||
</binding>
|
||||
|
||||
<service name="catalog">
|
||||
<!-- @binding doesn't like to be tns: -->
|
||||
<port name="catalog-port" binding="tns:catalog-binding">
|
||||
<soap:address location="xxxxxxxx"/>
|
||||
</port>
|
||||
</service>
|
||||
|
||||
</definitions>
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Bug #36614 (Segfault when using Soap)
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--INI--
|
||||
soap.wsdl_cache_enabled=0
|
||||
--FILE--
|
||||
<?php
|
||||
$lo_soap = new SoapClient(dirname(__FILE__)."/bug36614.wsdl");
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
||||
Executable
+204
@@ -0,0 +1,204 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<definitions name="SonicMobile Web-Services"
|
||||
targetNamespace="http://soap.sonicmobile.com/sonicmobile.wsdl"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns:sonic="http://soap.sonicmobile.com/sonicmobile.wsdl"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<types>
|
||||
<xsd:schema xmlns="http://www.w3.org/2000/10/XMLSchema">
|
||||
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
|
||||
<complexType name="TransportCount">
|
||||
<all>
|
||||
<element name="transport" type="string" />
|
||||
<element name="count" type="integer" />
|
||||
<element name="rate" type="integer" />
|
||||
<element name="last_message" type="integer" />
|
||||
</all>
|
||||
</complexType>
|
||||
<complexType name="ArrayOfTransportCount">
|
||||
<complexContent>
|
||||
<restriction base="soapenc:Array">
|
||||
<attribute ref="soapenc:arrayType" arrayType="TransportCount[]" />
|
||||
</restriction>
|
||||
</complexContent>
|
||||
</complexType>
|
||||
</xsd:schema>
|
||||
</types>
|
||||
|
||||
<message name="userSendMessageRequest">
|
||||
<part name="sourceUser" type="xsd:int"/>
|
||||
<part name="password" type="xsd:string"/>
|
||||
<part name="destinationUser" type="xsd:int"/>
|
||||
<part name="content" type="xsd:string"/>
|
||||
<part name="sendRepliesTo" type="xsd:string"/>
|
||||
<part name="reference" type="xsd:string"/>
|
||||
</message>
|
||||
|
||||
<message name="sendMessageRequest">
|
||||
<part name="application" type="xsd:string"/>
|
||||
<part name="password" type="xsd:string"/>
|
||||
<part name="destination" type="xsd:string"/>
|
||||
<part name="content" type="xsd:string"/>
|
||||
<part name="reference" type="xsd:string"/>
|
||||
<part name="requestSource" type="xsd:string"/>
|
||||
<part name="customer" type="xsd:string"/>
|
||||
<part name="class" type="xsd:string"/>
|
||||
</message>
|
||||
|
||||
<message name="MessageResponse">
|
||||
<part name="messageid" type="xsd:int"/>
|
||||
<part name="response" type="xsd:string"/>
|
||||
</message>
|
||||
|
||||
<message name="messageCountRequest">
|
||||
<part name="password" type="xsd:string"/>
|
||||
</message>
|
||||
|
||||
<message name="messageCountResponse">
|
||||
<part name="transports" type="tns:ArrayOfTransportCount"/>
|
||||
</message>
|
||||
|
||||
<message name="serverStatusRequest">
|
||||
<part name="password" type="xsd:string"/>
|
||||
</message>
|
||||
<message name="serverStatusResponse">
|
||||
<part name="status_string" type="xsd:string"/>
|
||||
</message>
|
||||
|
||||
<message name="flushGatewayRequest">
|
||||
<part name="password" type="xsd:string"/>
|
||||
</message>
|
||||
<message name="flushGatewayResponse">
|
||||
<part name="status_string" type="xsd:string"/>
|
||||
</message>
|
||||
|
||||
<portType name="SonicMobilePortType">
|
||||
<operation name="userSendMessage">
|
||||
<input message="sonic:userSendMessageRequest"/>
|
||||
<output message="sonic:MessageResponse"/>
|
||||
</operation>
|
||||
|
||||
<operation name="sendMessage">
|
||||
<input message="sonic:sendMessageRequest"/>
|
||||
<output message="sonic:MessageResponse"/>
|
||||
</operation>
|
||||
|
||||
<operation name="messageCount">
|
||||
<input message="sonic:messageCountRequest"/>
|
||||
<output message="sonic:messageCountResponse"/>
|
||||
</operation>
|
||||
|
||||
<operation name="serverStatus">
|
||||
<input message="sonic:serverStatusRequest"/>
|
||||
<output message="sonic:serverStatusResponse"/>
|
||||
</operation>
|
||||
|
||||
<operation name="flushGateway">
|
||||
<input message="sonic:flushGatewayRequest"/>
|
||||
<output message="sonic:flushGatewayResponse"/>
|
||||
</operation>
|
||||
</portType>
|
||||
|
||||
<binding name="SonicMobileBinding" type="sonic:SonicMobilePortType">
|
||||
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||
|
||||
<operation name="userSendMessage">
|
||||
<soap:operation soapAction="http://soap.sonicmobile.com/SonicMobile/SOAP#userSendMessage"/>
|
||||
|
||||
<input>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</output>
|
||||
</operation>
|
||||
|
||||
<operation name="sendMessage">
|
||||
<soap:operation soapAction="http://soap.sonicmobile.com/SonicMobile/SOAP#sendMessage"/>
|
||||
|
||||
<input>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</output>
|
||||
</operation>
|
||||
|
||||
<operation name="messageCount">
|
||||
<soap:operation soapAction="http://soap.sonicmobile.com/SonicMobile/SOAP#messageCount"/>
|
||||
|
||||
<input>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</output>
|
||||
</operation>
|
||||
|
||||
<operation name="serverStatus">
|
||||
<soap:operation soapAction="http://soap.sonicmobile.com/SonicMobile/SOAP#serverStatus"/>
|
||||
|
||||
<input>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</input>
|
||||
|
||||
<output>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</output>
|
||||
</operation>
|
||||
|
||||
<operation name="flushGateway">
|
||||
<soap:operation soapAction="http://soap.sonicmobile.com/SonicMobile/SOAP#flushGateway"/>
|
||||
|
||||
<input>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</input>
|
||||
<output>
|
||||
<soap:body
|
||||
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
namespace="http://soap.sonicmobile.com/SonicMobile/SOAP"
|
||||
use="encoded" />
|
||||
</output>
|
||||
</operation>
|
||||
|
||||
</binding>
|
||||
|
||||
<service name="SonicMobile">
|
||||
<port name="SonicMobilePort" binding="sonic:SonicMobileBinding">
|
||||
<soap:address location="http://soap.sonicmobile.com/"/>
|
||||
</port>
|
||||
</service>
|
||||
|
||||
</definitions>
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
--TEST--
|
||||
Bug #36629 (SoapServer::handle() exits on SOAP faults)
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
function test1() {
|
||||
throw new SoapFault("Server", "test1");
|
||||
}
|
||||
function test2() {
|
||||
return new SoapFault("Server", "test2");
|
||||
}
|
||||
|
||||
$server = new soapserver(null,array('uri'=>"http://testuri.org"));
|
||||
$server->addfunction(array("test1","test2"));
|
||||
|
||||
$HTTP_RAW_POST_DATA = <<<EOF
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<SOAP-ENV:Envelope
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si="http://soapinterop.org/xsd">
|
||||
<SOAP-ENV:Body>
|
||||
<ns1:test1 xmlns:ns1="http://testuri.org" />
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
EOF;
|
||||
$server->handle();
|
||||
|
||||
$HTTP_RAW_POST_DATA = <<<EOF
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<SOAP-ENV:Envelope
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si="http://soapinterop.org/xsd">
|
||||
<SOAP-ENV:Body>
|
||||
<ns1:test2 xmlns:ns1="http://testuri.org" />
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
EOF;
|
||||
$server->handle();
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>test1</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>test2</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
ok
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
--TEST--
|
||||
SOAP Classmap 3: encoding of inherited objects
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("soap.wsdl_cache_enabled",0);
|
||||
|
||||
class A {
|
||||
public $x;
|
||||
function __construct($a){
|
||||
$this->x = $a;
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public $y;
|
||||
function __construct($a){
|
||||
parent::__construct($a);
|
||||
$this->y = $a + 1;
|
||||
}
|
||||
}
|
||||
|
||||
function f(){
|
||||
return new B(5);
|
||||
}
|
||||
|
||||
class LocalSoapClient extends SoapClient {
|
||||
|
||||
function __construct($wsdl, $options) {
|
||||
parent::__construct($wsdl, $options);
|
||||
$this->server = new SoapServer($wsdl, $options);
|
||||
$this->server->addFunction("f");
|
||||
}
|
||||
|
||||
function __doRequest($request, $location, $action, $version) {
|
||||
ob_start();
|
||||
$this->server->handle($request);
|
||||
$response = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
$client = new LocalSoapClient(dirname(__FILE__)."/classmap003.wsdl",
|
||||
array('classmap'=>array('A'=>'A','B'=>'B')));
|
||||
print_r($client->f());
|
||||
?>
|
||||
--EXPECT--
|
||||
B Object
|
||||
(
|
||||
[y] => 6
|
||||
[x] => 5
|
||||
)
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
||||
<!-- WSDL file generated by Zend Studio. -->
|
||||
|
||||
<definitions name="ab" targetNamespace="urn:ab" xmlns:typens="urn:ab" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
|
||||
<types>
|
||||
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ab">
|
||||
<xsd:complexType name="A">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="x" type="xsd:anyType"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="B">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="typens:A">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="y" type="xsd:anyType"/>
|
||||
</xsd:sequence>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:schema>
|
||||
</types>
|
||||
<message name="f"/>
|
||||
<message name="fResponse">
|
||||
<part name="fReturn" type="typens:A"/>
|
||||
</message>
|
||||
<portType name="abServerPortType">
|
||||
<operation name="f">
|
||||
<input message="typens:f"/>
|
||||
<output message="typens:fResponse"/>
|
||||
</operation>
|
||||
</portType>
|
||||
<binding name="abServerBinding" type="typens:abServerPortType">
|
||||
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||
<operation name="f">
|
||||
<soap:operation soapAction="urn:abServerAction"/>
|
||||
<input>
|
||||
<soap:body namespace="urn:ab" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
|
||||
</input>
|
||||
<output>
|
||||
<soap:body namespace="urn:ab" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
|
||||
</output>
|
||||
</operation>
|
||||
</binding>
|
||||
<service name="abService">
|
||||
<port name="abServerPort" binding="typens:abServerBinding">
|
||||
<soap:address location="http://localhost/abServer.php"/>
|
||||
</port>
|
||||
</service>
|
||||
</definitions>
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
SOAP Server 23: Send SOAP headers those were not received
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
function test() {
|
||||
global $server;
|
||||
$server->addSoapHeader(new SoapHeader("http://testuri.org", "Test1", "Hello Header!"));
|
||||
$server->addSoapHeader(new SoapHeader("http://testuri.org", "Test2", "Hello Header!"));
|
||||
return "Hello Body!";
|
||||
}
|
||||
|
||||
$server = new soapserver(null,array('uri'=>"http://testuri.org"));
|
||||
$server->addfunction("test");
|
||||
|
||||
$HTTP_RAW_POST_DATA = <<<EOF
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<SOAP-ENV:Envelope
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si="http://soapinterop.org/xsd">
|
||||
<SOAP-ENV:Body>
|
||||
<ns1:test xmlns:ns1="http://testuri.org"/>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
EOF;
|
||||
|
||||
$server->handle();
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:Test1>Hello Header!</ns1:Test1><ns1:Test2>Hello Header!</ns1:Test2></SOAP-ENV:Header><SOAP-ENV:Body><ns1:testResponse><return xsi:type="xsd:string">Hello Body!</return></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
ok
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
--TEST--
|
||||
SOAP Server 24: Send SOAP headers those were not received
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class TestHeader1 extends SoapHeader {
|
||||
function __construct($data) {
|
||||
parent::__construct("http://testuri.org", "Test1", $data);
|
||||
}
|
||||
}
|
||||
|
||||
class TestHeader2 extends SoapHeader {
|
||||
function __construct($data) {
|
||||
parent::__construct("http://testuri.org", "Test2", $data);
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
global $server;
|
||||
$server->addSoapHeader(new TestHeader1("Hello Header!"));
|
||||
$server->addSoapHeader(new TestHeader2("Hello Header!"));
|
||||
return "Hello Body!";
|
||||
}
|
||||
|
||||
$server = new soapserver(null,array('uri'=>"http://testuri.org"));
|
||||
$server->addfunction("test");
|
||||
|
||||
$HTTP_RAW_POST_DATA = <<<EOF
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<SOAP-ENV:Envelope
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si="http://soapinterop.org/xsd">
|
||||
<SOAP-ENV:Body>
|
||||
<ns1:test xmlns:ns1="http://testuri.org"/>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
EOF;
|
||||
|
||||
$server->handle();
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Header><ns1:Test1>Hello Header!</ns1:Test1><ns1:Test2>Hello Header!</ns1:Test2></SOAP-ENV:Header><SOAP-ENV:Body><ns1:testResponse><return xsi:type="xsd:string">Hello Body!</return></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
ok
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
SOAP Server 25: One-way SOAP headers encoding using WSDL
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class TestHeader1 extends SoapHeader {
|
||||
function __construct($data) {
|
||||
parent::__construct("http://testuri.org", "Test1", $data);
|
||||
}
|
||||
}
|
||||
|
||||
class TestHeader2 extends SoapHeader {
|
||||
function __construct($data) {
|
||||
parent::__construct("http://testuri.org", "Test2", $data);
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
global $server;
|
||||
$server->addSoapHeader(new TestHeader1("Hello Header!"));
|
||||
$server->addSoapHeader(new TestHeader2("Hello Header!"));
|
||||
return "Hello Body!";
|
||||
}
|
||||
|
||||
$server = new soapserver(dirname(__FILE__)."/server025.wsdl");
|
||||
$server->addfunction("test");
|
||||
|
||||
$HTTP_RAW_POST_DATA = <<<EOF
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<SOAP-ENV:Envelope
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<SOAP-ENV:Body>
|
||||
<ns1:test xmlns:ns1="http://testuri.org"/>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
EOF;
|
||||
|
||||
$server->handle();
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://testuri.org"><SOAP-ENV:Header><ns1:Test1 xsi:type="xsd:string">Hello Header!</ns1:Test1><ns1:Test2 xsi:type="xsd:string">Hello Header!</ns1:Test2></SOAP-ENV:Header><SOAP-ENV:Body><ns1:testResponse><result>Hello Body!</result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
ok
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" ?>
|
||||
<definitions
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
xmlns:si="http://soapinterop.org/xsd"
|
||||
xmlns:tns="http://linuxsrv.home/~dmitry/soap/test.wsdl"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||
targetNamespace="http://testuri.org">
|
||||
|
||||
<message name="TestHeader1">
|
||||
<part name="Test1" type="xsd:string" />
|
||||
</message>
|
||||
<message name="TestHeader2">
|
||||
<part name="Test2" type="xsd:string" />
|
||||
</message>
|
||||
|
||||
<message name="TestRequest">
|
||||
</message>
|
||||
<message name="TestResponse">
|
||||
<part name="result" type="xsd:string" />
|
||||
</message>
|
||||
|
||||
<portType name="TestServicePortType">
|
||||
<operation name="test">
|
||||
<input message="tns:TestRequest" />
|
||||
<output message="tns:TestResponse" />
|
||||
</operation>
|
||||
</portType>
|
||||
|
||||
<binding name="TestServiceBinding" type="tns:TestServicePortType">
|
||||
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||
<operation name="test">
|
||||
<soap:operation soapAction="Test" style="rpc" />
|
||||
<input>
|
||||
<soap:body namespace="http://testuri.org" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||
</input>
|
||||
<output>
|
||||
<soap:body namespace="http://testuri.org" use="literal" />
|
||||
<soap:header namespace="http://testuri.org" message="tns:TestHeader1" part="Test1" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||
<soap:header namespace="http://testuri.org" message="tns:TestHeader2" part="Test2" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||
</output>
|
||||
</operation>
|
||||
</binding>
|
||||
|
||||
<service name="TestService">
|
||||
<port name="TestServicePort" binding="tns:TestServiceBinding">
|
||||
<soap:address location="http://linuxsrv.home/~dmitry/soap/soap_server.php" />
|
||||
</port>
|
||||
</service>
|
||||
|
||||
</definitions>
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
SPL: ArrayIterator and foreach by reference
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$ar = new ArrayObject(array(1)); foreach($ar as &$v) var_dump($v);
|
||||
$ar = new ArrayIterator(array(2)); foreach($ar as &$v) var_dump($v);
|
||||
$ar = new RecursiveArrayIterator(array(3)); foreach($ar as &$v) var_dump($v);
|
||||
|
||||
class ArrayIteratorEx extends ArrayIterator
|
||||
{
|
||||
function current()
|
||||
{
|
||||
return ArrayIterator::current();
|
||||
}
|
||||
}
|
||||
|
||||
$ar = new ArrayIteratorEx(array(4)); foreach($ar as $v) var_dump($v);
|
||||
$ar = new ArrayIteratorEx(array(5)); foreach($ar as &$v) var_dump($v);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
int(1)
|
||||
int(2)
|
||||
int(3)
|
||||
int(4)
|
||||
int(5)
|
||||
===DONE===
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
--TEST--
|
||||
SPL: ArrayIterator overloading
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class ArrayIteratorEx extends ArrayIterator
|
||||
{
|
||||
function rewind()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
ArrayIterator::rewind();
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
return ArrayIterator::valid();
|
||||
}
|
||||
|
||||
function key()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
return ArrayIterator::key();
|
||||
}
|
||||
|
||||
function current()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
return ArrayIterator::current();
|
||||
}
|
||||
|
||||
function next()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
return ArrayIterator::next();
|
||||
}
|
||||
}
|
||||
|
||||
$ar = new ArrayIteratorEx(array(1,2));
|
||||
foreach($ar as $k => $v)
|
||||
{
|
||||
var_dump($k);
|
||||
var_dump($v);
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
ArrayIteratorEx::rewind
|
||||
ArrayIteratorEx::valid
|
||||
ArrayIteratorEx::current
|
||||
ArrayIteratorEx::key
|
||||
int(0)
|
||||
int(1)
|
||||
ArrayIteratorEx::next
|
||||
ArrayIteratorEx::valid
|
||||
ArrayIteratorEx::current
|
||||
ArrayIteratorEx::key
|
||||
int(1)
|
||||
int(2)
|
||||
ArrayIteratorEx::next
|
||||
ArrayIteratorEx::valid
|
||||
===DONE===
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
SPL: ArrayObject::seek() and exceptions
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class foo extends ArrayObject
|
||||
{
|
||||
public function seek($key)
|
||||
{
|
||||
echo __METHOD__ . "($key)\n";
|
||||
throw new Exception("hi");
|
||||
}
|
||||
}
|
||||
|
||||
$test = new foo(array(1,2,3));
|
||||
|
||||
try
|
||||
{
|
||||
$test->seek('bar');
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
echo "got exception\n";
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
foo::seek(bar)
|
||||
got exception
|
||||
===DONE===
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
--TEST--
|
||||
SPL: ArrayObject/Iterator and reference to self
|
||||
--FILE--
|
||||
==ArrayObject===
|
||||
<?php
|
||||
|
||||
class MyArrayObject extends ArrayObject
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct($this);
|
||||
$this['bar'] = 'baz';
|
||||
}
|
||||
}
|
||||
|
||||
$a = new MyArrayObject;
|
||||
|
||||
$b = clone $a;
|
||||
$b['baz'] = 'Foo';
|
||||
|
||||
var_dump($a);
|
||||
var_dump($b);
|
||||
|
||||
?>
|
||||
==ArrayIterator===
|
||||
<?php
|
||||
|
||||
class MyArrayIterator extends ArrayIterator
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct($this);
|
||||
$this['bar'] = 'baz';
|
||||
}
|
||||
}
|
||||
|
||||
$a = new MyArrayIterator;
|
||||
|
||||
$b = clone $a;
|
||||
$b['baz'] = 'Foo';
|
||||
|
||||
var_dump($a);
|
||||
var_dump($b);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
==ArrayObject===
|
||||
object(MyArrayObject)#%d (1) {
|
||||
["bar"]=>
|
||||
string(3) "baz"
|
||||
}
|
||||
object(MyArrayObject)#%d (2) {
|
||||
["bar"]=>
|
||||
string(3) "baz"
|
||||
["baz"]=>
|
||||
string(3) "Foo"
|
||||
}
|
||||
==ArrayIterator===
|
||||
object(MyArrayIterator)#%d (1) {
|
||||
["bar"]=>
|
||||
string(3) "baz"
|
||||
}
|
||||
object(MyArrayIterator)#%d (2) {
|
||||
["bar"]=>
|
||||
string(3) "baz"
|
||||
["baz"]=>
|
||||
string(3) "Foo"
|
||||
}
|
||||
===DONE===
|
||||
--UEXPECTF--
|
||||
==ArrayObject===
|
||||
object(MyArrayObject)#%d (1) {
|
||||
[u"bar"]=>
|
||||
unicode(3) "baz"
|
||||
}
|
||||
object(MyArrayObject)#%d (2) {
|
||||
[u"bar"]=>
|
||||
unicode(3) "baz"
|
||||
[u"baz"]=>
|
||||
unicode(3) "Foo"
|
||||
}
|
||||
==ArrayIterator===
|
||||
object(MyArrayIterator)#%d (1) {
|
||||
[u"bar"]=>
|
||||
unicode(3) "baz"
|
||||
}
|
||||
object(MyArrayIterator)#%d (2) {
|
||||
[u"bar"]=>
|
||||
unicode(3) "baz"
|
||||
[u"baz"]=>
|
||||
unicode(3) "Foo"
|
||||
}
|
||||
===DONE===
|
||||
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Bug #36258 (SplFileObject::getPath() may lead to segfault)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$diriter = new RecursiveIteratorIterator( new RecursiveDirectoryIterator('.') );
|
||||
|
||||
foreach ($diriter as $key => $file) {
|
||||
var_dump($file->getFilename());
|
||||
var_dump($file->getPath());
|
||||
break;
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(%d) "%s"
|
||||
string(%d) "%s"
|
||||
Done
|
||||
Executable
+40
@@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
Bug #36287
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("."), true);
|
||||
|
||||
$idx = 0;
|
||||
foreach($it as $file)
|
||||
{
|
||||
echo "First\n";
|
||||
if("." != $file && ".." != $file)
|
||||
{
|
||||
var_Dump($file->getFilename());
|
||||
}
|
||||
echo "Second\n";
|
||||
if($file != "." && $file != "..")
|
||||
{
|
||||
var_dump($file->getFilename());
|
||||
}
|
||||
if (++$idx > 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
First
|
||||
string(%d) "%s"
|
||||
Second
|
||||
string(%d) "%s"
|
||||
First
|
||||
string(%d) "%s"
|
||||
Second
|
||||
string(%d) "%s"
|
||||
===DONE===
|
||||
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Bug #36825 (Exceptions thrown in ArrayObject::offsetGet cause segfault)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class foo extends ArrayObject
|
||||
{
|
||||
public function offsetGet($key)
|
||||
{
|
||||
echo __METHOD__ . "($key)\n";
|
||||
throw new Exception("hi");
|
||||
}
|
||||
}
|
||||
|
||||
$test = new foo();
|
||||
|
||||
try
|
||||
{
|
||||
var_dump($test['bar']);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
echo "got exception\n";
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
foo::offsetGet(bar)
|
||||
got exception
|
||||
===DONE===
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
Bug #36941 (ArrayIterator does not clone itself)
|
||||
--FILE--
|
||||
===ArrayObject===
|
||||
<?php
|
||||
$a = new ArrayObject();
|
||||
$a[] = 1;
|
||||
|
||||
$b = clone $a;
|
||||
|
||||
var_dump($a[0], $b[0]);
|
||||
$b[0] = $b[0] + 1;
|
||||
var_dump($a[0], $b[0]);
|
||||
$b[0] = 3;
|
||||
var_dump($a[0], $b[0]);
|
||||
?>
|
||||
===ArrayIterator===
|
||||
<?php
|
||||
$a = new ArrayIterator();
|
||||
$a[] = 1;
|
||||
|
||||
$b = clone $a;
|
||||
|
||||
var_dump($a[0], $b[0]);
|
||||
$b[0] = $b[0] + 1;
|
||||
var_dump($a[0], $b[0]);
|
||||
$b[0] = 3;
|
||||
var_dump($a[0], $b[0]);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===ArrayObject===
|
||||
int(1)
|
||||
int(1)
|
||||
int(1)
|
||||
int(2)
|
||||
int(1)
|
||||
int(3)
|
||||
===ArrayIterator===
|
||||
int(1)
|
||||
int(1)
|
||||
int(2)
|
||||
int(2)
|
||||
int(3)
|
||||
int(3)
|
||||
===DONE===
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
SPL: EmptyIterator access
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$it = new EmptyIterator;
|
||||
|
||||
var_dump($it->valid());
|
||||
$it->rewind();
|
||||
var_dump($it->valid());
|
||||
$it->next();
|
||||
var_dump($it->valid());
|
||||
|
||||
try
|
||||
{
|
||||
var_dump($it->key());
|
||||
}
|
||||
catch(BadMethodCallException $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var_dump($it->current());
|
||||
}
|
||||
catch(BadMethodCallException $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
var_dump($it->valid());
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
Accessing the key of an EmptyIterator
|
||||
Accessing the value of an EmptyIterator
|
||||
bool(false)
|
||||
===DONE===
|
||||
Executable
+118
@@ -0,0 +1,118 @@
|
||||
--TEST--
|
||||
SPL: AppendIterator::append() rewinds when neccessary
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyArrayIterator extends ArrayIterator
|
||||
{
|
||||
function rewind()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
parent::rewind();
|
||||
}
|
||||
}
|
||||
|
||||
$it = new MyArrayIterator(array(1,2));
|
||||
|
||||
foreach($it as $k=>$v)
|
||||
{
|
||||
echo "$k=>$v\n";
|
||||
}
|
||||
|
||||
class MyAppendIterator extends AppendIterator
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
|
||||
function rewind()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
parent::rewind();
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
return parent::valid();
|
||||
}
|
||||
|
||||
function append(Iterator $what)
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
parent::append($what);
|
||||
}
|
||||
|
||||
function parent__construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
|
||||
$ap = new MyAppendIterator;
|
||||
|
||||
try
|
||||
{
|
||||
$ap->append($it);
|
||||
}
|
||||
catch(BadMethodCallException $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
$ap->parent__construct();
|
||||
|
||||
try
|
||||
{
|
||||
$ap->parent__construct($it);
|
||||
}
|
||||
catch(BadMethodCallException $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
$ap->append($it);
|
||||
$ap->append($it);
|
||||
$ap->append($it);
|
||||
|
||||
foreach($ap as $k=>$v)
|
||||
{
|
||||
echo "$k=>$v\n";
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
MyArrayIterator::rewind
|
||||
0=>1
|
||||
1=>2
|
||||
MyAppendIterator::__construct
|
||||
MyAppendIterator::append
|
||||
Classes derived from AppendIterator must call AppendIterator::__construct()
|
||||
AppendIterator::getIterator() must be called exactly once per instance
|
||||
MyAppendIterator::append
|
||||
MyArrayIterator::rewind
|
||||
MyAppendIterator::append
|
||||
MyAppendIterator::append
|
||||
MyAppendIterator::rewind
|
||||
MyArrayIterator::rewind
|
||||
MyAppendIterator::valid
|
||||
0=>1
|
||||
MyAppendIterator::valid
|
||||
1=>2
|
||||
MyArrayIterator::rewind
|
||||
MyAppendIterator::valid
|
||||
0=>1
|
||||
MyAppendIterator::valid
|
||||
1=>2
|
||||
MyArrayIterator::rewind
|
||||
MyAppendIterator::valid
|
||||
0=>1
|
||||
MyAppendIterator::valid
|
||||
1=>2
|
||||
MyAppendIterator::valid
|
||||
===DONE===
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
--TEST--
|
||||
SPL: LimitIterator::getPosition()
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$it = new LimitIterator(new ArrayIterator(array(1,2,3,4)), 1, 2);
|
||||
|
||||
foreach($it as $k=>$v)
|
||||
{
|
||||
echo "$k=>$v\n";
|
||||
var_dump($it->getPosition());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$it->seek(0);
|
||||
}
|
||||
catch(OutOfBoundsException $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
$it->seek(2);
|
||||
var_dump($it->current());
|
||||
|
||||
try
|
||||
{
|
||||
$it->seek(3);
|
||||
}
|
||||
catch(OutOfBoundsException $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
$it->next();
|
||||
var_dump($it->valid());
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
1=>2
|
||||
int(1)
|
||||
2=>3
|
||||
int(2)
|
||||
Cannot seek to 0 which is below the offset 1
|
||||
int(3)
|
||||
Cannot seek to 3 which is behind offest 1 plus count 2
|
||||
bool(false)
|
||||
===DONE===
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
SPL: ParentIterator
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$it = new ParentIterator(new RecursiveArrayIterator(array(1,array(21,22, array(231)),3)));
|
||||
|
||||
foreach(new RecursiveIteratorIterator($it) as $k=>$v)
|
||||
{
|
||||
var_dump($k);
|
||||
var_dump($v);
|
||||
}
|
||||
|
||||
echo "==SECOND==\n";
|
||||
|
||||
foreach(new RecursiveIteratorIterator($it, 1) as $k=>$v)
|
||||
{
|
||||
var_dump($k);
|
||||
var_dump($v);
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
==SECOND==
|
||||
int(1)
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(21)
|
||||
[1]=>
|
||||
int(22)
|
||||
[2]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(231)
|
||||
}
|
||||
}
|
||||
int(2)
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(231)
|
||||
}
|
||||
===DONE===
|
||||
Executable
+190
@@ -0,0 +1,190 @@
|
||||
--TEST--
|
||||
SPL: RecursiveIteratorIterator and break deep
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyRecursiveArrayIterator extends RecursiveArrayIterator
|
||||
{
|
||||
function valid()
|
||||
{
|
||||
if (!parent::valid())
|
||||
{
|
||||
echo __METHOD__ . "() = false\n";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function getChildren()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
return parent::getChildren();
|
||||
}
|
||||
|
||||
function rewind()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
parent::rewind();
|
||||
}
|
||||
}
|
||||
|
||||
class RecursiveArrayIteratorIterator extends RecursiveIteratorIterator
|
||||
{
|
||||
private $max_depth;
|
||||
private $over = 0;
|
||||
|
||||
function __construct($it, $max_depth)
|
||||
{
|
||||
$this->max_depth = $max_depth;
|
||||
parent::__construct($it);
|
||||
}
|
||||
|
||||
function rewind()
|
||||
{
|
||||
echo __METHOD__ . "() - BEGIN\n";
|
||||
parent::rewind();
|
||||
echo __METHOD__ . "() - DONE\n";
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
return parent::valid();
|
||||
}
|
||||
|
||||
function current()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
return parent::current();
|
||||
}
|
||||
|
||||
function key()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
return parent::key();
|
||||
}
|
||||
|
||||
function next()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
parent::next();
|
||||
}
|
||||
|
||||
function callHasChildren()
|
||||
{
|
||||
$has = parent::callHasChildren();
|
||||
$res = $this->getDepth() < $this->max_depth && $has;
|
||||
echo __METHOD__ . "(".$this->getDepth().") = ".($res?"yes":"no")."/".($has?"yes":"no")."\n";
|
||||
return $res;
|
||||
}
|
||||
|
||||
function beginChildren()
|
||||
{
|
||||
echo __METHOD__ . "(".$this->getDepth().")\n";
|
||||
parent::beginChildren();
|
||||
}
|
||||
|
||||
function endChildren()
|
||||
{
|
||||
echo __METHOD__ . "(".$this->getDepth().")\n";
|
||||
parent::endChildren();
|
||||
}
|
||||
}
|
||||
|
||||
$p = 0;
|
||||
$it = new RecursiveArrayIteratorIterator(new MyRecursiveArrayIterator(array("a", array("ba", array("bba", "bbb"), array(array("bcaa"), array("bcba"))), array("ca"), "d")), 2);
|
||||
foreach($it as $k=>$v)
|
||||
{
|
||||
if (is_array($v)) $v = join('',$v);
|
||||
echo "$k=>$v\n";
|
||||
if ($p++ == 5)
|
||||
{
|
||||
echo "===BREAK===\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo "===FOREND===\n";
|
||||
|
||||
$it->rewind();
|
||||
|
||||
echo "===CHECK===\n";
|
||||
|
||||
var_dump($it->valid());
|
||||
var_dump($it->current() == "a");
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
RecursiveArrayIteratorIterator::rewind() - BEGIN
|
||||
MyRecursiveArrayIterator::rewind()
|
||||
RecursiveArrayIteratorIterator::callHasChildren(0) = no/no
|
||||
RecursiveArrayIteratorIterator::rewind() - DONE
|
||||
RecursiveArrayIteratorIterator::valid()
|
||||
RecursiveArrayIteratorIterator::current()
|
||||
RecursiveArrayIteratorIterator::key()
|
||||
0=>a
|
||||
RecursiveArrayIteratorIterator::next()
|
||||
RecursiveArrayIteratorIterator::callHasChildren(0) = yes/yes
|
||||
MyRecursiveArrayIterator::getChildren()
|
||||
MyRecursiveArrayIterator::rewind()
|
||||
RecursiveArrayIteratorIterator::beginChildren(1)
|
||||
RecursiveArrayIteratorIterator::callHasChildren(1) = no/no
|
||||
RecursiveArrayIteratorIterator::valid()
|
||||
RecursiveArrayIteratorIterator::current()
|
||||
RecursiveArrayIteratorIterator::key()
|
||||
0=>ba
|
||||
RecursiveArrayIteratorIterator::next()
|
||||
RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes
|
||||
MyRecursiveArrayIterator::getChildren()
|
||||
MyRecursiveArrayIterator::rewind()
|
||||
RecursiveArrayIteratorIterator::beginChildren(2)
|
||||
RecursiveArrayIteratorIterator::callHasChildren(2) = no/no
|
||||
RecursiveArrayIteratorIterator::valid()
|
||||
RecursiveArrayIteratorIterator::current()
|
||||
RecursiveArrayIteratorIterator::key()
|
||||
0=>bba
|
||||
RecursiveArrayIteratorIterator::next()
|
||||
RecursiveArrayIteratorIterator::callHasChildren(2) = no/no
|
||||
RecursiveArrayIteratorIterator::valid()
|
||||
RecursiveArrayIteratorIterator::current()
|
||||
RecursiveArrayIteratorIterator::key()
|
||||
1=>bbb
|
||||
RecursiveArrayIteratorIterator::next()
|
||||
MyRecursiveArrayIterator::valid() = false
|
||||
RecursiveArrayIteratorIterator::endChildren(2)
|
||||
RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes
|
||||
MyRecursiveArrayIterator::getChildren()
|
||||
MyRecursiveArrayIterator::rewind()
|
||||
RecursiveArrayIteratorIterator::beginChildren(2)
|
||||
RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes
|
||||
RecursiveArrayIteratorIterator::valid()
|
||||
RecursiveArrayIteratorIterator::current()
|
||||
RecursiveArrayIteratorIterator::key()
|
||||
0=>bcaa
|
||||
RecursiveArrayIteratorIterator::next()
|
||||
RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes
|
||||
RecursiveArrayIteratorIterator::valid()
|
||||
RecursiveArrayIteratorIterator::current()
|
||||
RecursiveArrayIteratorIterator::key()
|
||||
1=>bcba
|
||||
===BREAK===
|
||||
===FOREND===
|
||||
RecursiveArrayIteratorIterator::rewind() - BEGIN
|
||||
RecursiveArrayIteratorIterator::endChildren(1)
|
||||
RecursiveArrayIteratorIterator::endChildren(0)
|
||||
MyRecursiveArrayIterator::rewind()
|
||||
RecursiveArrayIteratorIterator::callHasChildren(0) = no/no
|
||||
RecursiveArrayIteratorIterator::rewind() - DONE
|
||||
===CHECK===
|
||||
RecursiveArrayIteratorIterator::valid()
|
||||
bool(true)
|
||||
RecursiveArrayIteratorIterator::current()
|
||||
bool(true)
|
||||
===DONE===
|
||||
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
SPL: ArrayIterator and values assigned by reference
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$tmp = 1;
|
||||
|
||||
$a = new ArrayIterator();
|
||||
$a[] = $tmp;
|
||||
$a[] = &$tmp;
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in %s on line %d
|
||||
Executable
+131
@@ -0,0 +1,131 @@
|
||||
--TEST--
|
||||
SPL: spl_autoload() with exceptions
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("spl")) print "skip"; ?>
|
||||
--INI--
|
||||
include_path=.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function MyAutoLoad($className)
|
||||
{
|
||||
echo __METHOD__ . "($className)\n";
|
||||
throw new Exception('Bla');
|
||||
}
|
||||
|
||||
class MyAutoLoader
|
||||
{
|
||||
static function autoLoad($className)
|
||||
{
|
||||
echo __METHOD__ . "($className)\n";
|
||||
throw new Exception('Bla');
|
||||
}
|
||||
|
||||
function dynaLoad($className)
|
||||
{
|
||||
echo __METHOD__ . "($className)\n";
|
||||
throw new Exception('Bla');
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new MyAutoLoader;
|
||||
|
||||
$funcs = array(
|
||||
'MyAutoLoad',
|
||||
'MyAutoLoader::autoLoad',
|
||||
'MyAutoLoader::dynaLoad',
|
||||
array('MyAutoLoader', 'autoLoad'),
|
||||
array('MyAutoLoader', 'dynaLoad'),
|
||||
array($obj, 'autoLoad'),
|
||||
array($obj, 'dynaLoad'),
|
||||
);
|
||||
|
||||
foreach($funcs as $idx => $func)
|
||||
{
|
||||
echo "====$idx====\n";
|
||||
|
||||
try
|
||||
{
|
||||
var_dump($func);
|
||||
spl_autoload_register($func);
|
||||
if (count(spl_autoload_functions()))
|
||||
{
|
||||
echo "registered\n";
|
||||
|
||||
var_dump(class_exists("NoExistingTestClass", true));
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
echo get_class($e) . ": " . $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
spl_autoload_unregister($func);
|
||||
var_dump(count(spl_autoload_functions()));
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
====0====
|
||||
string(10) "MyAutoLoad"
|
||||
registered
|
||||
MyAutoLoad(NoExistingTestClass)
|
||||
Exception: Bla
|
||||
int(0)
|
||||
====1====
|
||||
string(22) "MyAutoLoader::autoLoad"
|
||||
registered
|
||||
MyAutoLoader::autoLoad(NoExistingTestClass)
|
||||
Exception: Bla
|
||||
int(0)
|
||||
====2====
|
||||
string(22) "MyAutoLoader::dynaLoad"
|
||||
LogicException: Function 'MyAutoLoader::dynaLoad' not callable
|
||||
int(0)
|
||||
====3====
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(12) "MyAutoLoader"
|
||||
[1]=>
|
||||
string(8) "autoLoad"
|
||||
}
|
||||
registered
|
||||
MyAutoLoader::autoLoad(NoExistingTestClass)
|
||||
Exception: Bla
|
||||
int(0)
|
||||
====4====
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(12) "MyAutoLoader"
|
||||
[1]=>
|
||||
string(8) "dynaLoad"
|
||||
}
|
||||
LogicException: Passed array specifies a non static method but no object
|
||||
int(0)
|
||||
====5====
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(MyAutoLoader)#%d (0) {
|
||||
}
|
||||
[1]=>
|
||||
string(8) "autoLoad"
|
||||
}
|
||||
registered
|
||||
MyAutoLoader::autoLoad(NoExistingTestClass)
|
||||
Exception: Bla
|
||||
int(0)
|
||||
====6====
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(MyAutoLoader)#%d (0) {
|
||||
}
|
||||
[1]=>
|
||||
string(8) "dynaLoad"
|
||||
}
|
||||
registered
|
||||
MyAutoLoader::dynaLoad(NoExistingTestClass)
|
||||
Exception: Bla
|
||||
int(0)
|
||||
===DONE===
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
SPL: SimpleXMLIterator and getChildren()
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("spl")) print "skip";
|
||||
if (!extension_loaded('simplexml')) print 'skip';
|
||||
if (!extension_loaded("libxml")) print "skip LibXML not present";
|
||||
if (!class_exists('RecursiveIteratorIterator')) print 'skip RecursiveIteratorIterator not available';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$xml =<<<EOF
|
||||
<?xml version='1.0'?>
|
||||
<sxe>
|
||||
<elem1/>
|
||||
<elem2/>
|
||||
<elem2/>
|
||||
</sxe>
|
||||
EOF;
|
||||
|
||||
class SXETest extends SimpleXMLIterator
|
||||
{
|
||||
function count()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
return parent::count();
|
||||
}
|
||||
}
|
||||
|
||||
$sxe = new SXETest($xml);
|
||||
|
||||
var_dump(count($sxe));
|
||||
var_dump(count($sxe->elem1));
|
||||
var_dump(count($sxe->elem2));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
SXETest::count
|
||||
int(3)
|
||||
SXETest::count
|
||||
int(1)
|
||||
SXETest::count
|
||||
int(2)
|
||||
===DONE===
|
||||
@@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
Bug #37158 (if userspace stream is present, fread() reads in 8192 max, otherwise it works)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class VariableStream {
|
||||
|
||||
function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
stream_wrapper_register("var", "VariableStream");
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
$file = dirname(__FILE__) . '/footest.txt';
|
||||
$x = str_repeat(1, 8192);
|
||||
$fp = fopen($file, 'w');
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
fwrite($fp, $x);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
$fp = fopen($file, 'r');
|
||||
$outsidecontents = fread($fp, 20000);
|
||||
fclose($fp);
|
||||
var_dump('size of contents 1 = ' . strlen($outsidecontents));
|
||||
$outsidecontents = file_get_contents($file);
|
||||
var_dump('size of contents 2 = ' . strlen($outsidecontents));
|
||||
|
||||
unlink($file);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
string(26) "size of contents 1 = 20000"
|
||||
string(26) "size of contents 2 = 40960"
|
||||
Done
|
||||
@@ -0,0 +1,72 @@
|
||||
--TEST--
|
||||
stream filter - reading
|
||||
--FILE--
|
||||
<?php
|
||||
echo "-TEST\n";
|
||||
class filter extends php_user_filter {
|
||||
function filter($in, $out, &$consumed, $closing)
|
||||
{
|
||||
$output = 0;
|
||||
while ($bucket = stream_bucket_make_writeable($in)) {
|
||||
$bucket->data = strtoupper($bucket->data);
|
||||
$consumed += $bucket->datalen;
|
||||
stream_bucket_append($out, $bucket);
|
||||
$output = 1;
|
||||
}
|
||||
if ($closing) {
|
||||
$bucket = stream_bucket_new($this->stream, "\n===close===\n");
|
||||
stream_bucket_append($out, $bucket);
|
||||
$output = 1;
|
||||
}
|
||||
return $output ? PSFS_PASS_ON : PSFS_FEED_ME;
|
||||
}
|
||||
}
|
||||
stream_filter_register("strtoupper", "filter")
|
||||
or die("Failed to register filter");
|
||||
|
||||
if ($f = fopen(__FILE__, "rb")) {
|
||||
stream_filter_append($f, "strtoupper");
|
||||
while (!feof($f)) {
|
||||
echo fread($f, 8192);
|
||||
}
|
||||
fclose($f);
|
||||
}
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
%sTEST
|
||||
<?PHP
|
||||
ECHO "-TEST\N";
|
||||
CLASS FILTER EXTENDS PHP_USER_FILTER {
|
||||
FUNCTION FILTER($IN, $OUT, &$CONSUMED, $CLOSING)
|
||||
{
|
||||
$OUTPUT = 0;
|
||||
WHILE ($BUCKET = STREAM_BUCKET_MAKE_WRITEABLE($IN)) {
|
||||
$BUCKET->DATA = STRTOUPPER($BUCKET->DATA);
|
||||
$CONSUMED += $BUCKET->DATALEN;
|
||||
STREAM_BUCKET_APPEND($OUT, $BUCKET);
|
||||
$OUTPUT = 1;
|
||||
}
|
||||
IF ($CLOSING) {
|
||||
$BUCKET = STREAM_BUCKET_NEW($THIS->STREAM, "\N===CLOSE===\N");
|
||||
STREAM_BUCKET_APPEND($OUT, $BUCKET);
|
||||
$OUTPUT = 1;
|
||||
}
|
||||
RETURN $OUTPUT ? PSFS_PASS_ON : PSFS_FEED_ME;
|
||||
}
|
||||
}
|
||||
STREAM_FILTER_REGISTER("STRTOUPPER", "FILTER")
|
||||
OR DIE("FAILED TO REGISTER FILTER");
|
||||
|
||||
IF ($F = FOPEN(__FILE__, "RB")) {
|
||||
STREAM_FILTER_APPEND($F, "STRTOUPPER");
|
||||
WHILE (!FEOF($F)) {
|
||||
ECHO FREAD($F, 8192);
|
||||
}
|
||||
FCLOSE($F);
|
||||
}
|
||||
ECHO "DONE\N";
|
||||
?>
|
||||
|
||||
===close===
|
||||
Done
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
Bug #36011 (Strict errormsg wrong for call_user_func() and the likes)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class TestClass
|
||||
{
|
||||
static function test()
|
||||
{
|
||||
echo __METHOD__ . "()\n";
|
||||
}
|
||||
|
||||
function whee()
|
||||
{
|
||||
array_map(array('TestClass', 'test'), array('array_value'));
|
||||
}
|
||||
|
||||
function whee4()
|
||||
{
|
||||
call_user_func(array('TestClass', 'test'));
|
||||
}
|
||||
|
||||
static function whee5()
|
||||
{
|
||||
call_user_func(array('TestClass', 'test'));
|
||||
}
|
||||
}
|
||||
|
||||
TestClass::test();
|
||||
|
||||
$a = new TestClass();
|
||||
$a->whee();
|
||||
$a->whee4();
|
||||
$a->whee5();
|
||||
|
||||
TestClass::whee5();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
TestClass::test()
|
||||
TestClass::test()
|
||||
TestClass::test()
|
||||
TestClass::test()
|
||||
TestClass::test()
|
||||
===DONE===
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Bug #33605 (substr_compare crashes)
|
||||
--FILE--
|
||||
<?php
|
||||
$res = substr_compare("aa", "a", -99999999, 0, 0);
|
||||
var_dump($res);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: substr_compare(): The length must be greater than zero in %s on line %d
|
||||
bool(false)
|
||||
@@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Bug #36148 (unpack("H*hex", $data) is adding an extra character to the end of the string)
|
||||
--FILE--
|
||||
<?php
|
||||
$values = array("a", "aa", "aaa", "aaaa");
|
||||
foreach ($values as $value) {
|
||||
$a = pack("H*", $value);
|
||||
$b = unpack("H*", $a);
|
||||
echo $value.": ";
|
||||
var_dump($b);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
a: array(1) {
|
||||
[1]=>
|
||||
string(2) "a0"
|
||||
}
|
||||
aa: array(1) {
|
||||
[1]=>
|
||||
string(2) "aa"
|
||||
}
|
||||
aaa: array(1) {
|
||||
[1]=>
|
||||
string(4) "aaa0"
|
||||
}
|
||||
aaaa: array(1) {
|
||||
[1]=>
|
||||
string(4) "aaaa"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #36306 crc32() 64bit
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* as an example how to write crc32 tests
|
||||
PHP does not have uint values, you cannot
|
||||
display crc32 like a signed integer.
|
||||
Have to find some small strings to truely reproduce
|
||||
the problem, this example being not a problem
|
||||
*/
|
||||
echo dechex(crc32("platform independant")) . "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
ccd9fe66
|
||||
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #36944 (strncmp & strncasecmp do not return false on negative string length)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(strncmp("test ", "e", -1));
|
||||
var_dump(strncmp("test ", "e", 10));
|
||||
var_dump(strncmp("test ", "e", 0));
|
||||
|
||||
var_dump(strncasecmp("test ", "E", -1));
|
||||
var_dump(strncasecmp("test ", "E", 10));
|
||||
var_dump(strncasecmp("test ", "E", 0));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Length must be greater than or equal to 0 in %s on line %d
|
||||
bool(false)
|
||||
int(%d)
|
||||
int(0)
|
||||
|
||||
Warning: Length must be greater than or equal to 0 in %s on line %d
|
||||
bool(false)
|
||||
int(%d)
|
||||
int(0)
|
||||
Done
|
||||
@@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
substr_compare()
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(substr_compare("abcde", "bc", 1, 2));
|
||||
var_dump(substr_compare("abcde", "bcg", 1, 2));
|
||||
var_dump(substr_compare("abcde", "BC", 1, 2, true));
|
||||
var_dump(substr_compare("abcde", "bc", 1, 3));
|
||||
var_dump(substr_compare("abcde", "cd", 1, 2));
|
||||
var_dump(substr_compare("abcde", "abc", 5, 1));
|
||||
|
||||
var_dump(substr_compare("abcde", -1, 0, NULL, new stdClass));
|
||||
echo "Test\n";
|
||||
var_dump(substr_compare("abcde", "abc", -1, NULL, -5));
|
||||
var_dump(substr_compare("abcde", -1, 0, "str", new stdClass));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
int(0)
|
||||
int(0)
|
||||
int(0)
|
||||
int(1)
|
||||
int(-1)
|
||||
|
||||
Warning: substr_compare(): The start position cannot exceed initial string length in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: substr_compare() expects parameter 5 to be boolean, object given in %s on line %d
|
||||
bool(false)
|
||||
Test
|
||||
|
||||
Warning: substr_compare(): The length must be greater than zero in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: substr_compare() expects parameter 4 to be long, string given in %s on line %d
|
||||
bool(false)
|
||||
Done
|
||||
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
XMLReader: libxml2 XML Reader, string data
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlreader")) print "skip";
|
||||
$reader = new XMLReader();
|
||||
if (!method_exists($reader, 'readInnerXml')) print "skip";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$xmlstring = '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<books><book>test</book></books>';
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->XML($xmlstring);
|
||||
$reader->read();
|
||||
echo $reader->readInnerXml();
|
||||
echo "\n";
|
||||
$reader->close();
|
||||
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->XML($xmlstring);
|
||||
$reader->read();
|
||||
echo $reader->readOuterXml();
|
||||
echo "\n";
|
||||
$reader->close();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
<book>test</book>
|
||||
<books><book>test</book></books>
|
||||
===DONE===
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
<!ELEMENT foo EMPTY>
|
||||
<!ATTLIST foo bar CDATA '' baz CDATA ''>
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
--TEST--
|
||||
XMLReader: accessing empty and non existing attributes
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("xmlreader")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
/* $Id$ */
|
||||
|
||||
$xmlstring =<<<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<foo bar=""/>
|
||||
EOF;
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->XML($xmlstring);
|
||||
$reader->read();
|
||||
var_dump($reader->getAttribute('bar'));
|
||||
var_dump($reader->getAttribute('baz'));
|
||||
$reader->close();
|
||||
|
||||
$xmlstring =<<<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo SYSTEM "012.dtd">
|
||||
<foo bar=""/>
|
||||
EOF;
|
||||
|
||||
$xmlstring = str_replace('012.dtd', dirname(__FILE__).'/012.dtd', $xmlstring);
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->XML($xmlstring);
|
||||
$reader->setParserProperty(XMLReader::DEFAULTATTRS, true);
|
||||
while($reader->read() && $reader->nodeType != XMLReader::ELEMENT);
|
||||
var_dump($reader->getAttribute('bar'));
|
||||
var_dump($reader->getAttribute('baz'));
|
||||
$reader->close();
|
||||
|
||||
?>
|
||||
===FILE===
|
||||
<?php
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->open(dirname(__FILE__) . '/012.xml');
|
||||
//$reader->setParserProperty(XMLReader::DEFAULTATTRS, true);
|
||||
while($reader->read() && $reader->nodeType != XMLReader::ELEMENT);
|
||||
var_dump($reader->getAttribute('bar'));
|
||||
var_dump($reader->getAttribute('baz'));
|
||||
$reader->close();
|
||||
|
||||
$reader = new XMLReader();
|
||||
$reader->open(dirname(__FILE__) . '/012.xml');
|
||||
$reader->setParserProperty(XMLReader::DEFAULTATTRS, true);
|
||||
while($reader->read() && $reader->nodeType != XMLReader::ELEMENT);
|
||||
var_dump($reader->getAttribute('bar'));
|
||||
var_dump($reader->getAttribute('baz'));
|
||||
$reader->close();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
string(0) ""
|
||||
NULL
|
||||
string(0) ""
|
||||
string(0) ""
|
||||
===FILE===
|
||||
string(0) ""
|
||||
NULL
|
||||
string(0) ""
|
||||
string(0) ""
|
||||
===DONE===
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE foo SYSTEM "012.dtd">
|
||||
<foo bar=""/>
|
||||
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
Bug #36743 (In a class extending XMLReader array properties are not writable)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test extends XMLReader
|
||||
{
|
||||
private $testArr = array();
|
||||
public function __construct()
|
||||
{
|
||||
$this->testArr[] = 1;
|
||||
var_dump($this->testArr);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new test;
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
Done
|
||||
@@ -0,0 +1,62 @@
|
||||
--TEST--
|
||||
Bug #37057 (xmlrpc_decode() may produce arrays with numeric string keys which are unaccessible)
|
||||
--FILE--
|
||||
<?php
|
||||
$response='<?xml version="1.0"?>
|
||||
<methodResponse>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>50</name>
|
||||
<value><string>0.29</string></value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodResponse>';
|
||||
|
||||
$retval=xmlrpc_decode($response);
|
||||
var_dump($retval);
|
||||
var_dump($retval["50"]);
|
||||
var_dump($retval[50]);
|
||||
|
||||
$response='<?xml version="1.0"?>
|
||||
<methodResponse>
|
||||
<params>
|
||||
<param>
|
||||
<value>
|
||||
<struct>
|
||||
<member>
|
||||
<name>0</name>
|
||||
<value><string>0.29</string></value>
|
||||
</member>
|
||||
</struct>
|
||||
</value>
|
||||
</param>
|
||||
</params>
|
||||
</methodResponse>';
|
||||
|
||||
$retval=xmlrpc_decode($response);
|
||||
var_dump($retval);
|
||||
var_dump($retval["0"]);
|
||||
var_dump($retval[0]);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[50]=>
|
||||
string(4) "0.29"
|
||||
}
|
||||
string(4) "0.29"
|
||||
string(4) "0.29"
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(4) "0.29"
|
||||
}
|
||||
string(4) "0.29"
|
||||
string(4) "0.29"
|
||||
Done
|
||||
@@ -0,0 +1,938 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Dmitry Stogov <dmitry@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "fastcgi.h"
|
||||
#include "php.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
struct sockaddr_un {
|
||||
short sun_family;
|
||||
char sun_path[MAXPATHLEN];
|
||||
};
|
||||
|
||||
static HANDLE fcgi_accept_mutex = INVALID_HANDLE_VALUE;
|
||||
static int is_impersonate = 0;
|
||||
|
||||
#define FCGI_LOCK(fd) \
|
||||
if (fcgi_accept_mutex != INVALID_HANDLE_VALUE) { \
|
||||
DWORD ret; \
|
||||
while ((ret = WaitForSingleObject(fcgi_accept_mutex, 1000)) == WAIT_TIMEOUT) { \
|
||||
if (in_shutdown) return -1; \
|
||||
} \
|
||||
if (ret == WAIT_FAILED) { \
|
||||
fprintf(stderr, "WaitForSingleObject() failed\n"); \
|
||||
return -1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FCGI_UNLOCK(fd) \
|
||||
if (fcgi_accept_mutex != INVALID_HANDLE_VALUE) { \
|
||||
ReleaseMutex(fcgi_accept_mutex); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/un.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <netdb.h>
|
||||
# include <sys/signal.h>
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE ((unsigned long) -1)
|
||||
#endif
|
||||
|
||||
# ifndef HAVE_SOCKLEN_T
|
||||
typedef unsigned int socklen_t;
|
||||
# endif
|
||||
|
||||
# ifdef USE_LOCKING
|
||||
# define FCGI_LOCK(fd) \
|
||||
do { \
|
||||
struct flock lock; \
|
||||
lock.l_type = F_WRLCK; \
|
||||
lock.l_start = 0; \
|
||||
lock.l_whence = SEEK_SET; \
|
||||
lock.l_len = 0; \
|
||||
if (fcntl(fd, F_SETLKW, &lock) != -1) { \
|
||||
break; \
|
||||
} else if (errno != EINTR || in_shutdown) { \
|
||||
return -1; \
|
||||
} \
|
||||
} while (1)
|
||||
|
||||
# define FCGI_UNLOCK(fd) \
|
||||
do { \
|
||||
int orig_errno = errno; \
|
||||
while (1) { \
|
||||
struct flock lock; \
|
||||
lock.l_type = F_UNLCK; \
|
||||
lock.l_start = 0; \
|
||||
lock.l_whence = SEEK_SET; \
|
||||
lock.l_len = 0; \
|
||||
if (fcntl(fd, F_SETLK, &lock) != -1) { \
|
||||
break; \
|
||||
} else if (errno != EINTR) { \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
errno = orig_errno; \
|
||||
} while (0)
|
||||
# else
|
||||
# define FCGI_LOCK(fd)
|
||||
# define FCGI_UNLOCK(fd)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef union _sa_t {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_un sa_unix;
|
||||
struct sockaddr_in sa_inet;
|
||||
} sa_t;
|
||||
|
||||
typedef struct _fcgi_mgmt_rec {
|
||||
char* name;
|
||||
char val;
|
||||
} fcgi_mgmt_rec;
|
||||
|
||||
static const fcgi_mgmt_rec fcgi_mgmt_vars[] = {
|
||||
{"FCGI_MAX_CONNS", 1},
|
||||
{"FCGI_MAX_REQS", 1},
|
||||
{"FCGI_MPXS_CONNS", 0}
|
||||
};
|
||||
|
||||
|
||||
static int is_initialized = 0;
|
||||
static int is_fastcgi = 0;
|
||||
static int in_shutdown = 0;
|
||||
|
||||
static inline char* fcgi_strndup(const char *str, int len)
|
||||
{
|
||||
char *s = malloc(len+1);
|
||||
memcpy(s, str, len+1);
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static DWORD WINAPI fcgi_shutdown_thread(LPVOID arg)
|
||||
{
|
||||
HANDLE shutdown_event = (HANDLE) arg;
|
||||
WaitForSingleObject(shutdown_event, INFINITE);
|
||||
in_shutdown = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void fcgi_signal_handler(int signo)
|
||||
{
|
||||
if (signo == SIGUSR1 || signo == SIGTERM) {
|
||||
in_shutdown = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int fcgi_init(void)
|
||||
{
|
||||
if (!is_initialized) {
|
||||
#ifdef _WIN32
|
||||
# if 0
|
||||
/* TODO: Support for TCP sockets */
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2,0), &wsaData)) {
|
||||
fprintf(stderr, "Error starting Windows Sockets. Error: %d", WSAGetLastError());
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
is_initialized = 1;
|
||||
|
||||
if ((GetStdHandle(STD_OUTPUT_HANDLE) == INVALID_HANDLE_VALUE) &&
|
||||
(GetStdHandle(STD_ERROR_HANDLE) == INVALID_HANDLE_VALUE) &&
|
||||
(GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE)) {
|
||||
char *str;
|
||||
DWORD pipe_mode = PIPE_READMODE_BYTE | PIPE_WAIT;
|
||||
HANDLE pipe = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
SetNamedPipeHandleState(pipe, &pipe_mode, NULL, NULL);
|
||||
|
||||
str = getenv("_FCGI_SHUTDOWN_EVENT_");
|
||||
if (str != NULL) {
|
||||
HANDLE shutdown_event = (HANDLE) atoi(str);
|
||||
if (!CreateThread(NULL, 0, fcgi_shutdown_thread,
|
||||
shutdown_event, 0, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
str = getenv("_FCGI_MUTEX_");
|
||||
if (str != NULL) {
|
||||
fcgi_accept_mutex = (HANDLE) atoi(str);
|
||||
}
|
||||
return is_fastcgi = 1;
|
||||
} else {
|
||||
return is_fastcgi = 0;
|
||||
}
|
||||
#else
|
||||
sa_t sa;
|
||||
socklen_t len = sizeof(sa);
|
||||
|
||||
is_initialized = 1;
|
||||
errno = 0;
|
||||
if (getpeername(0, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) {
|
||||
struct sigaction new_sa, old_sa;
|
||||
|
||||
sigemptyset(&new_sa.sa_mask);
|
||||
new_sa.sa_flags = 0;
|
||||
new_sa.sa_handler = fcgi_signal_handler;
|
||||
sigaction(SIGUSR1, &new_sa, NULL);
|
||||
sigaction(SIGTERM, &new_sa, NULL);
|
||||
sigaction(SIGPIPE, NULL, &old_sa);
|
||||
if (old_sa.sa_handler == SIG_DFL) {
|
||||
sigaction(SIGPIPE, &new_sa, NULL);
|
||||
}
|
||||
|
||||
return is_fastcgi = 1;
|
||||
} else {
|
||||
return is_fastcgi = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return is_fastcgi;
|
||||
}
|
||||
|
||||
|
||||
int fcgi_is_fastcgi(void)
|
||||
{
|
||||
if (!is_initialized) {
|
||||
return fcgi_init();
|
||||
} else {
|
||||
return is_fastcgi;
|
||||
}
|
||||
}
|
||||
|
||||
int fcgi_listen(const char *path, int backlog)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* TODO: Support for manual binding on TCP sockets (php -b <port>) */
|
||||
return -1;
|
||||
#else
|
||||
char *s;
|
||||
int tcp = 0;
|
||||
char host[MAXPATHLEN];
|
||||
short port = 0;
|
||||
int listen_socket;
|
||||
sa_t sa;
|
||||
socklen_t sa_len;
|
||||
|
||||
if ((s = strchr(path, ':'))) {
|
||||
port = atoi(s+1);
|
||||
if (port != 0 && (s-path) < MAXPATHLEN) {
|
||||
strncpy(host, path, s-path);
|
||||
host[s-path] = '\0';
|
||||
tcp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare socket address */
|
||||
if (tcp) {
|
||||
memset(&sa.sa_inet, 0, sizeof(sa.sa_inet));
|
||||
sa.sa_inet.sin_family = AF_INET;
|
||||
sa.sa_inet.sin_port = htons(port);
|
||||
sa_len = sizeof(sa.sa_inet);
|
||||
|
||||
if (!*host || !strncmp(host, "*", sizeof("*")-1)) {
|
||||
sa.sa_inet.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
} else {
|
||||
sa.sa_inet.sin_addr.s_addr = inet_addr(host);
|
||||
if (sa.sa_inet.sin_addr.s_addr == INADDR_NONE) {
|
||||
struct hostent *hep;
|
||||
|
||||
hep = gethostbyname(host);
|
||||
if (!hep || hep->h_addrtype != AF_INET || !hep->h_addr_list[0]) {
|
||||
fprintf(stderr, "Cannot resolve host name '%s'!\n", host);
|
||||
return -1;
|
||||
} else if (hep->h_addr_list[1]) {
|
||||
fprintf(stderr, "Host '%s' has multiple addresses. You must choose one explicitly!\n", host);
|
||||
return -1;
|
||||
}
|
||||
sa.sa_inet.sin_addr.s_addr = ((struct in_addr*)hep->h_addr_list[0])->s_addr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int path_len = strlen(path);
|
||||
|
||||
if (path_len >= sizeof(sa.sa_unix.sun_path)) {
|
||||
fprintf(stderr, "Listening socket's path name is too long.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&sa.sa_unix, 0, sizeof(sa.sa_unix));
|
||||
sa.sa_unix.sun_family = AF_UNIX;
|
||||
memcpy(sa.sa_unix.sun_path, path, path_len + 1);
|
||||
sa_len = (size_t)(((struct sockaddr_un *)0)->sun_path) + path_len;
|
||||
#ifdef HAVE_SOCKADDR_UN_SUN_LEN
|
||||
sa.sa_unix.sun_len = sa_len;
|
||||
#endif
|
||||
unlink(path);
|
||||
}
|
||||
|
||||
/* Create, bind socket and start listen on it */
|
||||
if ((listen_socket = socket(sa.sa.sa_family, SOCK_STREAM, 0)) < 0 ||
|
||||
bind(listen_socket, (struct sockaddr *) &sa, sa_len) < 0 ||
|
||||
listen(listen_socket, backlog) < 0) {
|
||||
|
||||
fprintf(stderr, "Cannot bind/listen socket - [%d] %s.\n",errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tcp) {
|
||||
chmod(path, 0777);
|
||||
}
|
||||
|
||||
if (!is_initialized) {
|
||||
fcgi_init();
|
||||
}
|
||||
is_fastcgi = 1;
|
||||
return listen_socket;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fcgi_init_request(fcgi_request *req, int listen_socket)
|
||||
{
|
||||
memset(req, 0, sizeof(fcgi_request));
|
||||
req->listen_socket = listen_socket;
|
||||
req->fd = -1;
|
||||
req->id = -1;
|
||||
|
||||
req->in_len = 0;
|
||||
req->in_pad = 0;
|
||||
|
||||
req->out_hdr = NULL;
|
||||
req->out_pos = req->out_buf;
|
||||
}
|
||||
|
||||
static inline ssize_t safe_write(fcgi_request *req, const void *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
size_t n = 0;
|
||||
|
||||
do {
|
||||
ret = write(req->fd, ((char*)buf)+n, count-n);
|
||||
if (ret > 0) {
|
||||
n += ret;
|
||||
} else if (ret <= 0 && errno != 0 && errno != EINTR) {
|
||||
return ret;
|
||||
}
|
||||
} while (n != count);
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline ssize_t safe_read(fcgi_request *req, const void *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
size_t n = 0;
|
||||
|
||||
do {
|
||||
ret = read(req->fd, ((char*)buf)+n, count-n);
|
||||
if (ret > 0) {
|
||||
n += ret;
|
||||
} else if (ret == 0 && errno == 0) {
|
||||
return n;
|
||||
} else if (ret <= 0 && errno != 0 && errno != EINTR) {
|
||||
return ret;
|
||||
}
|
||||
} while (n != count);
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline int fcgi_make_header(fcgi_header *hdr, fcgi_request_type type, int req_id, int len)
|
||||
{
|
||||
int pad = ((len + 7) & ~7) - len;
|
||||
|
||||
hdr->contentLengthB0 = (unsigned char)(len & 0xff);
|
||||
hdr->contentLengthB1 = (unsigned char)((len >> 8) & 0xff);
|
||||
hdr->paddingLength = (unsigned char)pad;
|
||||
hdr->requestIdB0 = (unsigned char)(req_id & 0xff);
|
||||
hdr->requestIdB1 = (unsigned char)((req_id >> 8) & 0xff);
|
||||
hdr->reserved = 0;
|
||||
hdr->type = type;
|
||||
hdr->version = FCGI_VERSION_1;
|
||||
return pad;
|
||||
}
|
||||
|
||||
static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *end, int n)
|
||||
{
|
||||
int name_len, val_len;
|
||||
char *s;
|
||||
|
||||
while (p < end) {
|
||||
name_len = *p++;
|
||||
if (name_len >= 128) {
|
||||
name_len = ((name_len & 0x7f) << 24);
|
||||
name_len |= (*p++ << 16);
|
||||
name_len |= (*p++ << 8);
|
||||
name_len |= *p++;
|
||||
}
|
||||
val_len = *p++;
|
||||
if (val_len >= 128) {
|
||||
val_len = ((val_len & 0x7f) << 24);
|
||||
val_len |= (*p++ << 16);
|
||||
val_len |= (*p++ << 8);
|
||||
val_len |= *p++;
|
||||
}
|
||||
req->env[n] = s = malloc(name_len + val_len + 2);
|
||||
memcpy(s, p, name_len);
|
||||
p += name_len;
|
||||
s[name_len] = '=';
|
||||
memcpy(s+name_len+1, p, val_len);
|
||||
p += val_len;
|
||||
s[name_len+1+val_len] = '\0';
|
||||
n++;
|
||||
if (n > sizeof(req->env)/sizeof(req->env[0])) {
|
||||
/* TODO: to many environment variables */
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int fcgi_read_request(fcgi_request *req)
|
||||
{
|
||||
fcgi_header hdr;
|
||||
int len, padding;
|
||||
int n = 1;
|
||||
char *s;
|
||||
unsigned char buf[FCGI_MAX_LENGTH+8];
|
||||
|
||||
req->keep = 0;
|
||||
req->in_len = 0;
|
||||
req->out_hdr = NULL;
|
||||
req->out_pos = req->out_buf;
|
||||
memset(req->env, 0, sizeof(req->env));
|
||||
|
||||
if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
|
||||
hdr.version < FCGI_VERSION_1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0;
|
||||
padding = hdr.paddingLength;
|
||||
|
||||
while (hdr.type == FCGI_STDIN && len == 0) {
|
||||
if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
|
||||
hdr.version < FCGI_VERSION_1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0;
|
||||
padding = hdr.paddingLength;
|
||||
}
|
||||
|
||||
req->id = (hdr.requestIdB1 << 8) + hdr.requestIdB0;
|
||||
|
||||
if (hdr.type == FCGI_BEGIN_REQUEST && len == sizeof(fcgi_begin_request)) {
|
||||
if (safe_read(req, buf, len+padding) != len+padding) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
req->keep = (((fcgi_begin_request*)buf)->flags & FCGI_KEEP_CONN);
|
||||
switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + ((fcgi_begin_request*)buf)->roleB0) {
|
||||
case FCGI_RESPONDER:
|
||||
req->env[0] = fcgi_strndup("FCGI_ROLE=RESPONDER", sizeof("FCGI_ROLE=RESPONDER")-1);
|
||||
break;
|
||||
case FCGI_AUTHORIZER:
|
||||
req->env[0] = fcgi_strndup("FCGI_ROLE=AUTHORIZER", sizeof("FCGI_ROLE=AUTHORIZER")-1);
|
||||
break;
|
||||
case FCGI_FILTER:
|
||||
req->env[0] = fcgi_strndup("FCGI_ROLE=FILTER", sizeof("FCGI_ROLE=FILTER")-1);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
|
||||
hdr.version < FCGI_VERSION_1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0;
|
||||
padding = hdr.paddingLength;
|
||||
|
||||
while (hdr.type == FCGI_PARAMS && len > 0) {
|
||||
if (safe_read(req, buf, len+padding) != len+padding) {
|
||||
req->keep = 0;
|
||||
return 0;
|
||||
}
|
||||
n = fcgi_get_params(req, buf, buf+len, n);
|
||||
|
||||
if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
|
||||
hdr.version < FCGI_VERSION_1) {
|
||||
req->keep = 0;
|
||||
return 0;
|
||||
}
|
||||
len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0;
|
||||
padding = hdr.paddingLength;
|
||||
}
|
||||
} else if (hdr.type == FCGI_GET_VALUES) {
|
||||
int i, j;
|
||||
int name_len;
|
||||
unsigned char *p = buf + sizeof(fcgi_header);
|
||||
|
||||
if (safe_read(req, buf, len+padding) != len+padding) {
|
||||
return 0;
|
||||
}
|
||||
n = fcgi_get_params(req, buf, buf+len, 0);
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((s = strchr(req->env[i], '=')) != NULL) {
|
||||
*s = '\0';
|
||||
name_len = s - req->env[i];
|
||||
} else {
|
||||
name_len = strlen(req->env[i]);
|
||||
}
|
||||
for (j = 0; j < sizeof(fcgi_mgmt_vars)/sizeof(fcgi_mgmt_vars[0]); j++) {
|
||||
if (strncmp(req->env[i], fcgi_mgmt_vars[j].name, name_len) == 0) {
|
||||
sprintf((char*)p, "%c%c%s%c", name_len, 1, fcgi_mgmt_vars[j].name, fcgi_mgmt_vars[j].val);
|
||||
p += name_len+3;
|
||||
}
|
||||
}
|
||||
}
|
||||
len = p - buf - sizeof(fcgi_header);
|
||||
len += fcgi_make_header((fcgi_header*)buf, FCGI_GET_VALUES_RESULT, 0, len);
|
||||
if (safe_write(req, buf, sizeof(fcgi_header)+len) != (int)sizeof(fcgi_header)+len) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fcgi_read(fcgi_request *req, char *str, int len)
|
||||
{
|
||||
int ret, n, rest;
|
||||
fcgi_header hdr;
|
||||
unsigned char buf[8];
|
||||
|
||||
n = 0;
|
||||
rest = len;
|
||||
while (rest > 0) {
|
||||
if (req->in_len == 0) {
|
||||
if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
|
||||
hdr.version < FCGI_VERSION_1 ||
|
||||
hdr.type != FCGI_STDIN) {
|
||||
req->keep = 0;
|
||||
return 0;
|
||||
}
|
||||
req->in_len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0;
|
||||
req->in_pad = hdr.paddingLength;
|
||||
if (req->in_len == 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
if (req->in_len >= rest) {
|
||||
ret = safe_read(req, str, rest);
|
||||
} else {
|
||||
ret = safe_read(req, str, req->in_len);
|
||||
}
|
||||
if (ret < 0) {
|
||||
req->keep = 0;
|
||||
return ret;
|
||||
} else if (ret > 0) {
|
||||
req->in_len -= ret;
|
||||
rest -= ret;
|
||||
n += ret;
|
||||
str += ret;
|
||||
if (req->in_len == 0) {
|
||||
if (req->in_pad) {
|
||||
if (safe_read(req, buf, req->in_pad) != req->in_pad) {
|
||||
req->keep = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline void fcgi_close(fcgi_request *req, int force, int destroy)
|
||||
{
|
||||
if (destroy) {
|
||||
char **env = req->env;
|
||||
while (*env) {
|
||||
free(*env++);
|
||||
}
|
||||
}
|
||||
if ((force || !req->keep) && req->fd >= 0) {
|
||||
#ifdef _WIN32
|
||||
HANDLE pipe = (HANDLE)_get_osfhandle(req->fd);
|
||||
|
||||
if (!force) {
|
||||
FlushFileBuffers(pipe);
|
||||
}
|
||||
DisconnectNamedPipe(pipe);
|
||||
if (is_impersonate) {
|
||||
RevertToSelf();
|
||||
}
|
||||
#else
|
||||
#if 1
|
||||
shutdown(req->fd, 2);
|
||||
#else
|
||||
close(req->fd);
|
||||
#endif
|
||||
#endif
|
||||
req->fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int fcgi_accept_request(fcgi_request *req)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE pipe;
|
||||
OVERLAPPED ov;
|
||||
#endif
|
||||
fcgi_finish_request(req);
|
||||
|
||||
while (1) {
|
||||
if (req->fd < 0) {
|
||||
while (1) {
|
||||
if (in_shutdown) {
|
||||
return -1;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
pipe = (HANDLE)_get_osfhandle(req->listen_socket);
|
||||
|
||||
FCGI_LOCK(req->listen_socket);
|
||||
ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!ConnectNamedPipe(pipe, &ov)) {
|
||||
errno = GetLastError();
|
||||
if (errno == ERROR_IO_PENDING) {
|
||||
while (WaitForSingleObject(ov.hEvent, 1000) == WAIT_TIMEOUT) {
|
||||
if (in_shutdown) {
|
||||
CloseHandle(ov.hEvent);
|
||||
FCGI_UNLOCK(req->listen_socket);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (errno != ERROR_PIPE_CONNECTED) {
|
||||
}
|
||||
}
|
||||
CloseHandle(ov.hEvent);
|
||||
if (is_impersonate && !ImpersonateNamedPipeClient(pipe)) {
|
||||
DisconnectNamedPipe(pipe);
|
||||
req->fd = -1;
|
||||
} else {
|
||||
req->fd = req->listen_socket;
|
||||
}
|
||||
FCGI_UNLOCK(req->listen_socket);
|
||||
#else
|
||||
sa_t sa;
|
||||
socklen_t len = sizeof(sa);
|
||||
|
||||
FCGI_LOCK(req->listen_socket);
|
||||
req->fd = accept(req->listen_socket, (struct sockaddr *)&sa, &len);
|
||||
FCGI_UNLOCK(req->listen_socket);
|
||||
#endif
|
||||
|
||||
if (req->fd < 0 && (in_shutdown || errno != EINTR)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
break;
|
||||
#else
|
||||
if (req->fd >= 0) {
|
||||
struct timeval tv = {1,0};
|
||||
fd_set set;
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(req->fd, &set);
|
||||
try_again:
|
||||
errno = 0;
|
||||
if (select(req->fd + 1, &set, NULL, NULL, &tv) >= 0 && FD_ISSET(req->fd, &set)) {
|
||||
break;
|
||||
}
|
||||
if (errno == EINTR) goto try_again;
|
||||
fcgi_close(req, 1, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else if (in_shutdown) {
|
||||
return -1;
|
||||
}
|
||||
if (fcgi_read_request(req)) {
|
||||
return req->fd;
|
||||
} else {
|
||||
fcgi_close(req, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline fcgi_header* open_packet(fcgi_request *req, fcgi_request_type type)
|
||||
{
|
||||
req->out_hdr = (fcgi_header*) req->out_pos;
|
||||
req->out_hdr->type = type;
|
||||
req->out_pos += sizeof(fcgi_header);
|
||||
return req->out_hdr;
|
||||
}
|
||||
|
||||
static inline void close_packet(fcgi_request *req)
|
||||
{
|
||||
if (req->out_hdr) {
|
||||
int len = req->out_pos - ((unsigned char*)req->out_hdr + sizeof(fcgi_header));
|
||||
|
||||
req->out_pos += fcgi_make_header(req->out_hdr, req->out_hdr->type, req->id, len);
|
||||
req->out_hdr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int fcgi_flush(fcgi_request *req, int close)
|
||||
{
|
||||
int len;
|
||||
|
||||
close_packet(req);
|
||||
|
||||
len = req->out_pos - req->out_buf;
|
||||
|
||||
if (close) {
|
||||
fcgi_end_request_rec *rec = (fcgi_end_request_rec*)(req->out_pos);
|
||||
|
||||
fcgi_make_header(&rec->hdr, FCGI_END_REQUEST, req->id, sizeof(fcgi_end_request));
|
||||
rec->body.appStatusB3 = 0;
|
||||
rec->body.appStatusB2 = 0;
|
||||
rec->body.appStatusB1 = 0;
|
||||
rec->body.appStatusB0 = 0;
|
||||
rec->body.protocolStatus = FCGI_REQUEST_COMPLETE;
|
||||
len += sizeof(fcgi_end_request_rec);
|
||||
}
|
||||
|
||||
if (safe_write(req, req->out_buf, len) != len) {
|
||||
req->keep = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
req->out_pos = req->out_buf;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len)
|
||||
{
|
||||
int limit, rest;
|
||||
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req->out_hdr && req->out_hdr->type != type) {
|
||||
close_packet(req);
|
||||
}
|
||||
rest = len;
|
||||
#if 0
|
||||
/* Unoptinmzed, but clear version */
|
||||
while (rest > 0) {
|
||||
limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf);
|
||||
|
||||
if (!req->out_hdr) {
|
||||
if (limit < sizeof(fcgi_header)) {
|
||||
fcgi_flush(req, 0);
|
||||
}
|
||||
open_packet(req, type);
|
||||
}
|
||||
limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf);
|
||||
if (rest < limit) {
|
||||
memcpy(req->out_pos, str, rest);
|
||||
req->out_pos += rest;
|
||||
return len;
|
||||
} else {
|
||||
memcpy(req->out_pos, str, limit);
|
||||
req->out_pos += limit;
|
||||
rest -= limit;
|
||||
str += limit;
|
||||
fcgi_flush(req, 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Optinmzed version */
|
||||
if (!req->out_hdr) {
|
||||
rest += sizeof(fcgi_header);
|
||||
}
|
||||
limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf);
|
||||
|
||||
if (rest < limit) {
|
||||
if (!req->out_hdr) {
|
||||
open_packet(req, type);
|
||||
}
|
||||
memcpy(req->out_pos, str, len);
|
||||
req->out_pos += len;
|
||||
} else if (rest - limit < sizeof(req->out_buf) - sizeof(fcgi_header)) {
|
||||
if (!req->out_hdr) {
|
||||
open_packet(req, type);
|
||||
}
|
||||
memcpy(req->out_pos, str, limit);
|
||||
req->out_pos += limit;
|
||||
fcgi_flush(req, 0);
|
||||
open_packet(req, type);
|
||||
memcpy(req->out_pos, str + limit, len - limit);
|
||||
req->out_pos += len - limit;
|
||||
} else {
|
||||
int pos = 0;
|
||||
int pad;
|
||||
|
||||
close_packet(req);
|
||||
while ((len - pos) > 0xffff) {
|
||||
open_packet(req, type);
|
||||
fcgi_make_header(req->out_hdr, type, req->id, 0xfff8);
|
||||
req->out_hdr = NULL;
|
||||
fcgi_flush(req, 0);
|
||||
if (safe_write(req, str + pos, 0xfff8) != 0xfff8) {
|
||||
req->keep = 0;
|
||||
return -1;
|
||||
}
|
||||
pos += 0xfff8;
|
||||
}
|
||||
|
||||
pad = (((len - pos) + 7) & ~7) - (len - pos);
|
||||
rest = pad ? 8 - pad : 0;
|
||||
|
||||
open_packet(req, type);
|
||||
fcgi_make_header(req->out_hdr, type, req->id, (len - pos) - rest);
|
||||
req->out_hdr = NULL;
|
||||
fcgi_flush(req, 0);
|
||||
if (safe_write(req, str + pos, (len - pos) - rest) != (len - pos) - rest) {
|
||||
req->keep = 0;
|
||||
return -1;
|
||||
}
|
||||
if (pad) {
|
||||
open_packet(req, type);
|
||||
memcpy(req->out_pos, str + len - rest, rest);
|
||||
req->out_pos += rest;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return len;
|
||||
}
|
||||
|
||||
int fcgi_finish_request(fcgi_request *req)
|
||||
{
|
||||
fcgi_flush(req, 1);
|
||||
fcgi_close(req, 0, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* fcgi_getenv_helper(char** env, const char *name, int len)
|
||||
{
|
||||
if (name && env) {
|
||||
while (*env) {
|
||||
if ((strncmp(name, *env, len) == 0) && ((*env)[len] == '=')) {
|
||||
return *env+len+1;
|
||||
}
|
||||
env++;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* fcgi_getenv(fcgi_request *req, const char* var, int var_len)
|
||||
{
|
||||
if (!req) return NULL;
|
||||
return fcgi_getenv_helper(req->env, var, var_len);
|
||||
}
|
||||
|
||||
void fcgi_putenv(fcgi_request *req, char* var, int var_len)
|
||||
{
|
||||
if (var && req) {
|
||||
char **env = req->env;
|
||||
char *s = strchr(var, '=');
|
||||
int len;
|
||||
|
||||
if (!s) return ;
|
||||
len = s - var + 1;
|
||||
while (*env) {
|
||||
if ((strncmp(var, *env, len) == 0)) {
|
||||
free(*env);
|
||||
*env = fcgi_strndup(var, var_len);
|
||||
return;
|
||||
}
|
||||
env++;
|
||||
}
|
||||
*env = fcgi_strndup(var, var_len);
|
||||
}
|
||||
}
|
||||
|
||||
int FCGX_FPrintF(FCGX_Stream stream, const char *format, ...)
|
||||
{
|
||||
int result;
|
||||
va_list args;
|
||||
char buf[4096];
|
||||
|
||||
va_start(args, format);
|
||||
result = vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
fcgi_write(stream.req, stream.type, buf, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void OS_SetImpersonate(void)
|
||||
{
|
||||
char *os_name;
|
||||
|
||||
os_name = getenv("OS");
|
||||
if (os_name && stricmp(os_name, "Windows_NT") == 0) {
|
||||
is_impersonate = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Dmitry Stogov <dmitry@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* FastCGI protocol */
|
||||
|
||||
#define FCGI_VERSION_1 1
|
||||
|
||||
#define FCGI_MAX_LENGTH 0xffff
|
||||
|
||||
#define FCGI_KEEP_CONN 1
|
||||
|
||||
typedef enum _fcgi_role {
|
||||
FCGI_RESPONDER = 1,
|
||||
FCGI_AUTHORIZER = 2,
|
||||
FCGI_FILTER = 3
|
||||
} fcgi_role;
|
||||
|
||||
typedef enum _fcgi_request_type {
|
||||
FCGI_BEGIN_REQUEST = 1, /* [in] */
|
||||
FCGI_ABORT_REQUEST = 2, /* [in] (not supported) */
|
||||
FCGI_END_REQUEST = 3, /* [out] */
|
||||
FCGI_PARAMS = 4, /* [in] environment variables */
|
||||
FCGI_STDIN = 5, /* [in] post data */
|
||||
FCGI_STDOUT = 6, /* [out] response */
|
||||
FCGI_STDERR = 7, /* [out] errors */
|
||||
FCGI_DATA = 8, /* [in] filter data (not supported) */
|
||||
FCGI_GET_VALUES = 9, /* [in] */
|
||||
FCGI_GET_VALUES_RESULT = 10 /* [out] */
|
||||
} fcgi_request_type;
|
||||
|
||||
typedef enum _fcgi_protocol_status {
|
||||
FCGI_REQUEST_COMPLETE = 0,
|
||||
FCGI_CANT_MPX_CONN = 1,
|
||||
FCGI_OVERLOADED = 2,
|
||||
FCGI_UNKNOWN_ROLE = 3
|
||||
} dcgi_protocol_status;
|
||||
|
||||
typedef struct _fcgi_header {
|
||||
unsigned char version;
|
||||
unsigned char type;
|
||||
unsigned char requestIdB1;
|
||||
unsigned char requestIdB0;
|
||||
unsigned char contentLengthB1;
|
||||
unsigned char contentLengthB0;
|
||||
unsigned char paddingLength;
|
||||
unsigned char reserved;
|
||||
} fcgi_header;
|
||||
|
||||
typedef struct _fcgi_begin_request {
|
||||
unsigned char roleB1;
|
||||
unsigned char roleB0;
|
||||
unsigned char flags;
|
||||
unsigned char reserved[5];
|
||||
} fcgi_begin_request;
|
||||
|
||||
typedef struct _fcgi_begin_request_rec {
|
||||
fcgi_header hdr;
|
||||
fcgi_begin_request body;
|
||||
} fcgi_begin_request_rec;
|
||||
|
||||
typedef struct _fcgi_end_request {
|
||||
unsigned char appStatusB3;
|
||||
unsigned char appStatusB2;
|
||||
unsigned char appStatusB1;
|
||||
unsigned char appStatusB0;
|
||||
unsigned char protocolStatus;
|
||||
unsigned char reserved[3];
|
||||
} fcgi_end_request;
|
||||
|
||||
typedef struct _fcgi_end_request_rec {
|
||||
fcgi_header hdr;
|
||||
fcgi_end_request body;
|
||||
} fcgi_end_request_rec;
|
||||
|
||||
/* FastCGI client API */
|
||||
|
||||
typedef struct _fcgi_request {
|
||||
int listen_socket;
|
||||
int fd;
|
||||
int id;
|
||||
int keep;
|
||||
|
||||
int in_len;
|
||||
int in_pad;
|
||||
|
||||
fcgi_header *out_hdr;
|
||||
unsigned char *out_pos;
|
||||
unsigned char out_buf[1024*8];
|
||||
unsigned char reserved[sizeof(fcgi_end_request_rec)];
|
||||
|
||||
char *env[128];
|
||||
} fcgi_request;
|
||||
|
||||
int fcgi_init(void);
|
||||
int fcgi_is_fastcgi(void);
|
||||
int fcgi_listen(const char *path, int backlog);
|
||||
void fcgi_init_request(fcgi_request *req, int listen_socket);
|
||||
int fcgi_accept_request(fcgi_request *req);
|
||||
int fcgi_finish_request(fcgi_request *req);
|
||||
|
||||
char* fcgi_getenv(fcgi_request *req, const char* var, int var_len);
|
||||
void fcgi_putenv(fcgi_request *req, char* var, int var_len);
|
||||
|
||||
int fcgi_read(fcgi_request *req, char *str, int len);
|
||||
|
||||
int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len);
|
||||
int fcgi_flush(fcgi_request *req, int close);
|
||||
|
||||
/* Some defines for limited libfcgi comatibility */
|
||||
|
||||
typedef struct _FCGX_Stream {
|
||||
fcgi_request *req;
|
||||
fcgi_request_type type;
|
||||
} FCGX_Stream;
|
||||
|
||||
typedef struct _FCGX_Request {
|
||||
fcgi_request req;
|
||||
FCGX_Stream in;
|
||||
FCGX_Stream out;
|
||||
FCGX_Stream err;
|
||||
char **envp;
|
||||
} FCGX_Request;
|
||||
|
||||
#define FCGX_Init()
|
||||
#define FCGX_IsCGI() (!fcgi_is_fastcgi())
|
||||
#define FCGX_OpenSocket(path, backlog) fcgi_listen(path, backlog)
|
||||
|
||||
#define FCGX_InitRequest(r, sock, flags) \
|
||||
do { \
|
||||
fcgi_init_request(&(r)->req, sock); \
|
||||
(r)->in.req = &(r)->req; \
|
||||
(r)->out.req = &(r)->req; \
|
||||
(r)->err.req = &(r)->req; \
|
||||
(r)->in.type = FCGI_STDIN; \
|
||||
(r)->out.type = FCGI_STDOUT; \
|
||||
(r)->err.type = FCGI_STDERR; \
|
||||
(r)->envp = (r)->req.env; \
|
||||
} while (0);
|
||||
|
||||
|
||||
#define FCGX_Accept_r(r) fcgi_accept_request(&(r)->req)
|
||||
#define FCGX_Finish_r(r) fcgi_finish_request(&(r)->req)
|
||||
|
||||
#define FCGX_PutStr(str, len, stream) fcgi_write((stream).req, (stream).type, str, len)
|
||||
#define FCGX_PutS(str, len, stream) fcgi_write((stream).req, (stream).type, str, len)
|
||||
#define FCGX_FFlush(stream) fcgi_flush((stream).req, 0)
|
||||
#define FCGX_GetStr(str, len, stream) fcgi_read((stream).req, str, len)
|
||||
|
||||
#define FCGX_GetParam(var, envp) fcgi_getenv_helper(envp, var, strlen(var));
|
||||
|
||||
#define FCGX_PutEnv(r, var) fcgi_putenv(&(r)->req, var, strlen(var));
|
||||
|
||||
int FCGX_FPrintF(FCGX_Stream stream, const char *format, ...);
|
||||
|
||||
/* Internal helper functions. They shouldn't be used directly. */
|
||||
|
||||
char* fcgi_getenv_helper(char** env, const char *name, int len);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
||||
Reference in new issue
Block a user