├── CREDITS
├── tests
├── bug72750.phpt
├── bug74145.xml
├── bug75055.wddx
├── bug74145.phpt
├── bug68996.phpt
├── bug27287.phpt
├── bug73173.phpt
├── bug73631.phpt
├── bug75055.phpt
├── bug73331.phpt
├── bug72860.phpt
├── bug34306.phpt
├── bug41527.phpt
├── bug72340.phpt
├── bug72799.phpt
├── bug73793.phpt
├── bug37587.phpt
├── bug70741.phpt
├── bug73831.phpt
├── bug45901.phpt
├── bug71335.phpt
├── bug52468.phpt
├── bug41283.phpt
├── 003.phpt
├── bug72749.phpt
├── bug72142.phpt
├── 002.phpt
├── bug72790.phpt
├── bug71587.phpt
├── bug72564.phpt
├── 001-64bit.phpt
├── 001.phpt
├── bug48562.phpt
├── bug70661.phpt
├── bug35410.phpt
├── bug35410_64bit.phpt
├── 004.phpt
├── 005.phpt
├── wddx.xml
├── bug73065.phpt
└── bug37569.phpt
├── config.w32
├── .gitignore
├── php_wddx.h
├── config.m4
├── php_wddx_api.h
├── LICENSE
└── wddx.c
/CREDITS:
--------------------------------------------------------------------------------
1 | WDDX
2 | Andrei Zmievski
3 |
--------------------------------------------------------------------------------
/tests/bug72750.phpt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php/pecl-text-wddx/master/tests/bug72750.phpt
--------------------------------------------------------------------------------
/tests/bug74145.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tests/bug75055.wddx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | frONt of 0 0
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tests/bug74145.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #74145 (wddx parsing empty boolean tag leads to SIGSEGV)
3 | --SKIPIF--
4 |
7 | --FILE--
8 |
13 | DONE
14 | --EXPECTF--
15 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
16 | NULL
17 | DONE
18 |
--------------------------------------------------------------------------------
/tests/bug68996.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #68996 (Invalid free of CG(interned_empty_string))
3 | --SKIPIF--
4 |
8 | --FILE--
9 | "foo" ]) . "\n";
12 | ?>
13 | --EXPECT--
14 |
15 | foo
16 |
--------------------------------------------------------------------------------
/tests/bug27287.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #27287 (segfault with deserializing object data)
3 | --SKIPIF--
4 |
5 | --FILE--
6 | abc = 'def';
12 |
13 | $string = wddx_serialize_value($foo);
14 | $bar = wddx_deserialize($string);
15 |
16 | echo "OK\n";
17 |
18 | ?>
19 | --EXPECTF--
20 | Deprecated: Function wddx_serialize_value() is deprecated in %s on line %d
21 |
22 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
23 | OK
24 |
--------------------------------------------------------------------------------
/tests/bug73173.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #73173: huge memleak when wddx_unserialize
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
10 |
11 |
12 |
19 |
20 | XML;
21 | var_dump(wddx_deserialize($xml));
22 |
23 | ?>
24 | --EXPECTF--
25 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
26 | NULL
27 |
--------------------------------------------------------------------------------
/tests/bug73631.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #73631 (Memory leak due to invalid wddx stack processing)
3 | --SKIPIF--
4 |
5 | --XFAIL--
6 | Still has memory leaks in debug build.
7 | --FILE--
8 |
11 |
12 | 1234
13 |
14 |
15 | EOF;
16 | $wddx = wddx_deserialize($xml);
17 | var_dump($wddx);
18 | ?>
19 | --EXPECTF--
20 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
21 | int(1234)
22 |
--------------------------------------------------------------------------------
/tests/bug75055.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #75055 Out-Of-Bounds Read in timelib_meridian()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
15 | --EXPECTF--
16 | 323 bytes read.
17 |
18 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
19 | array(1) {
20 | ["aDateTime"]=>
21 | string(12) "frONt of 0 0"
22 | }
23 |
--------------------------------------------------------------------------------
/tests/bug73331.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #73331 (NULL Pointer Dereference in WDDX Packet Deserialization with PDORow)
3 | --SKIPIF--
4 |
5 | --FILE--
6 | PDORow";
9 | var_dump(wddx_deserialize($wddx));
10 | ?>
11 | --EXPECTF--
12 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
13 |
14 | Warning: wddx_deserialize(): Class pdorow can not be unserialized in %s73331.php on line %d
15 | NULL
16 |
--------------------------------------------------------------------------------
/tests/bug72860.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #72860: wddx_deserialize use-after-free
3 | --SKIPIF--
4 |
9 | --FILE--
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | XML;
21 |
22 | var_dump(wddx_deserialize($xml));
23 | ?>
24 | DONE
25 | --EXPECTF--
26 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
27 | NULL
28 | DONE
29 |
--------------------------------------------------------------------------------
/tests/bug34306.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | #34306 (wddx_serialize_value() crashes with long array keys)
3 | --SKIPIF--
4 |
5 | --FILE--
6 | 1);
9 | $buf = wddx_serialize_value($var, 'name');
10 | echo "OK\n";
11 |
12 | ?>
13 | --EXPECTF--
14 | Deprecated: Function wddx_serialize_value() is deprecated in %s on line %d
15 | OK
16 |
--------------------------------------------------------------------------------
/tests/bug41527.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #41527 (WDDX deserialize numeric string array keys)
3 | --SKIPIF--
4 |
5 | --FILE--
6 | 'Zero', '+1' => 'Plus sign', ' 1' => 'Space');
8 |
9 | var_dump(wddx_deserialize(wddx_serialize_vars('data')));
10 | ?>
11 | --EXPECTF--
12 | Deprecated: Function wddx_serialize_vars() is deprecated in %s on line %d
13 |
14 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
15 | array(1) {
16 | ["data"]=>
17 | array(3) {
18 | ["01"]=>
19 | string(4) "Zero"
20 | ["+1"]=>
21 | string(9) "Plus sign"
22 | [" 1"]=>
23 | string(5) "Space"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/bug72340.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #72340: Double Free Courruption in wddx_deserialize
3 | --SKIPIF--
4 |
7 | --FILE--
8 |
11 |
12 |
13 | TEST
14 |
15 |
16 |
17 |
18 | EOF;
19 | $array = wddx_deserialize($xml);
20 | var_dump($array);
21 | ?>
22 | --EXPECTF--
23 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
24 | array(0) {
25 | }
26 |
--------------------------------------------------------------------------------
/tests/bug72799.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #72799: wddx_deserialize null dereference in php_wddx_pop_element
3 | --SKIPIF--
4 |
9 | --FILE--
10 |
14 |
15 |
16 |
17 |
18 | 1998-06-12T04:32:12+00
19 |
20 |
21 |
22 | XML;
23 |
24 | $array = wddx_deserialize($xml);
25 | var_dump($array);
26 | ?>
27 | --EXPECTF--
28 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
29 | NULL
30 |
--------------------------------------------------------------------------------
/tests/bug73793.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #73793 (WDDX uses wrong decimal separator)
3 | --SKIPIF--
4 |
10 | --FILE--
11 | 5.1]));
14 | ?>
15 | ===DONE===
16 | --EXPECTF--
17 | Deprecated: Function wddx_serialize_value() is deprecated in %s on line %d
18 | string(120) "5.1"
19 | ===DONE===
20 |
--------------------------------------------------------------------------------
/config.w32:
--------------------------------------------------------------------------------
1 | // vim:ft=javascript
2 |
3 | ARG_WITH("wddx", "WDDX support", "yes");
4 |
5 | if (PHP_WDDX == "yes" &&
6 | PHP_LIBXML == "yes" &&
7 | CHECK_HEADER_ADD_INCLUDE("libxml/parser.h", "CFLAGS_WDDX", PHP_PHP_BUILD + "\\include\\libxml2")
8 | ) {
9 | EXTENSION("wddx", "wddx.c");
10 | AC_DEFINE("HAVE_WDDX", 1, "WDDX support");
11 |
12 | if (!PHP_WDDX_SHARED) {
13 | ADD_FLAG("CFLAGS_WDDX", "/D LIBXML_STATIC");
14 | } else {
15 | if (!CHECK_LIB("libxml2.lib", "wddx")) {
16 | WARNING("wddx support can't be enabled, libxml is not found")
17 | }
18 | }
19 |
20 | ADD_EXTENSION_DEP('wddx', 'libxml');
21 | ADD_EXTENSION_DEP('wddx', 'xml')
22 | CHECK_HEADER_ADD_INCLUDE("timelib_config.h", "CFLAGS_WDDX", "ext/date/lib");
23 | }
24 |
--------------------------------------------------------------------------------
/tests/bug37587.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #37587 (var without attribute causes segfault)
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
10 |
11 |
12 |
13 |
14 |
15 | Hello World
16 |
17 |
18 |
19 |
20 |
21 | EOF
22 | ));
23 |
24 | ?>
25 | ===DONE===
26 | --EXPECTF--
27 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
28 | array(1) {
29 | [0]=>
30 | array(1) {
31 | ["test"]=>
32 | string(11) "Hello World"
33 | }
34 | }
35 | ===DONE===
36 |
--------------------------------------------------------------------------------
/tests/bug70741.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #70741 (Session WDDX Packet Deserialization Type Confusion Vulnerability)
3 | --SKIPIF--
4 |
8 | --FILE--
9 |
15 |
16 |
17 |
18 | $hashtable
19 |
20 | ";
21 | session_decode($wddx);
22 | ?>
23 | DONE
24 | --EXPECTF--
25 | Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s on line %d
26 | DONE
27 |
--------------------------------------------------------------------------------
/tests/bug73831.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #73831 (NULL Pointer Dereference while unserialize php object)
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
9 |
10 |
11 |
12 | Throwable
13 |
14 |
15 |
16 | EOF;
17 | try {
18 | $wddx = wddx_deserialize($xml);
19 | } catch(Error $e) { echo $e->getMessage(); }
20 | ?>
21 | --EXPECTF--
22 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
23 |
24 | Warning: wddx_deserialize(): Class throwable can not be instantiated in %sbug73831.php on line %d
25 | Cannot instantiate interface Throwable
26 |
--------------------------------------------------------------------------------
/tests/bug45901.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #45901 (wddx_serialize_value crash with SimpleXMLElement object)
3 | --SKIPIF--
4 |
8 | --FILE--
9 | ');
12 | $xml->addChild('test');
13 | echo wddx_serialize_value($xml, 'Variables') . "\n";
14 | echo "DONE";
15 | ?>
16 | --EXPECTF--
17 | Deprecated: Function wddx_serialize_value() is deprecated in %sbug45901.php on line %d
18 |
19 | Warning: wddx_serialize_value(): Class SimpleXMLElement can not be serialized in %sbug45901.php on line %d
20 |
21 | DONE
22 |
--------------------------------------------------------------------------------
/tests/bug71335.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #71335 (Type Confusion in WDDX Packet Deserialization)
3 | --SKIPIF--
4 |
7 | --FILE--
8 |
10 |
11 |
12 |
13 |
14 |
15 | stdClass
16 |
17 |
18 | stdClass
19 |
20 |
21 |
22 | ";
23 |
24 | $d = wddx_deserialize($x);
25 | var_dump($d);
26 | ?>
27 | DONE
28 | --EXPECTF--
29 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
30 | object(stdClass)#%d (1) {
31 | ["php_class_name"]=>
32 | string(8) "stdClass"
33 | }
34 | DONE
35 |
--------------------------------------------------------------------------------
/tests/bug52468.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #52468 (wddx_deserialize corrupts integer field value when left empty)
3 | --SKIPIF--
4 |
9 | --FILE--
10 | ";
13 |
14 | print_r(wddx_deserialize($message));
15 | print_r(wddx_deserialize($message));
16 |
17 | ?>
18 | --EXPECTF--
19 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
20 | Array
21 | (
22 | [handle] => 0
23 | )
24 |
25 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
26 | Array
27 | (
28 | [handle] => 0
29 | )
30 |
--------------------------------------------------------------------------------
/tests/bug41283.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #41283 (Bug with serializing array key that are doubles or floats)
3 | --SKIPIF--
4 |
5 | --FILE--
6 | array('1.1' => 'One 1','1.2' => 'One 2', '1.0' => 'Three')
9 | );
10 |
11 | var_dump(wddx_deserialize(wddx_serialize_vars('data')));
12 | ?>
13 | --EXPECTF--
14 | Deprecated: Function wddx_serialize_vars() is deprecated in %s on line %d
15 |
16 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
17 | array(1) {
18 | ["data"]=>
19 | array(1) {
20 | ["somearray"]=>
21 | array(3) {
22 | ["1.1"]=>
23 | string(5) "One 1"
24 | ["1.2"]=>
25 | string(5) "One 2"
26 | ["1.0"]=>
27 | string(5) "Three"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | wddx deserialize from ressource
3 | --SKIPIF--
4 |
5 | --INI--
6 | precision=14
7 | --FILE--
8 | some string756");
12 | rewind($fp);
13 | var_dump(wddx_deserialize($fp));
14 | fclose($fp);
15 | ?>
16 | --EXPECTF--
17 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
18 | array(4) {
19 | ["var1"]=>
20 | NULL
21 | ["var2"]=>
22 | string(11) "some string"
23 | ["var3"]=>
24 | int(756)
25 | ["var4"]=>
26 | bool(true)
27 | }
28 |
--------------------------------------------------------------------------------
/tests/bug72749.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #72749: wddx_deserialize allows illegal memory access
3 | --SKIPIF--
4 |
9 | --FILE--
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 2\r2004-09-10T05:52:49+00
20 |
21 |
22 |
23 |
24 | XML;
25 |
26 | $array = wddx_deserialize($xml);
27 | var_dump($array);
28 | ?>
29 | --EXPECTF--
30 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
31 | array(1) {
32 | ["aDateTime3"]=>
33 | string(24) "2
34 | 2004-09-10T05:52:49+00"
35 | }
36 |
--------------------------------------------------------------------------------
/tests/bug72142.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #72142: WDDX Packet Injection Vulnerability in wddx_serialize_value()
3 | --SKIPIF--
4 |
5 | --FILE--
6 | stdClass');
9 | var_dump($wddx);
10 | var_dump(wddx_deserialize($wddx));
11 |
12 | ?>
13 | --EXPECTF--
14 | Deprecated: Function wddx_serialize_value() is deprecated in %s on line %d
15 | string(301) "</comment></header><data><struct><var name="php_class_name"><string>stdClass</string></var></struct></data></wddxPacket>"
16 |
17 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
18 | string(0) ""
19 |
--------------------------------------------------------------------------------
/tests/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | wddx packet construction using wddx ressource
3 | --SKIPIF--
4 |
5 | --INI--
6 | precision=14
7 | --FILE--
8 |
20 | --EXPECTF--
21 | Deprecated: Function wddx_packet_start() is deprecated in %s on line %d
22 |
23 | Deprecated: Function wddx_add_vars() is deprecated in %s on line %d
24 |
25 | Deprecated: Function wddx_packet_end() is deprecated in %s on line %d
26 | some string756
27 |
--------------------------------------------------------------------------------
/tests/bug72790.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #72790: wddx_deserialize null dereference with invalid xml
3 | --SKIPIF--
4 |
9 | --FILE--
10 |
14 |
15 |
16 | |array>
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | XML;
30 |
31 | $array = wddx_deserialize($xml);
32 | var_dump($array);
33 | ?>
34 | --EXPECTF--
35 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
36 | NULL
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .deps
2 | .libs
3 | .php-version
4 | .rbenv-version
5 | acinclude.m4
6 | aclocal.m4
7 | autom4te.cache
8 | build
9 | config.guess
10 | config.h
11 | config.h.in
12 | config.log
13 | config.nice
14 | config.status
15 | config.sub
16 | configure
17 | configure.in
18 | configure.ac
19 | extras
20 | include
21 | install-sh
22 | libtool
23 | ltmain.sh
24 | ltmain.sh.backup
25 | Makefile
26 | Makefile.fragments
27 | Makefile.global
28 | Makefile.objects
29 | missing
30 | mkinstalldirs
31 | modules
32 | run-tests.php
33 | tmp-php.ini
34 | yaml.loT
35 |
36 | # General Ignores
37 | *~
38 | .#*
39 | *.
40 | *.slo
41 | *.mk
42 | *.mem
43 | *.gcda
44 | *.gcno
45 | *.la
46 | *.lo
47 | *.o
48 | *.a
49 | *.ncb
50 | *.opt
51 | *.plg
52 | *swp
53 | *.patch
54 | *.tgz
55 | *.tar.gz
56 | *.tar.bz2
57 | .FBCIndex
58 | .FBCLockFolder
59 | core
60 |
61 | # Test specific Ignores
62 | tests/*.diff
63 | tests/*.exp
64 | tests/*.log
65 | tests/*.out
66 | tests/*.php
67 | tests/*.sh
68 |
69 | # coverage
70 | /coverage.info
71 | /reports
72 |
--------------------------------------------------------------------------------
/tests/bug71587.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #71587 (Use-After-Free / Double-Free in WDDX Deserialize)
3 | --SKIPIF--
4 |
7 | --FILE--
8 |
12 |
13 |
14 |
15 |
16 | manhluat
17 |
18 |
19 |
20 |
21 |
22 | EOF;
23 |
24 | $wddx = wddx_deserialize($xml);
25 | var_dump($wddx);
26 | // Print mem leak
27 | foreach($wddx as $k=>$v)
28 | printf("Key: %s\nValue: %s\n",bin2hex($k),bin2hex($v));
29 |
30 | ?>
31 | DONE
32 | --EXPECTF--
33 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
34 | array(2) {
35 | [0]=>
36 | string(8) "manhluat"
37 | [1]=>
38 | bool(true)
39 | }
40 | Key: 30
41 | Value: 6d616e686c756174
42 | Key: 31
43 | Value: 31
44 | DONE
45 |
--------------------------------------------------------------------------------
/tests/bug72564.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #72564: wddx deserialization of boolean
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
12 | Done
13 | --EXPECTF--
14 | Deprecated: Function wddx_serialize_value() is deprecated in %s on line %d
15 |
16 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
17 | string(84) ""
18 | bool(true)
19 |
20 | Deprecated: Function wddx_serialize_value() is deprecated in %s on line %d
21 |
22 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
23 | string(85) ""
24 | bool(false)
25 |
26 | Deprecated: Function wddx_serialize_value() is deprecated in %s on line %d
27 |
28 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
29 | string(68) ""
30 | NULL
31 | Done
32 |
--------------------------------------------------------------------------------
/tests/001-64bit.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | wddx deserialization test (64-bit)
3 | --SKIPIF--
4 |
8 | --INI--
9 | precision=14
10 | --FILE--
11 |
15 | --EXPECTF--
16 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
17 | array(11) {
18 | ["aNull"]=>
19 | NULL
20 | ["aString"]=>
21 | string(8) "a string"
22 | ["aNumber"]=>
23 | float(-12.456)
24 | ["aDateTime"]=>
25 | int(897625932)
26 | ["aDateTime2"]=>
27 | int(329632332)
28 | ["aDateTime3"]=>
29 | int(2223088332)
30 | ["aBoolean"]=>
31 | bool(true)
32 | ["anArray"]=>
33 | array(2) {
34 | [0]=>
35 | int(10)
36 | [1]=>
37 | string(14) "second element"
38 | }
39 | ["aBinary"]=>
40 | string(11) "binary data"
41 | ["anObject"]=>
42 | array(2) {
43 | ["s"]=>
44 | string(8) "a string"
45 | ["n"]=>
46 | float(-12.456)
47 | }
48 | ["aRecordset"]=>
49 | array(2) {
50 | ["NAME"]=>
51 | array(2) {
52 | [0]=>
53 | string(8) "John Doe"
54 | [1]=>
55 | string(8) "Jane Doe"
56 | }
57 | ["AGE"]=>
58 | array(2) {
59 | [0]=>
60 | int(34)
61 | [1]=>
62 | int(31)
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | wddx deserialization test (32-bit)
3 | --SKIPIF--
4 |
5 |
6 | --INI--
7 | precision=14
8 | --FILE--
9 |
13 | --EXPECTF--
14 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
15 | array(11) {
16 | ["aNull"]=>
17 | NULL
18 | ["aString"]=>
19 | string(8) "a string"
20 | ["aNumber"]=>
21 | float(-12.456)
22 | ["aDateTime"]=>
23 | int(897625932)
24 | ["aDateTime2"]=>
25 | int(329632332)
26 | ["aDateTime3"]=>
27 | string(22) "2040-06-12T04:32:12+00"
28 | ["aBoolean"]=>
29 | bool(true)
30 | ["anArray"]=>
31 | array(2) {
32 | [0]=>
33 | int(10)
34 | [1]=>
35 | string(14) "second element"
36 | }
37 | ["aBinary"]=>
38 | string(11) "binary data"
39 | ["anObject"]=>
40 | array(2) {
41 | ["s"]=>
42 | string(8) "a string"
43 | ["n"]=>
44 | float(-12.456)
45 | }
46 | ["aRecordset"]=>
47 | array(2) {
48 | ["NAME"]=>
49 | array(2) {
50 | [0]=>
51 | string(8) "John Doe"
52 | [1]=>
53 | string(8) "Jane Doe"
54 | }
55 | ["AGE"]=>
56 | array(2) {
57 | [0]=>
58 | int(34)
59 | [1]=>
60 | int(31)
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/tests/bug48562.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #48562 (Reference recursion causes segfault when used in wddx_serialize_vars())
3 | --SKIPIF--
4 |
9 | --FILE--
10 |
31 | --EXPECTF--
32 | Deprecated: Function wddx_serialize_vars() is deprecated in %s on line %d
33 |
34 | Warning: wddx_serialize_vars(): recursion detected in %s on line %d
35 | string(78) ""
36 |
37 | Deprecated: Function wddx_serialize_vars() is deprecated in %s on line %d
38 | string(120) "bar"
39 |
--------------------------------------------------------------------------------
/tests/bug70661.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization)
3 | --SKIPIF--
4 |
7 | --FILE--
8 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | stdClass
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | EOT;
34 |
35 | $y = wddx_deserialize($x);
36 |
37 | for ($i = 0; $i < 5; $i++) {
38 | $v[$i] = $fakezval.$i;
39 | }
40 |
41 | var_dump($y);
42 |
43 | function ptr2str($ptr)
44 | {
45 | $out = '';
46 |
47 | for ($i = 0; $i < 8; $i++) {
48 | $out .= chr($ptr & 0xff);
49 | $ptr >>= 8;
50 | }
51 |
52 | return $out;
53 | }
54 | ?>
55 | DONE
56 | --EXPECTF--
57 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
58 | array(1) {
59 | [0]=>
60 | array(1) {
61 | ["ryat"]=>
62 | array(2) {
63 | ["php_class_name"]=>
64 | string(8) "stdClass"
65 | [0]=>
66 | NULL
67 | }
68 | }
69 | }
70 | DONE
71 |
--------------------------------------------------------------------------------
/tests/bug35410.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | #35410 (wddx_deserialize() doesn't handle large ints as keys properly)
3 | --SKIPIF--
4 |
8 | --FILE--
9 |
12 |
13 | Content Configuration File
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | 10
25 |
26 |
27 | 4
28 |
29 |
30 |
31 |
32 |
33 |
34 | desc
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | WDX;
50 |
51 | var_dump(wddx_deserialize($wddx));
52 | ?>
53 | --EXPECTF--
54 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
55 | array(1) {
56 | ["content_queries"]=>
57 | array(1) {
58 | ["content_113300831086270200"]=>
59 | array(1) {
60 | ["113301888545229100"]=>
61 | array(3) {
62 | ["max"]=>
63 | int(10)
64 | ["cache"]=>
65 | int(4)
66 | ["order"]=>
67 | array(1) {
68 | ["content_113300831086270200"]=>
69 | array(1) {
70 | ["CMS_BUILD"]=>
71 | string(4) "desc"
72 | }
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/tests/bug35410_64bit.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | #35410 (wddx_deserialize() doesn't handle large ints as keys properly)
3 | --SKIPIF--
4 |
8 | --FILE--
9 |
12 |
13 | Content Configuration File
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | 10
25 |
26 |
27 | 4
28 |
29 |
30 |
31 |
32 |
33 |
34 | desc
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | WDX;
50 |
51 | var_dump(wddx_deserialize($wddx));
52 | ?>
53 | --EXPECTF--
54 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
55 | array(1) {
56 | ["content_queries"]=>
57 | array(1) {
58 | ["content_113300831086270200"]=>
59 | array(1) {
60 | [113301888545229100]=>
61 | array(3) {
62 | ["max"]=>
63 | int(10)
64 | ["cache"]=>
65 | int(4)
66 | ["order"]=>
67 | array(1) {
68 | ["content_113300831086270200"]=>
69 | array(1) {
70 | ["CMS_BUILD"]=>
71 | string(4) "desc"
72 | }
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/php_wddx.h:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 7 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Andrei Zmievski |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | #ifndef PHP_WDDX_H
20 | #define PHP_WDDX_H
21 |
22 | #if HAVE_WDDX
23 |
24 | extern zend_module_entry wddx_module_entry;
25 | #define wddx_module_ptr &wddx_module_entry
26 |
27 | #include "php_version.h"
28 | #define PHP_WDDX_VERSION "1.0.0-dev"
29 |
30 | PHP_FUNCTION(wddx_serialize_value);
31 | PHP_FUNCTION(wddx_serialize_vars);
32 | PHP_FUNCTION(wddx_packet_start);
33 | PHP_FUNCTION(wddx_packet_end);
34 | PHP_FUNCTION(wddx_add_vars);
35 | PHP_FUNCTION(wddx_deserialize);
36 |
37 | #else
38 |
39 | #define wddx_module_ptr NULL
40 |
41 | #endif /* HAVE_WDDX */
42 |
43 | #define phpext_wddx_ptr wddx_module_ptr
44 |
45 | #endif /* !PHP_WDDX_H */
46 |
--------------------------------------------------------------------------------
/tests/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | wddx session serializer handler (serialize)
3 | --SKIPIF--
4 |
25 | --INI--
26 | precision=14
27 | session.serialize_handler=wddx
28 | session.use_cookies=0
29 | session.cache_limiter=
30 | session.save_handler=files
31 | --FILE--
32 | yes = "done"; }
38 |
39 | public function __sleep() { return array('bar', 'yes'); }
40 | }
41 |
42 | session_start();
43 |
44 | $_SESSION['data'] = array(
45 | 'test1' => true,
46 | 'test2' => 'some string',
47 | 'test3' => 654321,
48 | 'test4' => array(
49 | 'some string',
50 | true,
51 | null
52 | ),
53 | );
54 |
55 | $_SESSION['class'] = new foo();
56 | $_SESSION['class']->method();
57 |
58 | var_dump(session_encode());
59 |
60 | session_destroy();
61 | ?>
62 | --EXPECT--
63 | string(550) "some string654321some stringfoookdone"
64 |
--------------------------------------------------------------------------------
/config.m4:
--------------------------------------------------------------------------------
1 | dnl config.m4 for extension wddx
2 |
3 | PHP_ARG_ENABLE([wddx],
4 | [whether to enable WDDX support],
5 | [AS_HELP_STRING([--enable-wddx],
6 | [Enable WDDX support])])
7 |
8 | if test -z "$PHP_LIBXML_DIR"; then
9 | PHP_ARG_WITH([libxml-dir],
10 | [libxml2 install dir],
11 | [AS_HELP_STRING([--with-libxml-dir=DIR],
12 | [WDDX: libxml2 install prefix])],
13 | [no],
14 | [no])
15 | fi
16 |
17 | PHP_ARG_WITH([libexpat-dir],
18 | [libexpat dir for WDDX],
19 | [AS_HELP_STRING([--with-libexpat-dir=DIR],
20 | [WDDX: libexpat dir for XMLRPC-EPI (deprecated)])],
21 | [no],
22 | [no])
23 |
24 | if test "$PHP_WDDX" != "no"; then
25 |
26 | dnl
27 | dnl Default to libxml2 if --with-libexpat-dir is not used
28 | dnl
29 | if test "$PHP_LIBEXPAT_DIR" = "no"; then
30 | if test "$PHP_LIBXML" = "no"; then
31 | AC_MSG_ERROR([WDDX extension requires LIBXML extension, add --enable-libxml])
32 | fi
33 |
34 | PHP_SETUP_LIBXML(WDDX_SHARED_LIBADD, [
35 | if test "$PHP_XML" = "no"; then
36 | PHP_ADD_SOURCES(ext/xml, compat.c)
37 | PHP_ADD_BUILD_DIR(ext/xml)
38 | fi
39 | ], [
40 | AC_MSG_ERROR([libxml2 not found. Use --with-libxml-dir=])
41 | ])
42 | fi
43 |
44 | dnl
45 | dnl Check for expat only if --with-libexpat-dir is used.
46 | dnl
47 | if test "$PHP_LIBEXPAT_DIR" != "no"; then
48 | for i in $PHP_XML $PHP_LIBEXPAT_DIR /usr /usr/local; do
49 | if test -f "$i/$PHP_LIBDIR/libexpat.a" || test -f "$i/$PHP_LIBDIR/libexpat.$SHLIB_SUFFIX_NAME"; then
50 | EXPAT_DIR=$i
51 | break
52 | fi
53 | done
54 |
55 | if test -z "$EXPAT_DIR"; then
56 | AC_MSG_ERROR([not found. Please reinstall the expat distribution.])
57 | fi
58 |
59 | PHP_ADD_INCLUDE($EXPAT_DIR/include)
60 | PHP_ADD_LIBRARY_WITH_PATH(expat, $EXPAT_DIR/$PHP_LIBDIR, WDDX_SHARED_LIBADD)
61 | AC_DEFINE(HAVE_LIBEXPAT, 1, [ ])
62 | fi
63 |
64 | AC_DEFINE(HAVE_WDDX, 1, [ ])
65 | PHP_NEW_EXTENSION(wddx, wddx.c, $ext_shared)
66 | PHP_ADD_EXTENSION_DEP(wddx, libxml)
67 | PHP_SUBST(XMLRPC_SHARED_LIBADD)
68 | fi
69 |
--------------------------------------------------------------------------------
/tests/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | wddx session serializer handler (deserialize)
3 | --SKIPIF--
4 |
25 | --INI--
26 | precision=14
27 | session.serialize_handler=wddx
28 | session.use_cookies=0
29 | session.cache_limiter=
30 | session.save_handler=files
31 | --FILE--
32 | yes = "done"; }
37 | }
38 |
39 | session_start();
40 |
41 | session_decode("some string654321some stringfoookdone");
42 |
43 | var_dump($_SESSION);
44 |
45 | session_destroy();
46 | ?>
47 | --EXPECT--
48 | array(2) {
49 | ["data"]=>
50 | array(4) {
51 | ["test1"]=>
52 | bool(true)
53 | ["test2"]=>
54 | string(11) "some string"
55 | ["test3"]=>
56 | int(654321)
57 | ["test4"]=>
58 | array(3) {
59 | [0]=>
60 | string(11) "some string"
61 | [1]=>
62 | bool(true)
63 | [2]=>
64 | NULL
65 | }
66 | }
67 | ["class"]=>
68 | object(foo)#1 (2) {
69 | ["bar"]=>
70 | string(2) "ok"
71 | ["yes"]=>
72 | string(4) "done"
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/wddx.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | a string
12 |
13 |
14 | -12.456
15 |
16 |
17 | 1998-06-12T04:32:12+00
18 |
19 |
20 | 1980-06-12T04:32:12+00
21 |
22 |
23 | 2040-06-12T04:32:12+00
24 |
25 |
26 |
27 |
28 |
29 |
30 | 10
31 | second element
32 |
33 |
34 |
35 | YmluYXJ5IGRhdGE=
36 |
37 |
38 |
39 |
40 | a string
41 |
42 |
43 | -12.456
44 |
45 |
46 |
47 |
48 |
49 |
50 | John Doe
51 | Jane Doe
52 |
53 |
54 | 34
55 | 31
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/tests/bug73065.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #73065: Out-Of-Bounds Read in php_wddx_push_element of wddx.c
3 | --SKIPIF--
4 |
9 | --FILE--
10 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | XML;
28 |
29 | $xml2 = <<
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | XML;
40 |
41 | $xml3 = <<
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | XML;
52 |
53 | $xml4 = <<
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | XML;
64 |
65 | $xml5 = <<
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | XML;
76 |
77 | for($i=1;$i<=5;$i++) {
78 | $xmlvar = "xml$i";
79 | $array = wddx_deserialize($$xmlvar);
80 | var_dump($array);
81 | }
82 | ?>
83 | DONE
84 | --EXPECTF--
85 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
86 | array(0) {
87 | }
88 |
89 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
90 | array(0) {
91 | }
92 |
93 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
94 | array(0) {
95 | }
96 |
97 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
98 | array(1) {
99 | [0]=>
100 | array(0) {
101 | }
102 | }
103 |
104 | Deprecated: Function wddx_deserialize() is deprecated in %s on line %d
105 | array(0) {
106 | }
107 | DONE
108 |
--------------------------------------------------------------------------------
/php_wddx_api.h:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 7 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Andrei Zmievski |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | #ifndef PHP_WDDX_API_H
20 | #define PHP_WDDX_API_H
21 |
22 | #include "zend_smart_str_public.h"
23 |
24 | #define WDDX_ARRAY_S ""
25 | #define WDDX_ARRAY_E ""
26 | #define WDDX_BINARY_S ""
27 | #define WDDX_BINARY_E ""
28 | #define WDDX_BOOLEAN_TRUE ""
29 | #define WDDX_BOOLEAN_FALSE ""
30 | #define WDDX_CHAR ""
31 | #define WDDX_COMMENT_S ""
32 | #define WDDX_COMMENT_E ""
33 | #define WDDX_DATA_S ""
34 | #define WDDX_DATA_E ""
35 | #define WDDX_HEADER ""
36 | #define WDDX_HEADER_S ""
37 | #define WDDX_HEADER_E ""
38 | #define WDDX_NULL ""
39 | #define WDDX_NUMBER "%s"
40 | #define WDDX_PACKET_S ""
41 | #define WDDX_PACKET_E ""
42 | #define WDDX_STRING_S ""
43 | #define WDDX_STRING_E ""
44 | #define WDDX_STRUCT_S ""
45 | #define WDDX_STRUCT_E ""
46 | #define WDDX_VAR_S ""
47 | #define WDDX_VAR_E ""
48 |
49 | #define php_wddx_add_chunk(packet, str) smart_str_appends(packet, str)
50 | #define php_wddx_add_chunk_ex(packet, str, len) smart_str_appendl(packet, str, len)
51 | #define php_wddx_add_chunk_static(packet, str) smart_str_appendl(packet, str, sizeof(str)-1)
52 |
53 | typedef smart_str wddx_packet;
54 |
55 | wddx_packet* php_wddx_constructor(void);
56 | void php_wddx_destructor(wddx_packet *packet);
57 |
58 | void php_wddx_packet_start(wddx_packet *packet, char *comment, size_t comment_len);
59 | void php_wddx_packet_end(wddx_packet *packet);
60 |
61 | void php_wddx_serialize_var(wddx_packet *packet, zval *var, zend_string *name);
62 | int php_wddx_deserialize_ex(const char *, size_t, zval *return_value);
63 | #define php_wddx_gather(packet) estrndup(packet->c, packet->len)
64 |
65 | #endif /* PHP_WDDX_API_H */
66 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | --------------------------------------------------------------------
2 | The PHP License, version 3.01
3 | Copyright (c) 1999 - 2019 The PHP Group. All rights reserved.
4 | --------------------------------------------------------------------
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, is permitted provided that the following conditions
8 | are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in
15 | the documentation and/or other materials provided with the
16 | distribution.
17 |
18 | 3. The name "PHP" must not be used to endorse or promote products
19 | derived from this software without prior written permission. For
20 | written permission, please contact group@php.net.
21 |
22 | 4. Products derived from this software may not be called "PHP", nor
23 | may "PHP" appear in their name, without prior written permission
24 | from group@php.net. You may indicate that your software works in
25 | conjunction with PHP by saying "Foo for PHP" instead of calling
26 | it "PHP Foo" or "phpfoo"
27 |
28 | 5. The PHP Group may publish revised and/or new versions of the
29 | license from time to time. Each version will be given a
30 | distinguishing version number.
31 | Once covered code has been published under a particular version
32 | of the license, you may always continue to use it under the terms
33 | of that version. You may also choose to use such covered code
34 | under the terms of any subsequent version of the license
35 | published by the PHP Group. No one other than the PHP Group has
36 | the right to modify the terms applicable to covered code created
37 | under this License.
38 |
39 | 6. Redistributions of any form whatsoever must retain the following
40 | acknowledgment:
41 | "This product includes PHP software, freely available from
42 | ".
43 |
44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55 | OF THE POSSIBILITY OF SUCH DAMAGE.
56 |
57 | --------------------------------------------------------------------
58 |
59 | This software consists of voluntary contributions made by many
60 | individuals on behalf of the PHP Group.
61 |
62 | The PHP Group can be contacted via Email at group@php.net.
63 |
64 | For more information on the PHP Group and the PHP project,
65 | please see .
66 |
67 | PHP includes the Zend Engine, freely available at
68 | .
69 |
--------------------------------------------------------------------------------
/tests/bug37569.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #37569 (WDDX incorrectly encodes high-ascii characters)
3 | --SKIPIF--
4 |
5 | --INI--
6 | error_reporting=E_ALL & ~E_DEPRECATED
7 | --FILE--
8 | = 0xc0) {
11 | $v = chr(0xc3) . chr($i - 64);
12 | } elseif ($i >= 0x80) {
13 | $v = chr(0xc2) . chr($i);
14 | } else {
15 | $v = chr($i); // make it UTF-8
16 | }
17 | $ret = wddx_serialize_value($v);
18 | echo $ret . "\n";
19 | var_dump(bin2hex($v), bin2hex(wddx_deserialize($ret)), $v == wddx_deserialize($ret));
20 | }
21 | ?>
22 | --EXPECT--
23 | A
24 | string(2) "41"
25 | string(2) "41"
26 | bool(true)
27 | B
28 | string(2) "42"
29 | string(2) "42"
30 | bool(true)
31 | C
32 | string(2) "43"
33 | string(2) "43"
34 | bool(true)
35 | D
36 | string(2) "44"
37 | string(2) "44"
38 | bool(true)
39 | E
40 | string(2) "45"
41 | string(2) "45"
42 | bool(true)
43 | F
44 | string(2) "46"
45 | string(2) "46"
46 | bool(true)
47 | G
48 | string(2) "47"
49 | string(2) "47"
50 | bool(true)
51 | H
52 | string(2) "48"
53 | string(2) "48"
54 | bool(true)
55 | I
56 | string(2) "49"
57 | string(2) "49"
58 | bool(true)
59 | J
60 | string(2) "4a"
61 | string(2) "4a"
62 | bool(true)
63 | K
64 | string(2) "4b"
65 | string(2) "4b"
66 | bool(true)
67 | L
68 | string(2) "4c"
69 | string(2) "4c"
70 | bool(true)
71 | M
72 | string(2) "4d"
73 | string(2) "4d"
74 | bool(true)
75 | N
76 | string(2) "4e"
77 | string(2) "4e"
78 | bool(true)
79 | O
80 | string(2) "4f"
81 | string(2) "4f"
82 | bool(true)
83 | P
84 | string(2) "50"
85 | string(2) "50"
86 | bool(true)
87 | Q
88 | string(2) "51"
89 | string(2) "51"
90 | bool(true)
91 | R
92 | string(2) "52"
93 | string(2) "52"
94 | bool(true)
95 | S
96 | string(2) "53"
97 | string(2) "53"
98 | bool(true)
99 | T
100 | string(2) "54"
101 | string(2) "54"
102 | bool(true)
103 | U
104 | string(2) "55"
105 | string(2) "55"
106 | bool(true)
107 | V
108 | string(2) "56"
109 | string(2) "56"
110 | bool(true)
111 | W
112 | string(2) "57"
113 | string(2) "57"
114 | bool(true)
115 | X
116 | string(2) "58"
117 | string(2) "58"
118 | bool(true)
119 | Y
120 | string(2) "59"
121 | string(2) "59"
122 | bool(true)
123 | Z
124 | string(2) "5a"
125 | string(2) "5a"
126 | bool(true)
127 | [
128 | string(2) "5b"
129 | string(2) "5b"
130 | bool(true)
131 | \
132 | string(2) "5c"
133 | string(2) "5c"
134 | bool(true)
135 | ]
136 | string(2) "5d"
137 | string(2) "5d"
138 | bool(true)
139 | ^
140 | string(2) "5e"
141 | string(2) "5e"
142 | bool(true)
143 | _
144 | string(2) "5f"
145 | string(2) "5f"
146 | bool(true)
147 | `
148 | string(2) "60"
149 | string(2) "60"
150 | bool(true)
151 | a
152 | string(2) "61"
153 | string(2) "61"
154 | bool(true)
155 | b
156 | string(2) "62"
157 | string(2) "62"
158 | bool(true)
159 | c
160 | string(2) "63"
161 | string(2) "63"
162 | bool(true)
163 | d
164 | string(2) "64"
165 | string(2) "64"
166 | bool(true)
167 | e
168 | string(2) "65"
169 | string(2) "65"
170 | bool(true)
171 | f
172 | string(2) "66"
173 | string(2) "66"
174 | bool(true)
175 | g
176 | string(2) "67"
177 | string(2) "67"
178 | bool(true)
179 | h
180 | string(2) "68"
181 | string(2) "68"
182 | bool(true)
183 | i
184 | string(2) "69"
185 | string(2) "69"
186 | bool(true)
187 | j
188 | string(2) "6a"
189 | string(2) "6a"
190 | bool(true)
191 | k
192 | string(2) "6b"
193 | string(2) "6b"
194 | bool(true)
195 | l
196 | string(2) "6c"
197 | string(2) "6c"
198 | bool(true)
199 | m
200 | string(2) "6d"
201 | string(2) "6d"
202 | bool(true)
203 | n
204 | string(2) "6e"
205 | string(2) "6e"
206 | bool(true)
207 | o
208 | string(2) "6f"
209 | string(2) "6f"
210 | bool(true)
211 | p
212 | string(2) "70"
213 | string(2) "70"
214 | bool(true)
215 | q
216 | string(2) "71"
217 | string(2) "71"
218 | bool(true)
219 | r
220 | string(2) "72"
221 | string(2) "72"
222 | bool(true)
223 | s
224 | string(2) "73"
225 | string(2) "73"
226 | bool(true)
227 | t
228 | string(2) "74"
229 | string(2) "74"
230 | bool(true)
231 | u
232 | string(2) "75"
233 | string(2) "75"
234 | bool(true)
235 | v
236 | string(2) "76"
237 | string(2) "76"
238 | bool(true)
239 | w
240 | string(2) "77"
241 | string(2) "77"
242 | bool(true)
243 | x
244 | string(2) "78"
245 | string(2) "78"
246 | bool(true)
247 | y
248 | string(2) "79"
249 | string(2) "79"
250 | bool(true)
251 | z
252 | string(2) "7a"
253 | string(2) "7a"
254 | bool(true)
255 | {
256 | string(2) "7b"
257 | string(2) "7b"
258 | bool(true)
259 | |
260 | string(2) "7c"
261 | string(2) "7c"
262 | bool(true)
263 | }
264 | string(2) "7d"
265 | string(2) "7d"
266 | bool(true)
267 | ~
268 | string(2) "7e"
269 | string(2) "7e"
270 | bool(true)
271 |
272 | string(2) "7f"
273 | string(2) "7f"
274 | bool(true)
275 |
276 | string(4) "c280"
277 | string(4) "c280"
278 | bool(true)
279 |
280 | string(4) "c281"
281 | string(4) "c281"
282 | bool(true)
283 |
284 | string(4) "c282"
285 | string(4) "c282"
286 | bool(true)
287 |
288 | string(4) "c283"
289 | string(4) "c283"
290 | bool(true)
291 |
292 | string(4) "c284"
293 | string(4) "c284"
294 | bool(true)
295 |
296 | string(4) "c285"
297 | string(4) "c285"
298 | bool(true)
299 |
300 | string(4) "c286"
301 | string(4) "c286"
302 | bool(true)
303 |
304 | string(4) "c287"
305 | string(4) "c287"
306 | bool(true)
307 |
308 | string(4) "c288"
309 | string(4) "c288"
310 | bool(true)
311 |
312 | string(4) "c289"
313 | string(4) "c289"
314 | bool(true)
315 |
316 | string(4) "c28a"
317 | string(4) "c28a"
318 | bool(true)
319 |
320 | string(4) "c28b"
321 | string(4) "c28b"
322 | bool(true)
323 |
324 | string(4) "c28c"
325 | string(4) "c28c"
326 | bool(true)
327 |
328 | string(4) "c28d"
329 | string(4) "c28d"
330 | bool(true)
331 |
332 | string(4) "c28e"
333 | string(4) "c28e"
334 | bool(true)
335 |
336 | string(4) "c28f"
337 | string(4) "c28f"
338 | bool(true)
339 |
340 | string(4) "c290"
341 | string(4) "c290"
342 | bool(true)
343 |
344 | string(4) "c291"
345 | string(4) "c291"
346 | bool(true)
347 |
348 | string(4) "c292"
349 | string(4) "c292"
350 | bool(true)
351 |
352 | string(4) "c293"
353 | string(4) "c293"
354 | bool(true)
355 |
356 | string(4) "c294"
357 | string(4) "c294"
358 | bool(true)
359 |
360 | string(4) "c295"
361 | string(4) "c295"
362 | bool(true)
363 |
364 | string(4) "c296"
365 | string(4) "c296"
366 | bool(true)
367 |
368 | string(4) "c297"
369 | string(4) "c297"
370 | bool(true)
371 |
372 | string(4) "c298"
373 | string(4) "c298"
374 | bool(true)
375 |
376 | string(4) "c299"
377 | string(4) "c299"
378 | bool(true)
379 |
380 | string(4) "c29a"
381 | string(4) "c29a"
382 | bool(true)
383 |
384 | string(4) "c29b"
385 | string(4) "c29b"
386 | bool(true)
387 |
388 | string(4) "c29c"
389 | string(4) "c29c"
390 | bool(true)
391 |
392 | string(4) "c29d"
393 | string(4) "c29d"
394 | bool(true)
395 |
396 | string(4) "c29e"
397 | string(4) "c29e"
398 | bool(true)
399 |
400 | string(4) "c29f"
401 | string(4) "c29f"
402 | bool(true)
403 |
404 | string(4) "c2a0"
405 | string(4) "c2a0"
406 | bool(true)
407 | ¡
408 | string(4) "c2a1"
409 | string(4) "c2a1"
410 | bool(true)
411 | ¢
412 | string(4) "c2a2"
413 | string(4) "c2a2"
414 | bool(true)
415 | £
416 | string(4) "c2a3"
417 | string(4) "c2a3"
418 | bool(true)
419 | ¤
420 | string(4) "c2a4"
421 | string(4) "c2a4"
422 | bool(true)
423 | ¥
424 | string(4) "c2a5"
425 | string(4) "c2a5"
426 | bool(true)
427 | ¦
428 | string(4) "c2a6"
429 | string(4) "c2a6"
430 | bool(true)
431 | §
432 | string(4) "c2a7"
433 | string(4) "c2a7"
434 | bool(true)
435 | ¨
436 | string(4) "c2a8"
437 | string(4) "c2a8"
438 | bool(true)
439 | ©
440 | string(4) "c2a9"
441 | string(4) "c2a9"
442 | bool(true)
443 | ª
444 | string(4) "c2aa"
445 | string(4) "c2aa"
446 | bool(true)
447 | «
448 | string(4) "c2ab"
449 | string(4) "c2ab"
450 | bool(true)
451 | ¬
452 | string(4) "c2ac"
453 | string(4) "c2ac"
454 | bool(true)
455 |
456 | string(4) "c2ad"
457 | string(4) "c2ad"
458 | bool(true)
459 | ®
460 | string(4) "c2ae"
461 | string(4) "c2ae"
462 | bool(true)
463 | ¯
464 | string(4) "c2af"
465 | string(4) "c2af"
466 | bool(true)
467 | °
468 | string(4) "c2b0"
469 | string(4) "c2b0"
470 | bool(true)
471 | ±
472 | string(4) "c2b1"
473 | string(4) "c2b1"
474 | bool(true)
475 | ²
476 | string(4) "c2b2"
477 | string(4) "c2b2"
478 | bool(true)
479 | ³
480 | string(4) "c2b3"
481 | string(4) "c2b3"
482 | bool(true)
483 | ´
484 | string(4) "c2b4"
485 | string(4) "c2b4"
486 | bool(true)
487 | µ
488 | string(4) "c2b5"
489 | string(4) "c2b5"
490 | bool(true)
491 | ¶
492 | string(4) "c2b6"
493 | string(4) "c2b6"
494 | bool(true)
495 | ·
496 | string(4) "c2b7"
497 | string(4) "c2b7"
498 | bool(true)
499 | ¸
500 | string(4) "c2b8"
501 | string(4) "c2b8"
502 | bool(true)
503 | ¹
504 | string(4) "c2b9"
505 | string(4) "c2b9"
506 | bool(true)
507 | º
508 | string(4) "c2ba"
509 | string(4) "c2ba"
510 | bool(true)
511 | »
512 | string(4) "c2bb"
513 | string(4) "c2bb"
514 | bool(true)
515 | ¼
516 | string(4) "c2bc"
517 | string(4) "c2bc"
518 | bool(true)
519 | ½
520 | string(4) "c2bd"
521 | string(4) "c2bd"
522 | bool(true)
523 | ¾
524 | string(4) "c2be"
525 | string(4) "c2be"
526 | bool(true)
527 | ¿
528 | string(4) "c2bf"
529 | string(4) "c2bf"
530 | bool(true)
531 | À
532 | string(4) "c380"
533 | string(4) "c380"
534 | bool(true)
535 | Á
536 | string(4) "c381"
537 | string(4) "c381"
538 | bool(true)
539 | Â
540 | string(4) "c382"
541 | string(4) "c382"
542 | bool(true)
543 | Ã
544 | string(4) "c383"
545 | string(4) "c383"
546 | bool(true)
547 | Ä
548 | string(4) "c384"
549 | string(4) "c384"
550 | bool(true)
551 | Å
552 | string(4) "c385"
553 | string(4) "c385"
554 | bool(true)
555 | Æ
556 | string(4) "c386"
557 | string(4) "c386"
558 | bool(true)
559 | Ç
560 | string(4) "c387"
561 | string(4) "c387"
562 | bool(true)
563 | È
564 | string(4) "c388"
565 | string(4) "c388"
566 | bool(true)
567 | É
568 | string(4) "c389"
569 | string(4) "c389"
570 | bool(true)
571 | Ê
572 | string(4) "c38a"
573 | string(4) "c38a"
574 | bool(true)
575 | Ë
576 | string(4) "c38b"
577 | string(4) "c38b"
578 | bool(true)
579 | Ì
580 | string(4) "c38c"
581 | string(4) "c38c"
582 | bool(true)
583 | Í
584 | string(4) "c38d"
585 | string(4) "c38d"
586 | bool(true)
587 | Î
588 | string(4) "c38e"
589 | string(4) "c38e"
590 | bool(true)
591 | Ï
592 | string(4) "c38f"
593 | string(4) "c38f"
594 | bool(true)
595 | Ð
596 | string(4) "c390"
597 | string(4) "c390"
598 | bool(true)
599 | Ñ
600 | string(4) "c391"
601 | string(4) "c391"
602 | bool(true)
603 | Ò
604 | string(4) "c392"
605 | string(4) "c392"
606 | bool(true)
607 | Ó
608 | string(4) "c393"
609 | string(4) "c393"
610 | bool(true)
611 | Ô
612 | string(4) "c394"
613 | string(4) "c394"
614 | bool(true)
615 | Õ
616 | string(4) "c395"
617 | string(4) "c395"
618 | bool(true)
619 | Ö
620 | string(4) "c396"
621 | string(4) "c396"
622 | bool(true)
623 | ×
624 | string(4) "c397"
625 | string(4) "c397"
626 | bool(true)
627 | Ø
628 | string(4) "c398"
629 | string(4) "c398"
630 | bool(true)
631 | Ù
632 | string(4) "c399"
633 | string(4) "c399"
634 | bool(true)
635 | Ú
636 | string(4) "c39a"
637 | string(4) "c39a"
638 | bool(true)
639 | Û
640 | string(4) "c39b"
641 | string(4) "c39b"
642 | bool(true)
643 | Ü
644 | string(4) "c39c"
645 | string(4) "c39c"
646 | bool(true)
647 | Ý
648 | string(4) "c39d"
649 | string(4) "c39d"
650 | bool(true)
651 | Þ
652 | string(4) "c39e"
653 | string(4) "c39e"
654 | bool(true)
655 | ß
656 | string(4) "c39f"
657 | string(4) "c39f"
658 | bool(true)
659 | à
660 | string(4) "c3a0"
661 | string(4) "c3a0"
662 | bool(true)
663 | á
664 | string(4) "c3a1"
665 | string(4) "c3a1"
666 | bool(true)
667 | â
668 | string(4) "c3a2"
669 | string(4) "c3a2"
670 | bool(true)
671 | ã
672 | string(4) "c3a3"
673 | string(4) "c3a3"
674 | bool(true)
675 | ä
676 | string(4) "c3a4"
677 | string(4) "c3a4"
678 | bool(true)
679 | å
680 | string(4) "c3a5"
681 | string(4) "c3a5"
682 | bool(true)
683 | æ
684 | string(4) "c3a6"
685 | string(4) "c3a6"
686 | bool(true)
687 | ç
688 | string(4) "c3a7"
689 | string(4) "c3a7"
690 | bool(true)
691 | è
692 | string(4) "c3a8"
693 | string(4) "c3a8"
694 | bool(true)
695 | é
696 | string(4) "c3a9"
697 | string(4) "c3a9"
698 | bool(true)
699 | ê
700 | string(4) "c3aa"
701 | string(4) "c3aa"
702 | bool(true)
703 | ë
704 | string(4) "c3ab"
705 | string(4) "c3ab"
706 | bool(true)
707 | ì
708 | string(4) "c3ac"
709 | string(4) "c3ac"
710 | bool(true)
711 | í
712 | string(4) "c3ad"
713 | string(4) "c3ad"
714 | bool(true)
715 | î
716 | string(4) "c3ae"
717 | string(4) "c3ae"
718 | bool(true)
719 | ï
720 | string(4) "c3af"
721 | string(4) "c3af"
722 | bool(true)
723 | ð
724 | string(4) "c3b0"
725 | string(4) "c3b0"
726 | bool(true)
727 | ñ
728 | string(4) "c3b1"
729 | string(4) "c3b1"
730 | bool(true)
731 | ò
732 | string(4) "c3b2"
733 | string(4) "c3b2"
734 | bool(true)
735 | ó
736 | string(4) "c3b3"
737 | string(4) "c3b3"
738 | bool(true)
739 | ô
740 | string(4) "c3b4"
741 | string(4) "c3b4"
742 | bool(true)
743 | õ
744 | string(4) "c3b5"
745 | string(4) "c3b5"
746 | bool(true)
747 | ö
748 | string(4) "c3b6"
749 | string(4) "c3b6"
750 | bool(true)
751 | ÷
752 | string(4) "c3b7"
753 | string(4) "c3b7"
754 | bool(true)
755 | ø
756 | string(4) "c3b8"
757 | string(4) "c3b8"
758 | bool(true)
759 | ù
760 | string(4) "c3b9"
761 | string(4) "c3b9"
762 | bool(true)
763 | ú
764 | string(4) "c3ba"
765 | string(4) "c3ba"
766 | bool(true)
767 | û
768 | string(4) "c3bb"
769 | string(4) "c3bb"
770 | bool(true)
771 | ü
772 | string(4) "c3bc"
773 | string(4) "c3bc"
774 | bool(true)
775 | ý
776 | string(4) "c3bd"
777 | string(4) "c3bd"
778 | bool(true)
779 | þ
780 | string(4) "c3be"
781 | string(4) "c3be"
782 | bool(true)
783 | ÿ
784 | string(4) "c3bf"
785 | string(4) "c3bf"
786 | bool(true)
787 |
--------------------------------------------------------------------------------
/wddx.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | PHP Version 7 |
4 | +----------------------------------------------------------------------+
5 | | Copyright (c) The PHP Group |
6 | +----------------------------------------------------------------------+
7 | | This source file is subject to version 3.01 of the PHP license, |
8 | | that is bundled with this package in the file LICENSE, and is |
9 | | available through the world-wide-web at the following url: |
10 | | http://www.php.net/license/3_01.txt |
11 | | If you did not receive a copy of the PHP license and are unable to |
12 | | obtain it through the world-wide-web, please send a note to |
13 | | license@php.net so we can mail you a copy immediately. |
14 | +----------------------------------------------------------------------+
15 | | Author: Andrei Zmievski |
16 | +----------------------------------------------------------------------+
17 | */
18 |
19 | #ifdef HAVE_CONFIG_H
20 | #include "config.h"
21 | #endif
22 |
23 | #include "php.h"
24 |
25 | #if HAVE_WDDX
26 |
27 | #include "ext/xml/expat_compat.h"
28 | #include "php_wddx.h"
29 | #include "php_wddx_api.h"
30 |
31 | #include "ext/xml/php_xml.h"
32 | #include "ext/standard/php_incomplete_class.h"
33 | #include "ext/standard/base64.h"
34 | #include "ext/standard/info.h"
35 | #include "zend_smart_str.h"
36 | #include "ext/standard/html.h"
37 | #include "ext/standard/php_string.h"
38 | #include "ext/date/php_date.h"
39 | #include "zend_globals.h"
40 |
41 | #define WDDX_BUF_LEN 256
42 | #define PHP_CLASS_NAME_VAR "php_class_name"
43 |
44 | #define EL_ARRAY "array"
45 | #define EL_BINARY "binary"
46 | #define EL_BOOLEAN "boolean"
47 | #define EL_CHAR "char"
48 | #define EL_CHAR_CODE "code"
49 | #define EL_NULL "null"
50 | #define EL_NUMBER "number"
51 | #define EL_PACKET "wddxPacket"
52 | #define EL_STRING "string"
53 | #define EL_STRUCT "struct"
54 | #define EL_VALUE "value"
55 | #define EL_VAR "var"
56 | #define EL_NAME "name"
57 | #define EL_VERSION "version"
58 | #define EL_RECORDSET "recordset"
59 | #define EL_FIELD "field"
60 | #define EL_DATETIME "dateTime"
61 |
62 | #define php_wddx_deserialize(a,b) \
63 | php_wddx_deserialize_ex(Z_STRVAL_P(a), Z_STRLEN_P(a), (b))
64 |
65 | #define SET_STACK_VARNAME \
66 | if (stack->varname) { \
67 | ent.varname = estrdup(stack->varname); \
68 | efree(stack->varname); \
69 | stack->varname = NULL; \
70 | } else \
71 | ent.varname = NULL; \
72 |
73 | static int le_wddx;
74 |
75 | typedef struct {
76 | zval data;
77 | enum {
78 | ST_ARRAY,
79 | ST_BOOLEAN,
80 | ST_NULL,
81 | ST_NUMBER,
82 | ST_STRING,
83 | ST_BINARY,
84 | ST_STRUCT,
85 | ST_RECORDSET,
86 | ST_FIELD,
87 | ST_DATETIME
88 | } type;
89 | char *varname;
90 | } st_entry;
91 |
92 | typedef struct {
93 | int top, max;
94 | char *varname;
95 | zend_bool done;
96 | void **elements;
97 | } wddx_stack;
98 |
99 |
100 | static void php_wddx_process_data(void *user_data, const XML_Char *s, int len);
101 |
102 | /* {{{ arginfo */
103 | ZEND_BEGIN_ARG_INFO_EX(arginfo_wddx_serialize_value, 0, 0, 1)
104 | ZEND_ARG_INFO(0, var)
105 | ZEND_ARG_INFO(0, comment)
106 | ZEND_END_ARG_INFO()
107 |
108 | ZEND_BEGIN_ARG_INFO_EX(arginfo_wddx_serialize_vars, 0, 0, 1)
109 | ZEND_ARG_VARIADIC_INFO(0, var_names)
110 | ZEND_END_ARG_INFO()
111 |
112 | ZEND_BEGIN_ARG_INFO_EX(arginfo_wddx_serialize_start, 0, 0, 0)
113 | ZEND_ARG_INFO(0, comment)
114 | ZEND_END_ARG_INFO()
115 |
116 | ZEND_BEGIN_ARG_INFO_EX(arginfo_wddx_packet_end, 0, 0, 1)
117 | ZEND_ARG_INFO(0, packet_id)
118 | ZEND_END_ARG_INFO()
119 |
120 | ZEND_BEGIN_ARG_INFO_EX(arginfo_wddx_add_vars, 0, 0, 2)
121 | ZEND_ARG_INFO(0, packet_id)
122 | ZEND_ARG_VARIADIC_INFO(0, var_names)
123 | ZEND_END_ARG_INFO()
124 |
125 | ZEND_BEGIN_ARG_INFO_EX(arginfo_wddx_deserialize, 0, 0, 1)
126 | ZEND_ARG_INFO(0, packet)
127 | ZEND_END_ARG_INFO()
128 | /* }}} */
129 |
130 | /* {{{ wddx_functions[]
131 | */
132 | static const zend_function_entry wddx_functions[] = {
133 | PHP_DEP_FE(wddx_serialize_value, arginfo_wddx_serialize_value)
134 | PHP_DEP_FE(wddx_serialize_vars, arginfo_wddx_serialize_vars)
135 | PHP_DEP_FE(wddx_packet_start, arginfo_wddx_serialize_start)
136 | PHP_DEP_FE(wddx_packet_end, arginfo_wddx_packet_end)
137 | PHP_DEP_FE(wddx_add_vars, arginfo_wddx_add_vars)
138 | PHP_DEP_FE(wddx_deserialize, arginfo_wddx_deserialize)
139 | PHP_FE_END
140 | };
141 | /* }}} */
142 |
143 | PHP_MINIT_FUNCTION(wddx);
144 | PHP_MINFO_FUNCTION(wddx);
145 |
146 | /* {{{ dynamically loadable module stuff */
147 | #ifdef COMPILE_DL_WDDX
148 | ZEND_GET_MODULE(wddx)
149 | #endif /* COMPILE_DL_WDDX */
150 | /* }}} */
151 |
152 | static const zend_module_dep wddx_deps[] = {
153 | ZEND_MOD_REQUIRED("xml")
154 | ZEND_MOD_END
155 | };
156 |
157 |
158 | /* {{{ wddx_module_entry
159 | */
160 | zend_module_entry wddx_module_entry = {
161 | STANDARD_MODULE_HEADER_EX,
162 | NULL,
163 | wddx_deps,
164 | "wddx",
165 | wddx_functions,
166 | PHP_MINIT(wddx),
167 | NULL,
168 | NULL,
169 | NULL,
170 | PHP_MINFO(wddx),
171 | PHP_WDDX_VERSION,
172 | STANDARD_MODULE_PROPERTIES
173 | };
174 | /* }}} */
175 |
176 | /* {{{ wddx_stack_init
177 | */
178 | static int wddx_stack_init(wddx_stack *stack)
179 | {
180 | stack->top = 0;
181 | stack->elements = (void **) safe_emalloc(sizeof(void **), STACK_BLOCK_SIZE, 0);
182 | stack->max = STACK_BLOCK_SIZE;
183 | stack->varname = NULL;
184 | stack->done = 0;
185 |
186 | return SUCCESS;
187 | }
188 | /* }}} */
189 |
190 | /* {{{ wddx_stack_push
191 | */
192 | static int wddx_stack_push(wddx_stack *stack, void *element, int size)
193 | {
194 | if (stack->top >= stack->max) { /* we need to allocate more memory */
195 | stack->elements = (void **) erealloc(stack->elements,
196 | (sizeof(void **) * (stack->max += STACK_BLOCK_SIZE)));
197 | }
198 | stack->elements[stack->top] = (void *) emalloc(size);
199 | memcpy(stack->elements[stack->top], element, size);
200 | return stack->top++;
201 | }
202 | /* }}} */
203 |
204 | /* {{{ wddx_stack_top
205 | */
206 | static int wddx_stack_top(wddx_stack *stack, void **element)
207 | {
208 | if (stack->top > 0) {
209 | *element = stack->elements[stack->top - 1];
210 | return SUCCESS;
211 | } else {
212 | *element = NULL;
213 | return FAILURE;
214 | }
215 | }
216 | /* }}} */
217 |
218 | /* {{{ wddx_stack_is_empty
219 | */
220 | static int wddx_stack_is_empty(wddx_stack *stack)
221 | {
222 | if (stack->top == 0) {
223 | return 1;
224 | } else {
225 | return 0;
226 | }
227 | }
228 | /* }}} */
229 |
230 | /* {{{ wddx_stack_destroy
231 | */
232 | static int wddx_stack_destroy(wddx_stack *stack)
233 | {
234 | register int i;
235 |
236 | if (stack->elements) {
237 | for (i = 0; i < stack->top; i++) {
238 | if (Z_TYPE(((st_entry *)stack->elements[i])->data) != IS_UNDEF
239 | && ((st_entry *)stack->elements[i])->type != ST_FIELD) {
240 | zval_ptr_dtor(&((st_entry *)stack->elements[i])->data);
241 | }
242 | if (((st_entry *)stack->elements[i])->varname) {
243 | efree(((st_entry *)stack->elements[i])->varname);
244 | }
245 | efree(stack->elements[i]);
246 | }
247 | efree(stack->elements);
248 | }
249 | if (stack->varname) {
250 | efree(stack->varname);
251 | }
252 | return SUCCESS;
253 | }
254 | /* }}} */
255 |
256 | /* {{{ release_wddx_packet_rsrc
257 | */
258 | static void release_wddx_packet_rsrc(zend_resource *rsrc)
259 | {
260 | smart_str *str = (smart_str *)rsrc->ptr;
261 | smart_str_free(str);
262 | efree(str);
263 | }
264 | /* }}} */
265 |
266 | #include "ext/session/php_session.h"
267 |
268 | #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
269 | /* {{{ PS_SERIALIZER_ENCODE_FUNC
270 | */
271 | PS_SERIALIZER_ENCODE_FUNC(wddx)
272 | {
273 | wddx_packet *packet;
274 | zend_string *str;
275 | PS_ENCODE_VARS;
276 |
277 | packet = php_wddx_constructor();
278 |
279 | php_wddx_packet_start(packet, NULL, 0);
280 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
281 |
282 | PS_ENCODE_LOOP(
283 | php_wddx_serialize_var(packet, struc, key);
284 | );
285 |
286 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
287 | php_wddx_packet_end(packet);
288 | smart_str_0(packet);
289 | str = zend_string_copy(packet->s);
290 | php_wddx_destructor(packet);
291 |
292 | return str;
293 | }
294 | /* }}} */
295 |
296 | /* {{{ PS_SERIALIZER_DECODE_FUNC
297 | */
298 | PS_SERIALIZER_DECODE_FUNC(wddx)
299 | {
300 | zval retval;
301 | zval *ent;
302 | zend_string *key;
303 | zend_ulong idx;
304 | int ret;
305 |
306 | if (vallen == 0) {
307 | return SUCCESS;
308 | }
309 |
310 | ZVAL_UNDEF(&retval);
311 | if ((ret = php_wddx_deserialize_ex(val, vallen, &retval)) == SUCCESS) {
312 | if (Z_TYPE(retval) != IS_ARRAY) {
313 | zval_ptr_dtor_nogc(&retval);
314 | return FAILURE;
315 | }
316 | ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL(retval), idx, key, ent) {
317 | if (key == NULL) {
318 | key = zend_long_to_str(idx);
319 | } else {
320 | zend_string_addref(key);
321 | }
322 | if (php_set_session_var(key, ent, NULL)) {
323 | Z_TRY_ADDREF_P(ent);
324 | }
325 | PS_ADD_VAR(key);
326 | zend_string_release_ex(key, 0);
327 | } ZEND_HASH_FOREACH_END();
328 | }
329 |
330 | zval_ptr_dtor(&retval);
331 |
332 | return ret;
333 | }
334 | /* }}} */
335 | #endif
336 |
337 | /* {{{ PHP_MINIT_FUNCTION
338 | */
339 | PHP_MINIT_FUNCTION(wddx)
340 | {
341 | le_wddx = zend_register_list_destructors_ex(release_wddx_packet_rsrc, NULL, "wddx", module_number);
342 |
343 | #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
344 | php_session_register_serializer("wddx",
345 | PS_SERIALIZER_ENCODE_NAME(wddx),
346 | PS_SERIALIZER_DECODE_NAME(wddx));
347 | #endif
348 |
349 | return SUCCESS;
350 | }
351 | /* }}} */
352 |
353 | /* {{{ PHP_MINFO_FUNCTION
354 | */
355 | PHP_MINFO_FUNCTION(wddx)
356 | {
357 | php_info_print_table_start();
358 | #if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION)
359 | php_info_print_table_header(2, "WDDX Support", "enabled" );
360 | php_info_print_table_row(2, "WDDX extension version", PHP_WDDX_VERSION);
361 | php_info_print_table_row(2, "WDDX Session Serializer", "enabled" );
362 | #else
363 | php_info_print_table_row(2, "WDDX Support", "enabled" );
364 | #endif
365 | php_info_print_table_end();
366 | }
367 | /* }}} */
368 |
369 | /* {{{ php_wddx_packet_start
370 | */
371 | void php_wddx_packet_start(wddx_packet *packet, char *comment, size_t comment_len)
372 | {
373 | php_wddx_add_chunk_static(packet, WDDX_PACKET_S);
374 | if (comment) {
375 | zend_string *escaped = php_escape_html_entities(
376 | (unsigned char *)comment, comment_len, 0, ENT_QUOTES, NULL);
377 |
378 | php_wddx_add_chunk_static(packet, WDDX_HEADER_S);
379 | php_wddx_add_chunk_static(packet, WDDX_COMMENT_S);
380 | php_wddx_add_chunk_ex(packet, ZSTR_VAL(escaped), ZSTR_LEN(escaped));
381 | php_wddx_add_chunk_static(packet, WDDX_COMMENT_E);
382 | php_wddx_add_chunk_static(packet, WDDX_HEADER_E);
383 |
384 | zend_string_release_ex(escaped, 0);
385 | } else {
386 | php_wddx_add_chunk_static(packet, WDDX_HEADER);
387 | }
388 | php_wddx_add_chunk_static(packet, WDDX_DATA_S);
389 | }
390 | /* }}} */
391 |
392 | /* {{{ php_wddx_packet_end
393 | */
394 | void php_wddx_packet_end(wddx_packet *packet)
395 | {
396 | php_wddx_add_chunk_static(packet, WDDX_DATA_E);
397 | php_wddx_add_chunk_static(packet, WDDX_PACKET_E);
398 | }
399 | /* }}} */
400 |
401 | #define FLUSH_BUF() \
402 | if (l > 0) { \
403 | php_wddx_add_chunk_ex(packet, buf, l); \
404 | l = 0; \
405 | }
406 |
407 | /* {{{ php_wddx_serialize_string
408 | */
409 | static void php_wddx_serialize_string(wddx_packet *packet, zval *var)
410 | {
411 | php_wddx_add_chunk_static(packet, WDDX_STRING_S);
412 |
413 | if (Z_STRLEN_P(var) > 0) {
414 | zend_string *buf = php_escape_html_entities(
415 | (unsigned char *) Z_STRVAL_P(var), Z_STRLEN_P(var), 0, ENT_QUOTES, NULL);
416 |
417 | php_wddx_add_chunk_ex(packet, ZSTR_VAL(buf), ZSTR_LEN(buf));
418 |
419 | zend_string_release_ex(buf, 0);
420 | }
421 | php_wddx_add_chunk_static(packet, WDDX_STRING_E);
422 | }
423 | /* }}} */
424 |
425 | /* {{{ php_wddx_serialize_number
426 | */
427 | static void php_wddx_serialize_number(wddx_packet *packet, zval *var)
428 | {
429 | char tmp_buf[WDDX_BUF_LEN], *dec_point;
430 | zend_string *str = zval_get_string_func(var);
431 | snprintf(tmp_buf, sizeof(tmp_buf), WDDX_NUMBER, ZSTR_VAL(str));
432 | zend_string_release_ex(str, 0);
433 |
434 | dec_point = strchr(tmp_buf, ',');
435 | if (dec_point) {
436 | *dec_point = '.';
437 | }
438 | php_wddx_add_chunk(packet, tmp_buf);
439 | }
440 | /* }}} */
441 |
442 | /* {{{ php_wddx_serialize_boolean
443 | */
444 | static void php_wddx_serialize_boolean(wddx_packet *packet, zval *var)
445 | {
446 | php_wddx_add_chunk(packet, Z_TYPE_P(var) == IS_TRUE ? WDDX_BOOLEAN_TRUE : WDDX_BOOLEAN_FALSE);
447 | }
448 | /* }}} */
449 |
450 | /* {{{ php_wddx_serialize_unset
451 | */
452 | static void php_wddx_serialize_unset(wddx_packet *packet)
453 | {
454 | php_wddx_add_chunk_static(packet, WDDX_NULL);
455 | }
456 | /* }}} */
457 |
458 | /* {{{ php_wddx_serialize_object
459 | */
460 | static void php_wddx_serialize_object(wddx_packet *packet, zval *obj)
461 | {
462 | /* OBJECTS_FIXME */
463 | zval *ent, fname, *varname;
464 | zval retval;
465 | zend_string *key;
466 | zend_ulong idx;
467 | char tmp_buf[WDDX_BUF_LEN];
468 | HashTable *objhash, *sleephash;
469 | zend_class_entry *ce;
470 | PHP_CLASS_ATTRIBUTES;
471 |
472 | PHP_SET_CLASS_ATTRIBUTES(obj);
473 | ce = Z_OBJCE_P(obj);
474 | if (!ce || ce->serialize || ce->unserialize) {
475 | php_error_docref(NULL, E_WARNING, "Class %s can not be serialized", ZSTR_VAL(class_name));
476 | PHP_CLEANUP_CLASS_ATTRIBUTES();
477 | return;
478 | }
479 |
480 | ZVAL_STRING(&fname, "__sleep");
481 | /*
482 | * We try to call __sleep() method on object. It's supposed to return an
483 | * array of property names to be serialized.
484 | */
485 | if (call_user_function(CG(function_table), obj, &fname, &retval, 0, 0) == SUCCESS) {
486 | if (!Z_ISUNDEF(retval) && (sleephash = HASH_OF(&retval))) {
487 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
488 | snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
489 | php_wddx_add_chunk(packet, tmp_buf);
490 | php_wddx_add_chunk_static(packet, WDDX_STRING_S);
491 | php_wddx_add_chunk_ex(packet, ZSTR_VAL(class_name), ZSTR_LEN(class_name));
492 | php_wddx_add_chunk_static(packet, WDDX_STRING_E);
493 | php_wddx_add_chunk_static(packet, WDDX_VAR_E);
494 |
495 | objhash = Z_OBJPROP_P(obj);
496 |
497 | ZEND_HASH_FOREACH_VAL(sleephash, varname) {
498 | if (Z_TYPE_P(varname) != IS_STRING) {
499 | php_error_docref(NULL, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize.");
500 | continue;
501 | }
502 |
503 | if ((ent = zend_hash_find(objhash, Z_STR_P(varname))) != NULL) {
504 | php_wddx_serialize_var(packet, ent, Z_STR_P(varname));
505 | }
506 | } ZEND_HASH_FOREACH_END();
507 |
508 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
509 | }
510 | } else {
511 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
512 | snprintf(tmp_buf, WDDX_BUF_LEN, WDDX_VAR_S, PHP_CLASS_NAME_VAR);
513 | php_wddx_add_chunk(packet, tmp_buf);
514 | php_wddx_add_chunk_static(packet, WDDX_STRING_S);
515 | php_wddx_add_chunk_ex(packet, ZSTR_VAL(class_name), ZSTR_LEN(class_name));
516 | php_wddx_add_chunk_static(packet, WDDX_STRING_E);
517 | php_wddx_add_chunk_static(packet, WDDX_VAR_E);
518 |
519 | objhash = Z_OBJPROP_P(obj);
520 | ZEND_HASH_FOREACH_KEY_VAL(objhash, idx, key, ent) {
521 | if (ent == obj) {
522 | continue;
523 | }
524 | if (key) {
525 | const char *class_name, *prop_name;
526 | size_t prop_name_len;
527 | zend_string *tmp;
528 |
529 | zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_name_len);
530 | tmp = zend_string_init(prop_name, prop_name_len, 0);
531 | php_wddx_serialize_var(packet, ent, tmp);
532 | zend_string_release_ex(tmp, 0);
533 | } else {
534 | key = zend_long_to_str(idx);
535 | php_wddx_serialize_var(packet, ent, key);
536 | zend_string_release_ex(key, 0);
537 | }
538 | } ZEND_HASH_FOREACH_END();
539 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
540 | }
541 |
542 | PHP_CLEANUP_CLASS_ATTRIBUTES();
543 |
544 | zval_ptr_dtor(&fname);
545 | zval_ptr_dtor(&retval);
546 | }
547 | /* }}} */
548 |
549 | /* {{{ php_wddx_serialize_array
550 | */
551 | static void php_wddx_serialize_array(wddx_packet *packet, zval *arr)
552 | {
553 | zval *ent;
554 | zend_string *key;
555 | int is_struct = 0;
556 | zend_ulong idx;
557 | HashTable *target_hash;
558 | char tmp_buf[WDDX_BUF_LEN];
559 | zend_ulong ind = 0;
560 |
561 | target_hash = Z_ARRVAL_P(arr);
562 | ZEND_HASH_FOREACH_KEY(target_hash, idx, key) {
563 | if (key) {
564 | is_struct = 1;
565 | break;
566 | }
567 |
568 | if (idx != ind) {
569 | is_struct = 1;
570 | break;
571 | }
572 | ind++;
573 | } ZEND_HASH_FOREACH_END();
574 |
575 | if (is_struct) {
576 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
577 | } else {
578 | snprintf(tmp_buf, sizeof(tmp_buf), WDDX_ARRAY_S, zend_hash_num_elements(target_hash));
579 | php_wddx_add_chunk(packet, tmp_buf);
580 | }
581 |
582 | ZEND_HASH_FOREACH_KEY_VAL(target_hash, idx, key, ent) {
583 | if (ent == arr) {
584 | continue;
585 | }
586 |
587 | if (is_struct) {
588 | if (key) {
589 | php_wddx_serialize_var(packet, ent, key);
590 | } else {
591 | key = zend_long_to_str(idx);
592 | php_wddx_serialize_var(packet, ent, key);
593 | zend_string_release_ex(key, 0);
594 | }
595 | } else {
596 | php_wddx_serialize_var(packet, ent, NULL);
597 | }
598 | } ZEND_HASH_FOREACH_END();
599 |
600 | if (is_struct) {
601 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
602 | } else {
603 | php_wddx_add_chunk_static(packet, WDDX_ARRAY_E);
604 | }
605 | }
606 | /* }}} */
607 |
608 | /* {{{ php_wddx_serialize_var
609 | */
610 | void php_wddx_serialize_var(wddx_packet *packet, zval *var, zend_string *name)
611 | {
612 | HashTable *ht;
613 |
614 | if (name) {
615 | char *tmp_buf;
616 | zend_string *name_esc = php_escape_html_entities((unsigned char *) ZSTR_VAL(name), ZSTR_LEN(name), 0, ENT_QUOTES, NULL);
617 | tmp_buf = emalloc(ZSTR_LEN(name_esc) + sizeof(WDDX_VAR_S));
618 | snprintf(tmp_buf, ZSTR_LEN(name_esc) + sizeof(WDDX_VAR_S), WDDX_VAR_S, ZSTR_VAL(name_esc));
619 | php_wddx_add_chunk(packet, tmp_buf);
620 | efree(tmp_buf);
621 | zend_string_release_ex(name_esc, 0);
622 | }
623 |
624 | if (Z_TYPE_P(var) == IS_INDIRECT) {
625 | var = Z_INDIRECT_P(var);
626 | }
627 | ZVAL_DEREF(var);
628 | switch (Z_TYPE_P(var)) {
629 | case IS_STRING:
630 | php_wddx_serialize_string(packet, var);
631 | break;
632 |
633 | case IS_LONG:
634 | case IS_DOUBLE:
635 | php_wddx_serialize_number(packet, var);
636 | break;
637 |
638 | case IS_TRUE:
639 | case IS_FALSE:
640 | php_wddx_serialize_boolean(packet, var);
641 | break;
642 |
643 | case IS_NULL:
644 | php_wddx_serialize_unset(packet);
645 | break;
646 |
647 | case IS_ARRAY:
648 | ht = Z_ARRVAL_P(var);
649 | if (Z_REFCOUNTED_P(var)) {
650 | if (GC_IS_RECURSIVE(ht)) {
651 | zend_throw_error(NULL, "WDDX doesn't support circular references");
652 | return;
653 | }
654 | GC_PROTECT_RECURSION(ht);
655 | }
656 | php_wddx_serialize_array(packet, var);
657 | if (Z_REFCOUNTED_P(var)) {
658 | GC_UNPROTECT_RECURSION(ht);
659 | }
660 | break;
661 |
662 | case IS_OBJECT:
663 | ht = Z_OBJPROP_P(var);
664 | if (GC_IS_RECURSIVE(ht)) {
665 | zend_throw_error(NULL, "WDDX doesn't support circular references");
666 | return;
667 | }
668 | GC_PROTECT_RECURSION(ht);
669 | php_wddx_serialize_object(packet, var);
670 | GC_UNPROTECT_RECURSION(ht);
671 | break;
672 | }
673 |
674 | if (name) {
675 | php_wddx_add_chunk_static(packet, WDDX_VAR_E);
676 | }
677 | }
678 | /* }}} */
679 |
680 | /* {{{ php_wddx_add_var
681 | */
682 | static void php_wddx_add_var(wddx_packet *packet, zval *name_var)
683 | {
684 | zval *val;
685 | HashTable *target_hash;
686 |
687 | if (Z_TYPE_P(name_var) == IS_STRING) {
688 | zend_array *symbol_table = zend_rebuild_symbol_table();
689 | if ((val = zend_hash_find(symbol_table, Z_STR_P(name_var))) != NULL) {
690 | if (Z_TYPE_P(val) == IS_INDIRECT) {
691 | val = Z_INDIRECT_P(val);
692 | }
693 | php_wddx_serialize_var(packet, val, Z_STR_P(name_var));
694 | }
695 | } else if (Z_TYPE_P(name_var) == IS_ARRAY || Z_TYPE_P(name_var) == IS_OBJECT) {
696 | int is_array = Z_TYPE_P(name_var) == IS_ARRAY;
697 |
698 | target_hash = HASH_OF(name_var);
699 |
700 | if (!Z_REFCOUNTED_P(name_var)) {
701 | ZEND_HASH_FOREACH_VAL(target_hash, val) {
702 | php_wddx_add_var(packet, val);
703 | } ZEND_HASH_FOREACH_END();
704 | } else {
705 | if (is_array) {
706 | if (GC_IS_RECURSIVE(target_hash)) {
707 | php_error_docref(NULL, E_WARNING, "recursion detected");
708 | return;
709 | }
710 | GC_PROTECT_RECURSION(target_hash);
711 | }
712 | ZEND_HASH_FOREACH_VAL(target_hash, val) {
713 | ZVAL_DEREF(val);
714 | php_wddx_add_var(packet, val);
715 |
716 | } ZEND_HASH_FOREACH_END();
717 | if (is_array) {
718 | GC_UNPROTECT_RECURSION(target_hash);
719 | }
720 | }
721 | }
722 | }
723 | /* }}} */
724 |
725 | /* {{{ php_wddx_push_element
726 | */
727 | static void php_wddx_push_element(void *user_data, const XML_Char *name, const XML_Char **atts)
728 | {
729 | st_entry ent;
730 | wddx_stack *stack = (wddx_stack *)user_data;
731 | if (!strcmp((char *)name, EL_PACKET)) {
732 | int i;
733 |
734 | if (atts) for (i=0; atts[i]; i++) {
735 | if (!strcmp((char *)atts[i], EL_VERSION)) {
736 | /* nothing for now */
737 | }
738 | }
739 | } else if (!strcmp((char *)name, EL_STRING)) {
740 | ent.type = ST_STRING;
741 | SET_STACK_VARNAME;
742 |
743 | ZVAL_STR(&ent.data, ZSTR_EMPTY_ALLOC());
744 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
745 | } else if (!strcmp((char *)name, EL_BINARY)) {
746 | ent.type = ST_BINARY;
747 | SET_STACK_VARNAME;
748 |
749 | ZVAL_STR(&ent.data, ZSTR_EMPTY_ALLOC());
750 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
751 | } else if (!strcmp((char *)name, EL_CHAR)) {
752 | int i;
753 |
754 | if (atts) for (i = 0; atts[i]; i++) {
755 | if (!strcmp((char *)atts[i], EL_CHAR_CODE) && atts[i+1] && atts[i+1][0]) {
756 | char tmp_buf[2];
757 |
758 | snprintf(tmp_buf, sizeof(tmp_buf), "%c", (char)strtol((char *)atts[i+1], NULL, 16));
759 | php_wddx_process_data(user_data, (XML_Char *) tmp_buf, strlen(tmp_buf));
760 | break;
761 | }
762 | }
763 | } else if (!strcmp((char *)name, EL_NUMBER)) {
764 | ent.type = ST_NUMBER;
765 | SET_STACK_VARNAME;
766 |
767 | ZVAL_LONG(&ent.data, 0);
768 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
769 | } else if (!strcmp((char *)name, EL_BOOLEAN)) {
770 | int i;
771 |
772 | ent.type = ST_BOOLEAN;
773 | SET_STACK_VARNAME;
774 | if (atts) for (i = 0; atts[i]; i++) {
775 | if (!strcmp((char *)atts[i], EL_VALUE) && atts[i+1] && atts[i+1][0]) {
776 | ZVAL_TRUE(&ent.data);
777 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
778 | php_wddx_process_data(user_data, atts[i+1], strlen((char *)atts[i+1]));
779 | break;
780 | }
781 | } else {
782 | ZVAL_FALSE(&ent.data);
783 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
784 | }
785 | } else if (!strcmp((char *)name, EL_NULL)) {
786 | ent.type = ST_NULL;
787 | SET_STACK_VARNAME;
788 |
789 | ZVAL_NULL(&ent.data);
790 |
791 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
792 | } else if (!strcmp((char *)name, EL_ARRAY)) {
793 | ent.type = ST_ARRAY;
794 | SET_STACK_VARNAME;
795 |
796 | array_init(&ent.data);
797 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
798 | } else if (!strcmp((char *)name, EL_STRUCT)) {
799 | ent.type = ST_STRUCT;
800 | SET_STACK_VARNAME;
801 | array_init(&ent.data);
802 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
803 | } else if (!strcmp((char *)name, EL_VAR)) {
804 | int i;
805 |
806 | if (atts) for (i = 0; atts[i]; i++) {
807 | if (!strcmp((char *)atts[i], EL_NAME) && atts[i+1] && atts[i+1][0]) {
808 | if (stack->varname) efree(stack->varname);
809 | stack->varname = estrdup((char *)atts[i+1]);
810 | break;
811 | }
812 | }
813 | } else if (!strcmp((char *)name, EL_RECORDSET)) {
814 | int i;
815 |
816 | ent.type = ST_RECORDSET;
817 | SET_STACK_VARNAME;
818 | array_init(&ent.data);
819 |
820 | if (atts) for (i = 0; atts[i]; i++) {
821 | if (!strcmp((char *)atts[i], "fieldNames") && atts[i+1] && atts[i+1][0]) {
822 | zval tmp;
823 | char *key;
824 | const char *p1, *p2, *endp;
825 |
826 | i++;
827 | endp = (char *)atts[i] + strlen((char *)atts[i]);
828 | p1 = (char *)atts[i];
829 | while ((p2 = php_memnstr(p1, ",", sizeof(",")-1, endp)) != NULL) {
830 | key = estrndup(p1, p2 - p1);
831 | array_init(&tmp);
832 | add_assoc_zval_ex(&ent.data, key, p2 - p1, &tmp);
833 | p1 = p2 + sizeof(",")-1;
834 | efree(key);
835 | }
836 |
837 | if (p1 <= endp) {
838 | array_init(&tmp);
839 | add_assoc_zval_ex(&ent.data, p1, endp - p1, &tmp);
840 | }
841 |
842 | break;
843 | }
844 | }
845 |
846 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
847 | } else if (!strcmp((char *)name, EL_FIELD)) {
848 | int i;
849 | st_entry ent;
850 |
851 | ent.type = ST_FIELD;
852 | ent.varname = NULL;
853 | ZVAL_UNDEF(&ent.data);
854 |
855 | if (atts) for (i = 0; atts[i]; i++) {
856 | if (!strcmp((char *)atts[i], EL_NAME) && atts[i+1] && atts[i+1][0]) {
857 | st_entry *recordset;
858 | zval *field;
859 |
860 | if (wddx_stack_top(stack, (void**)&recordset) == SUCCESS &&
861 | recordset->type == ST_RECORDSET &&
862 | (field = zend_hash_str_find(Z_ARRVAL(recordset->data), (char*)atts[i+1], strlen((char *)atts[i+1]))) != NULL) {
863 | ZVAL_COPY_VALUE(&ent.data, field);
864 | }
865 |
866 | break;
867 | }
868 | }
869 |
870 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
871 | } else if (!strcmp((char *)name, EL_DATETIME)) {
872 | ent.type = ST_DATETIME;
873 | SET_STACK_VARNAME;
874 |
875 | ZVAL_LONG(&ent.data, 0);
876 | wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
877 | }
878 | }
879 | /* }}} */
880 |
881 | /* {{{ php_wddx_pop_element
882 | */
883 | static void php_wddx_pop_element(void *user_data, const XML_Char *name)
884 | {
885 | st_entry *ent1, *ent2;
886 | wddx_stack *stack = (wddx_stack *)user_data;
887 | HashTable *target_hash;
888 | zend_class_entry *pce;
889 | zval obj;
890 |
891 | /* OBJECTS_FIXME */
892 | if (stack->top == 0) {
893 | return;
894 | }
895 |
896 | if (!strcmp((char *)name, EL_STRING) || !strcmp((char *)name, EL_NUMBER) ||
897 | !strcmp((char *)name, EL_BOOLEAN) || !strcmp((char *)name, EL_NULL) ||
898 | !strcmp((char *)name, EL_ARRAY) || !strcmp((char *)name, EL_STRUCT) ||
899 | !strcmp((char *)name, EL_RECORDSET) || !strcmp((char *)name, EL_BINARY) ||
900 | !strcmp((char *)name, EL_DATETIME)) {
901 | wddx_stack_top(stack, (void**)&ent1);
902 |
903 | if (Z_TYPE(ent1->data) == IS_UNDEF) {
904 | if (stack->top > 1) {
905 | stack->top--;
906 | efree(ent1);
907 | } else {
908 | stack->done = 1;
909 | }
910 | return;
911 | }
912 |
913 | if (!strcmp((char *)name, EL_BINARY)) {
914 | zend_string *new_str = NULL;
915 |
916 | if (ZSTR_EMPTY_ALLOC() != Z_STR(ent1->data)) {
917 | new_str = php_base64_decode(
918 | (unsigned char *)Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
919 | }
920 |
921 | zval_ptr_dtor(&ent1->data);
922 | if (new_str) {
923 | ZVAL_STR(&ent1->data, new_str);
924 | } else {
925 | ZVAL_EMPTY_STRING(&ent1->data);
926 | }
927 | }
928 |
929 | /* Call __wakeup() method on the object. */
930 | if (Z_TYPE(ent1->data) == IS_OBJECT) {
931 | zval fname, retval;
932 |
933 | ZVAL_STRING(&fname, "__wakeup");
934 |
935 | call_user_function(NULL, &ent1->data, &fname, &retval, 0, 0);
936 |
937 | zval_ptr_dtor(&fname);
938 | zval_ptr_dtor(&retval);
939 | }
940 |
941 | if (stack->top > 1) {
942 | stack->top--;
943 | wddx_stack_top(stack, (void**)&ent2);
944 |
945 | /* if non-existent field */
946 | if (Z_ISUNDEF(ent2->data)) {
947 | zval_ptr_dtor(&ent1->data);
948 | efree(ent1);
949 | return;
950 | }
951 |
952 | if (Z_TYPE(ent2->data) == IS_ARRAY || Z_TYPE(ent2->data) == IS_OBJECT) {
953 | target_hash = HASH_OF(&ent2->data);
954 |
955 | if (ent1->varname) {
956 | if (!strcmp(ent1->varname, PHP_CLASS_NAME_VAR) &&
957 | Z_TYPE(ent1->data) == IS_STRING && Z_STRLEN(ent1->data) &&
958 | ent2->type == ST_STRUCT && Z_TYPE(ent2->data) == IS_ARRAY) {
959 | zend_bool incomplete_class = 0;
960 |
961 | zend_str_tolower(Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
962 | zend_string_forget_hash_val(Z_STR(ent1->data));
963 | if ((pce = zend_hash_find_ptr(EG(class_table), Z_STR(ent1->data))) == NULL) {
964 | incomplete_class = 1;
965 | pce = PHP_IC_ENTRY;
966 | }
967 |
968 | if (pce != PHP_IC_ENTRY && (pce->serialize || pce->unserialize)) {
969 | zval_ptr_dtor(&ent2->data);
970 | ZVAL_UNDEF(&ent2->data);
971 | php_error_docref(NULL, E_WARNING, "Class %s can not be unserialized", Z_STRVAL(ent1->data));
972 | } else {
973 | /* Initialize target object */
974 | if (object_init_ex(&obj, pce) != SUCCESS || EG(exception)) {
975 | zval_ptr_dtor(&ent2->data);
976 | ZVAL_UNDEF(&ent2->data);
977 | php_error_docref(NULL, E_WARNING, "Class %s can not be instantiated", Z_STRVAL(ent1->data));
978 | } else {
979 | /* Merge current hashtable with object's default properties */
980 | zend_hash_merge(Z_OBJPROP(obj),
981 | Z_ARRVAL(ent2->data),
982 | zval_add_ref, 0);
983 |
984 | if (incomplete_class) {
985 | #if PHP_VERSION_ID < 80000
986 | php_store_class_name(&obj, Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
987 | #else
988 | php_store_class_name(&obj, Z_STR(ent1->data));
989 | #endif
990 | }
991 |
992 | /* Clean up old array entry */
993 | zval_ptr_dtor(&ent2->data);
994 |
995 | /* Set stack entry to point to the newly created object */
996 | ZVAL_COPY_VALUE(&ent2->data, &obj);
997 | }
998 | }
999 |
1000 | /* Clean up class name var entry */
1001 | zval_ptr_dtor(&ent1->data);
1002 | } else if (Z_TYPE(ent2->data) == IS_OBJECT) {
1003 | #if PHP_VERSION_ID < 80000
1004 | zend_update_property(Z_OBJCE(ent2->data), &ent2->data, ent1->varname, strlen(ent1->varname), &ent1->data);
1005 | #else
1006 | zend_update_property(Z_OBJCE(ent2->data), Z_OBJ(ent2->data), ent1->varname, strlen(ent1->varname), &ent1->data);
1007 | #endif
1008 | Z_TRY_DELREF(ent1->data);
1009 | } else {
1010 | zend_symtable_str_update(target_hash, ent1->varname, strlen(ent1->varname), &ent1->data);
1011 | }
1012 | efree(ent1->varname);
1013 | } else {
1014 | zend_hash_next_index_insert(target_hash, &ent1->data);
1015 | }
1016 | }
1017 | efree(ent1);
1018 | } else {
1019 | stack->done = 1;
1020 | }
1021 | } else if (!strcmp((char *)name, EL_VAR) && stack->varname) {
1022 | efree(stack->varname);
1023 | stack->varname = NULL;
1024 | } else if (!strcmp((char *)name, EL_FIELD)) {
1025 | st_entry *ent;
1026 | wddx_stack_top(stack, (void **)&ent);
1027 | efree(ent);
1028 | stack->top--;
1029 | }
1030 | }
1031 | /* }}} */
1032 |
1033 | /* {{{ php_wddx_process_data
1034 | */
1035 | static void php_wddx_process_data(void *user_data, const XML_Char *s, int len)
1036 | {
1037 | st_entry *ent;
1038 | wddx_stack *stack = (wddx_stack *)user_data;
1039 |
1040 | if (!wddx_stack_is_empty(stack) && !stack->done) {
1041 | wddx_stack_top(stack, (void**)&ent);
1042 | switch (ent->type) {
1043 | case ST_BINARY:
1044 | case ST_STRING:
1045 | if (Z_STRLEN(ent->data) == 0) {
1046 | zval_ptr_dtor(&ent->data);
1047 | ZVAL_STRINGL(&ent->data, (char *)s, len);
1048 | } else {
1049 | Z_STR(ent->data) = zend_string_extend(Z_STR(ent->data), Z_STRLEN(ent->data) + len, 0);
1050 | memcpy(Z_STRVAL(ent->data) + Z_STRLEN(ent->data) - len, (char *)s, len);
1051 | Z_STRVAL(ent->data)[Z_STRLEN(ent->data)] = '\0';
1052 | }
1053 | break;
1054 | case ST_NUMBER:
1055 | ZVAL_STRINGL(&ent->data, (char *)s, len);
1056 | convert_scalar_to_number(&ent->data);
1057 | break;
1058 |
1059 | case ST_BOOLEAN:
1060 | if (!strcmp((char *)s, "true")) {
1061 | ZVAL_TRUE(&ent->data);
1062 | } else if (!strcmp((char *)s, "false")) {
1063 | ZVAL_FALSE(&ent->data);
1064 | } else {
1065 | zval_ptr_dtor(&ent->data);
1066 | if (ent->varname) {
1067 | efree(ent->varname);
1068 | ent->varname = NULL;
1069 | }
1070 | ZVAL_UNDEF(&ent->data);
1071 | }
1072 | break;
1073 |
1074 | case ST_DATETIME: {
1075 | zend_string *str;
1076 |
1077 | if (Z_TYPE(ent->data) == IS_STRING) {
1078 | str = zend_string_safe_alloc(Z_STRLEN(ent->data), 1, len, 0);
1079 | memcpy(ZSTR_VAL(str), Z_STRVAL(ent->data), Z_STRLEN(ent->data));
1080 | memcpy(ZSTR_VAL(str) + Z_STRLEN(ent->data), s, len);
1081 | ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
1082 | zval_ptr_dtor_str(&ent->data);
1083 | } else {
1084 | str = zend_string_init((char *)s, len, 0);
1085 | }
1086 |
1087 | ZVAL_LONG(&ent->data, php_parse_date(ZSTR_VAL(str), NULL));
1088 | /* date out of range < 1969 or > 2038 */
1089 | if (Z_LVAL(ent->data) == -1) {
1090 | ZVAL_STR_COPY(&ent->data, str);
1091 | }
1092 |
1093 | zend_string_release_ex(str, 0);
1094 | }
1095 | break;
1096 |
1097 | default:
1098 | break;
1099 | }
1100 | }
1101 | }
1102 | /* }}} */
1103 |
1104 | /* {{{ php_wddx_deserialize_ex
1105 | */
1106 | int php_wddx_deserialize_ex(const char *value, size_t vallen, zval *return_value)
1107 | {
1108 | wddx_stack stack;
1109 | XML_Parser parser;
1110 | st_entry *ent;
1111 | int retval;
1112 |
1113 | wddx_stack_init(&stack);
1114 | parser = XML_ParserCreate((XML_Char *) "UTF-8");
1115 |
1116 | XML_SetUserData(parser, &stack);
1117 | XML_SetElementHandler(parser, php_wddx_push_element, php_wddx_pop_element);
1118 | XML_SetCharacterDataHandler(parser, php_wddx_process_data);
1119 |
1120 | /* XXX value should be parsed in the loop to exhaust size_t */
1121 | XML_Parse(parser, (const XML_Char *) value, (int)vallen, 1);
1122 |
1123 | XML_ParserFree(parser);
1124 |
1125 | if (stack.top == 1) {
1126 | wddx_stack_top(&stack, (void**)&ent);
1127 | if (Z_ISUNDEF(ent->data)) {
1128 | retval = FAILURE;
1129 | } else {
1130 | ZVAL_COPY(return_value, &ent->data);
1131 | retval = SUCCESS;
1132 | }
1133 | } else {
1134 | retval = FAILURE;
1135 | }
1136 |
1137 | wddx_stack_destroy(&stack);
1138 |
1139 | return retval;
1140 | }
1141 | /* }}} */
1142 |
1143 | /* {{{ proto string wddx_serialize_value(mixed var [, string comment])
1144 | Creates a new packet and serializes the given value */
1145 | PHP_FUNCTION(wddx_serialize_value)
1146 | {
1147 | zval *var;
1148 | char *comment = NULL;
1149 | size_t comment_len = 0;
1150 | wddx_packet *packet;
1151 |
1152 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|s", &var, &comment, &comment_len) == FAILURE) {
1153 | return;
1154 | }
1155 |
1156 | packet = php_wddx_constructor();
1157 |
1158 | php_wddx_packet_start(packet, comment, comment_len);
1159 | php_wddx_serialize_var(packet, var, NULL);
1160 | php_wddx_packet_end(packet);
1161 | smart_str_0(packet);
1162 |
1163 | RETVAL_STR_COPY(packet->s);
1164 | php_wddx_destructor(packet);
1165 | }
1166 | /* }}} */
1167 |
1168 | /* {{{ proto string wddx_serialize_vars(mixed var_name [, mixed ...])
1169 | Creates a new packet and serializes given variables into a struct */
1170 | PHP_FUNCTION(wddx_serialize_vars)
1171 | {
1172 | int num_args, i;
1173 | wddx_packet *packet;
1174 | zval *args = NULL;
1175 |
1176 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &num_args) == FAILURE) {
1177 | return;
1178 | }
1179 |
1180 | packet = php_wddx_constructor();
1181 |
1182 | php_wddx_packet_start(packet, NULL, 0);
1183 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
1184 |
1185 | for (i=0; is);
1203 | php_wddx_destructor(packet);
1204 | }
1205 | /* }}} */
1206 |
1207 | /* {{{ php_wddx_constructor
1208 | */
1209 | wddx_packet *php_wddx_constructor(void)
1210 | {
1211 | smart_str *packet;
1212 |
1213 | packet = ecalloc(1, sizeof(smart_str));
1214 |
1215 | return packet;
1216 | }
1217 | /* }}} */
1218 |
1219 | /* {{{ php_wddx_destructor
1220 | */
1221 | void php_wddx_destructor(wddx_packet *packet)
1222 | {
1223 | smart_str_free(packet);
1224 | efree(packet);
1225 | }
1226 | /* }}} */
1227 |
1228 | /* {{{ proto resource wddx_packet_start([string comment])
1229 | Starts a WDDX packet with optional comment and returns the packet id */
1230 | PHP_FUNCTION(wddx_packet_start)
1231 | {
1232 | char *comment = NULL;
1233 | size_t comment_len = 0;
1234 | wddx_packet *packet;
1235 |
1236 | comment = NULL;
1237 |
1238 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s", &comment, &comment_len) == FAILURE) {
1239 | return;
1240 | }
1241 |
1242 | packet = php_wddx_constructor();
1243 |
1244 | php_wddx_packet_start(packet, comment, comment_len);
1245 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_S);
1246 |
1247 | RETURN_RES(zend_register_resource(packet, le_wddx));
1248 | }
1249 | /* }}} */
1250 |
1251 | /* {{{ proto string wddx_packet_end(resource packet_id)
1252 | Ends specified WDDX packet and returns the string containing the packet */
1253 | PHP_FUNCTION(wddx_packet_end)
1254 | {
1255 | zval *packet_id;
1256 | wddx_packet *packet = NULL;
1257 |
1258 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &packet_id) == FAILURE) {
1259 | return;
1260 | }
1261 |
1262 | if ((packet = (wddx_packet *)zend_fetch_resource(Z_RES_P(packet_id), "WDDX packet ID", le_wddx)) == NULL) {
1263 | RETURN_FALSE;
1264 | }
1265 |
1266 | php_wddx_add_chunk_static(packet, WDDX_STRUCT_E);
1267 |
1268 | php_wddx_packet_end(packet);
1269 | smart_str_0(packet);
1270 |
1271 | RETVAL_STR_COPY(packet->s);
1272 |
1273 | zend_list_close(Z_RES_P(packet_id));
1274 | }
1275 | /* }}} */
1276 |
1277 | /* {{{ proto bool wddx_add_vars(resource packet_id, mixed var_names [, mixed ...])
1278 | Serializes given variables and adds them to packet given by packet_id */
1279 | PHP_FUNCTION(wddx_add_vars)
1280 | {
1281 | int num_args, i;
1282 | zval *args = NULL;
1283 | zval *packet_id;
1284 | wddx_packet *packet = NULL;
1285 |
1286 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "r+", &packet_id, &args, &num_args) == FAILURE) {
1287 | return;
1288 | }
1289 |
1290 | if ((packet = (wddx_packet *)zend_fetch_resource(Z_RES_P(packet_id), "WDDX packet ID", le_wddx)) == NULL) {
1291 | RETURN_FALSE;
1292 | }
1293 |
1294 | for (i=0; i