├── 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 |
Variables
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 |
my_command
"; 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 |
TEST comment
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 |
TEST comment
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