diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/curl/interface.c | 14 | ||||
| -rw-r--r-- | ext/curl/php_curl.h | 2 | ||||
| -rw-r--r-- | ext/curl/tests/bug65458.phpt | 25 | ||||
| -rw-r--r-- | ext/odbc/config.m4 | 37 | ||||
| -rw-r--r-- | ext/openssl/openssl.c | 50 | ||||
| -rw-r--r-- | ext/openssl/tests/bug64802.pem | 37 | ||||
| -rw-r--r-- | ext/openssl/tests/bug64802.phpt | 56 | ||||
| -rw-r--r-- | ext/standard/php_var.h | 1 | ||||
| -rw-r--r-- | ext/standard/tests/file/glob_variation3.phpt | 19 | ||||
| -rw-r--r-- | ext/standard/tests/serialize/bug65481.phpt | 40 | ||||
| -rw-r--r-- | ext/standard/var_unserializer.c | 117 | ||||
| -rw-r--r-- | ext/standard/var_unserializer.re | 53 | ||||
| -rw-r--r-- | ext/xmlrpc/tests/003.phpt | 109 | ||||
| -rw-r--r-- | ext/xmlrpc/tests/004.phpt | 19 |
14 files changed, 474 insertions, 105 deletions
diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 531f15ba15..f79d0d54c2 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1373,9 +1373,9 @@ static void curl_free_post(void **post) /* {{{ curl_free_slist */ -static void curl_free_slist(void **slist) +static void curl_free_slist(void *slist) { - curl_slist_free_all((struct curl_slist *) *slist); + curl_slist_free_all(*((struct curl_slist **) slist)); } /* }}} */ @@ -1443,8 +1443,10 @@ static void alloc_curl_handle(php_curl **ch) (*ch)->handlers->read->stream = NULL; zend_llist_init(&(*ch)->to_free->str, sizeof(char *), (llist_dtor_func_t) curl_free_string, 0); - zend_llist_init(&(*ch)->to_free->slist, sizeof(struct curl_slist), (llist_dtor_func_t) curl_free_slist, 0); zend_llist_init(&(*ch)->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t) curl_free_post, 0); + + (*ch)->to_free->slist = emalloc(sizeof(HashTable)); + zend_hash_init((*ch)->to_free->slist, 4, NULL, curl_free_slist, 0); } /* }}} */ @@ -1675,6 +1677,7 @@ PHP_FUNCTION(curl_copy_handle) curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER, (void *) dupch); curl_easy_setopt(dupch->cp, CURLOPT_PROGRESSDATA, (void *) dupch); + efree(dupch->to_free->slist); efree(dupch->to_free); dupch->to_free = ch->to_free; @@ -2184,7 +2187,7 @@ string_copy: return 1; } } - zend_llist_add_element(&ch->to_free->slist, &slist); + zend_hash_index_update(ch->to_free->slist, (ulong) option, &slist, sizeof(struct curl_slist *), NULL); error = curl_easy_setopt(ch->cp, option, slist); @@ -2680,8 +2683,9 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC) /* cURL destructors should be invoked only by last curl handle */ if (Z_REFCOUNT_P(ch->clone) <= 1) { zend_llist_clean(&ch->to_free->str); - zend_llist_clean(&ch->to_free->slist); zend_llist_clean(&ch->to_free->post); + zend_hash_destroy(ch->to_free->slist); + efree(ch->to_free->slist); efree(ch->to_free); FREE_ZVAL(ch->clone); } else { diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 945f0a4307..911d87a6b4 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -126,7 +126,7 @@ struct _php_curl_send_headers { struct _php_curl_free { zend_llist str; zend_llist post; - zend_llist slist; + HashTable *slist; }; typedef struct { diff --git a/ext/curl/tests/bug65458.phpt b/ext/curl/tests/bug65458.phpt new file mode 100644 index 0000000000..99288f24be --- /dev/null +++ b/ext/curl/tests/bug65458.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #65458 (curl memory leak) +--SKIPIF-- +<?php +if (!extension_loaded('curl')) exit("skip curl extension not loaded"); +?> +--FILE-- +<?php +$ch = curl_init(); +$init = memory_get_usage(); +for ($i = 0; $i < 10000; $i++) { + curl_setopt($ch, CURLOPT_HTTPHEADER, [ "SOAPAction: getItems" ]); +} + +$preclose = memory_get_usage(); +curl_close($ch); + +// This is a slightly tricky heuristic, but basically, we want to ensure +// $preclose - $init has a delta in the order of bytes, not megabytes. Given +// the number of iterations in the loop, if we're wasting memory here, we +// should have megs and megs of extra allocations. +var_dump(($preclose - $init) < 10000); +?> +--EXPECT-- +bool(true) diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4 index 5be3288f30..a1201db57c 100644 --- a/ext/odbc/config.m4 +++ b/ext/odbc/config.m4 @@ -370,18 +370,33 @@ PHP_ARG_WITH(iodbc,, if test "$PHP_IODBC" != "no"; then AC_MSG_CHECKING(for iODBC support) - if test "$PHP_IODBC" = "yes"; then - PHP_IODBC=/usr/local + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libiodbc ; then + PHP_ADD_LIBRARY_WITH_PATH(iodbc, $PHP_IODBC/$PHP_LIBDIR) + ODBC_TYPE=iodbc + ODBC_INCLUDE=`$PKG_CONFIG --cflags-only-I libiodbc` + ODBC_LFLAGS=`$PKG_CONFIG --libs-only-L libiodbc` + ODBC_LIBS=`$PKG_CONFIG --libs-only-l libiodbc` + PHP_EVAL_INCLINE($ODBC_INCLUDE) + AC_DEFINE(HAVE_IODBC,1,[ ]) + AC_DEFINE(HAVE_ODBC2,1,[ ]) + AC_MSG_RESULT([$ext_output]) + else + if test "$PHP_IODBC" = "yes"; then + PHP_IODBC=/usr/local + fi + PHP_ADD_LIBRARY_WITH_PATH(iodbc, $PHP_IODBC/$PHP_LIBDIR) + PHP_ADD_INCLUDE($PHP_IODBC/include, 1) + ODBC_TYPE=iodbc + ODBC_INCLUDE=-I$PHP_IODBC/include + ODBC_LFLAGS=-L$PHP_IODBC/$PHP_LIBDIR + ODBC_LIBS=-liodbc + AC_DEFINE(HAVE_IODBC,1,[ ]) + AC_DEFINE(HAVE_ODBC2,1,[ ]) + AC_MSG_RESULT([$ext_output]) fi - PHP_ADD_LIBRARY_WITH_PATH(iodbc, $PHP_IODBC/$PHP_LIBDIR) - PHP_ADD_INCLUDE($PHP_IODBC/include, 1) - ODBC_TYPE=iodbc - ODBC_INCLUDE=-I$PHP_IODBC/include - ODBC_LFLAGS=-L$PHP_IODBC/$PHP_LIBDIR - ODBC_LIBS=-liodbc - AC_DEFINE(HAVE_IODBC,1,[ ]) - AC_DEFINE(HAVE_ODBC2,1,[ ]) - AC_MSG_RESULT([$ext_output]) fi fi diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 68be86f833..f1dfa5024a 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -561,6 +561,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname TSRMLS_DC) /* {{{ */ { + zval **data; zval *subitem, *subentries; int i, j = -1, last = -1, obj_cnt = 0; char *sname; @@ -592,39 +593,27 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s sname = (char *) OBJ_nid2ln(nid); } - MAKE_STD_ZVAL(subentries); - array_init(subentries); + str = X509_NAME_ENTRY_get_data(ne); + if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) { + to_add_len = ASN1_STRING_to_UTF8(&to_add, str); + } else { + to_add = ASN1_STRING_data(str); + to_add_len = ASN1_STRING_length(str); + } - last = -1; - for (;;) { - j = X509_NAME_get_index_by_OBJ(name, obj, last); - if (j < 0) { - if (last != -1) break; - } else { - obj_cnt++; - ne = X509_NAME_get_entry(name, j); - str = X509_NAME_ENTRY_get_data(ne); - if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) { - to_add_len = ASN1_STRING_to_UTF8(&to_add, str); - if (to_add_len != -1) { - add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); - } - } else { - to_add = ASN1_STRING_data(str); - to_add_len = ASN1_STRING_length(str); + if (to_add_len != -1) { + if (zend_hash_find(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, (void**)&data) == SUCCESS) { + if (Z_TYPE_PP(data) == IS_ARRAY) { + subentries = *data; + add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); + } else if (Z_TYPE_PP(data) == IS_STRING) { + MAKE_STD_ZVAL(subentries); + array_init(subentries); + add_next_index_stringl(subentries, Z_STRVAL_PP(data), Z_STRLEN_PP(data), 1); add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); + zend_hash_update(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, &subentries, sizeof(zval*), NULL); } - } - last = j; - } - i = last; - - if (obj_cnt > 1) { - add_assoc_zval_ex(subitem, sname, strlen(sname) + 1, subentries); - } else { - zval_dtor(subentries); - FREE_ZVAL(subentries); - if (obj_cnt && str && to_add_len > -1) { + } else { add_assoc_stringl(subitem, sname, (char *)to_add, to_add_len, 1); } } @@ -1574,6 +1563,7 @@ PHP_FUNCTION(openssl_x509_parse) bio_out = BIO_new(BIO_s_mem()); if (nid == NID_subject_alt_name) { if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) { + BIO_get_mem_ptr(bio_out, &bio_buf); add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); } else { zval_dtor(return_value); diff --git a/ext/openssl/tests/bug64802.pem b/ext/openssl/tests/bug64802.pem new file mode 100644 index 0000000000..187cda31d7 --- /dev/null +++ b/ext/openssl/tests/bug64802.pem @@ -0,0 +1,37 @@ +-----BEGIN CERTIFICATE----- +MIIGfzCCBWegAwIBAgIQSVCinGH6MkvjJZjRyjK9nTANBgkqhkiG9w0BAQUFADCB +jjELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNDAyBgNV +BAMTK0NPTU9ETyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIgQ0Ew +HhcNMTIwMjI5MDAwMDAwWhcNMTQwMjI4MjM1OTU5WjCCAW8xEjAQBgNVBAMTCXd3 +dy5yZC5pbzERMA8GA1UEAxMIcmRpby5jb20xDjAMBgNVBAMTBXJkLmlvMRUwEwYD +VQQDEwxhcGkucmRpby5jb20xEjAQBgNVBAMTCWFwaS5yZC5pbzEQMA4GA1UEBRMH +NDU4NjAwNzETMBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgECEwhE +ZWxhd2FyZTEdMBsGA1UEDxMUUHJpdmF0ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYT +AlVTMQ4wDAYDVQQREwU5NDEwMzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFzAVBgNVBAkTDjE1NTAgQnJ5YW50IHN0MRMwEQYDVQQKEwpSZGlv +LCBJbmMuMSMwIQYDVQQLExpDT01PRE8gRVYgTXVsdGktRG9tYWluIFNTTDEVMBMG +A1UEAxMMd3d3LnJkaW8uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAt0AgYOe8EBJNVBAuSJFLKHRKZn0/ObCLBFG4xVH/5fb1rfYHBT1XSjjOqR3t +iGC/A3esF8YC7TuHQcTLVephx0DtJv1ASxRg3zPM8ebBRsuul18N0W+sY1aNXpkd +36quxvjg5UdBrAweuekJ7OTSZcCe2Ry/SKBeZSWWtkWsI4krCLv7JaKUwxw2h+Hn +TAZSBLVxz/mixF0WYdepYwnq2Hm7XvvVEIQ7wxOQ9bA7iCevLojZOnb39BT2QII7 +cy8AB47RZdfYg7UwaO3bST2rauA4MKar7/Ozqc0aemNFpLatJfgv07cydiuj9fsd +5aE/c8is8C9M9+7MmSMkcNEgGwIDAQABo4IB8zCCAe8wHwYDVR0jBBgwFoAUiERR +/1AqaV4tiPQhutkM8s7L6nwwHQYDVR0OBBYEFCrYw8bfrYJ61NS2yYx6/CnhjzT4 +MA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjBGBgNVHSAEPzA9MDsGDCsGAQQBsjEBAgEFATArMCkGCCsG +AQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQUzBTBgNVHR8ETDBK +MEigRqBEhkJodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9FeHRlbmRlZFZh +bGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYQGCCsGAQUFBwEBBHgwdjBOBggr +BgEFBQcwAoZCaHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPRXh0ZW5kZWRW +YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8v +b2NzcC5jb21vZG9jYS5jb20wTAYDVR0RBEUwQ4IMd3d3LnJkaW8uY29tgglhcGku +cmQuaW+CDGFwaS5yZGlvLmNvbYIFcmQuaW+CCHJkaW8uY29tggl3d3cucmQuaW8w +DQYJKoZIhvcNAQEFBQADggEBAKFd4bPVFRyrlqIKPtrtMuqGqid6685ohxf0cv52 +sjdRYwLVTjnZOrmkDdNaF3R2A1ZlVMRN+67rK+qfY5sTeijFcudV3/i0PDtOFRwP +6yYVD2uZmYkxfPiW309HPmDF+EzhxpVjWlTQEOwkfFLTmJmwl3Qu2Kffp8F1ENXW +OTVNvj5VtMghvzu68PpzKl1VjlOR4Ej9NCwh1dUjNKEoTPzvpehXsIZ7jHSpX/T1 +wSSt9ckiechDdpgZXTzHgbxHNibK0Uhh+QhkBgYMj5F8qj5BlBhWAWqQa/VnEdmr +Pfo7U+QmadoqQd7qt06hE2hG1nfZ0vPJDbWV3oVSwG2Yt7I= +-----END CERTIFICATE----- diff --git a/ext/openssl/tests/bug64802.phpt b/ext/openssl/tests/bug64802.phpt new file mode 100644 index 0000000000..9a59701494 --- /dev/null +++ b/ext/openssl/tests/bug64802.phpt @@ -0,0 +1,56 @@ +--TEST-- +Bug #64802: openssl_x509_parse fails to parse subject properly in some cases +--SKIPIF-- +<?php +if (!extension_loaded("openssl")) die("skip"); +?> +--FILE-- +<?php +$cert = file_get_contents(__DIR__.'/bug64802.pem'); +$r = openssl_x509_parse($cert,$use_short_names=true); +sort($r['subject']); +var_dump( $r['subject'] ); +?> +--EXPECTF-- +array(11) { + [0]=> + string(14) "1550 Bryant st" + [1]=> + string(5) "94103" + [2]=> + string(7) "4586007" + [3]=> + string(2) "CA" + [4]=> + string(26) "COMODO EV Multi-Domain SSL" + [5]=> + string(20) "Private Organization" + [6]=> + string(10) "Rdio, Inc." + [7]=> + string(13) "San Francisco" + [8]=> + string(2) "US" + [9]=> + array(2) { + [0]=> + string(2) "US" + [1]=> + string(8) "Delaware" + } + [10]=> + array(6) { + [0]=> + string(9) "www.rd.io" + [1]=> + string(8) "rdio.com" + [2]=> + string(5) "rd.io" + [3]=> + string(12) "api.rdio.com" + [4]=> + string(9) "api.rd.io" + [5]=> + string(12) "www.rdio.com" + } +} diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h index 35343b3d5d..afc5f178e4 100644 --- a/ext/standard/php_var.h +++ b/ext/standard/php_var.h @@ -115,6 +115,7 @@ do { \ PHPAPI void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval **nzval); PHPAPI void var_push_dtor(php_unserialize_data_t *var_hash, zval **val); +PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval); PHPAPI void var_destroy(php_unserialize_data_t *var_hash); #define PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash, ozval, nzval) \ diff --git a/ext/standard/tests/file/glob_variation3.phpt b/ext/standard/tests/file/glob_variation3.phpt new file mode 100644 index 0000000000..9e1e28baf9 --- /dev/null +++ b/ext/standard/tests/file/glob_variation3.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test glob() function: ensure no platform difference +--FILE-- +<?php +$path = dirname(__FILE__); + +ini_set('open_basedir', NULL); +var_dump(glob("$path/*.none")); + +ini_set('open_basedir', $path); +var_dump(glob("$path/*.none")); + +?> +==DONE== +--EXPECT-- +array(0) { +} +bool(false) +==DONE== diff --git a/ext/standard/tests/serialize/bug65481.phpt b/ext/standard/tests/serialize/bug65481.phpt new file mode 100644 index 0000000000..65634f63ba --- /dev/null +++ b/ext/standard/tests/serialize/bug65481.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #65481 (shutdown segfault due to serialize) +--FILE-- +<?php +echo "Test\n"; + +class A { + public $e = array(); +} + +class Token implements \Serializable { + public function serialize() + { + $c = new A; + + for ($i = 0; $i < 4; $i++) + { + $e = new A; + $c->e[] = $e; + $e->e = $c->e; + } + + return serialize(array(serialize($c))); + } + + public function unserialize($str) + { + $r = unserialize($str); + $r = unserialize($r[0]); + } +} + +$token = new Token; +$token = serialize($token); + +?> +Done +--EXPECT-- +Test +Done diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index d8bae08d2a..8a35e0a5af 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Sat Mar 9 22:33:09 2013 */ +/* Generated by re2c 0.13.5 on Mon Jul 29 17:57:26 2013 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ @@ -26,6 +26,7 @@ /* {{{ reference-handling for unserializer: var_* */ #define VAR_ENTRIES_MAX 1024 +#define VAR_ENTRIES_DBG 0 typedef struct { zval *data[VAR_ENTRIES_MAX]; @@ -36,7 +37,7 @@ typedef struct { static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) { var_entries *var_hash = (*var_hashx)->last; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif @@ -60,7 +61,7 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) { var_entries *var_hash = (*var_hashx)->last_dtor; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif @@ -82,11 +83,35 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) var_hash->data[var_hash->used_slots++] = *rval; } +PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval) +{ + var_entries *var_hash = (*var_hashx)->last_dtor; +#if VAR_ENTRIES_DBG + fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); +#endif + + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { + var_hash = emalloc(sizeof(var_entries)); + var_hash->used_slots = 0; + var_hash->next = 0; + + if (!(*var_hashx)->first_dtor) { + (*var_hashx)->first_dtor = var_hash; + } else { + ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash; + } + + (*var_hashx)->last_dtor = var_hash; + } + + var_hash->data[var_hash->used_slots++] = *rval; +} + PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) { long i; var_entries *var_hash = (*var_hashx)->first; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_replace(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(nzval)); #endif @@ -104,7 +129,7 @@ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **n static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store) { var_entries *var_hash = (*var_hashx)->first; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_access(%ld): %ld\n", var_hash?var_hash->used_slots:-1L, id); #endif @@ -127,7 +152,7 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) void *next; long i; var_entries *var_hash = (*var_hashx)->first; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); #endif @@ -201,7 +226,7 @@ static char *unserialize_str(const unsigned char **p, size_t *len, size_t maxlen #define YYMARKER marker -#line 209 "ext/standard/var_unserializer.re" +#line 234 "ext/standard/var_unserializer.re" @@ -432,7 +457,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) -#line 436 "ext/standard/var_unserializer.c" +#line 461 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -492,9 +517,9 @@ yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: -#line 785 "ext/standard/var_unserializer.re" +#line 812 "ext/standard/var_unserializer.re" { return 0; } -#line 498 "ext/standard/var_unserializer.c" +#line 523 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; @@ -537,13 +562,13 @@ yy13: goto yy3; yy14: ++YYCURSOR; -#line 779 "ext/standard/var_unserializer.re" +#line 806 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 547 "ext/standard/var_unserializer.c" +#line 572 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; @@ -573,7 +598,7 @@ yy20: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 635 "ext/standard/var_unserializer.re" +#line 660 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -625,9 +650,9 @@ yy20: do { /* Try to find class directly */ - BG(serialize_lock) = 1; + BG(serialize_lock)++; if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (EG(exception)) { efree(class_name); return 0; @@ -635,7 +660,7 @@ yy20: ce = *pce; break; } - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (EG(exception)) { efree(class_name); @@ -655,9 +680,9 @@ yy20: args[0] = &arg_func_name; MAKE_STD_ZVAL(arg_func_name); ZVAL_STRING(arg_func_name, class_name, 1); - BG(serialize_lock) = 1; + BG(serialize_lock)++; if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (EG(exception)) { efree(class_name); zval_ptr_dtor(&user_func); @@ -671,7 +696,7 @@ yy20: zval_ptr_dtor(&arg_func_name); break; } - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } @@ -699,7 +724,9 @@ yy20: *p = YYCURSOR; if (custom_object) { - int ret = object_custom(UNSERIALIZE_PASSTHRU, ce); + int ret; + + ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { php_store_class_name(*rval, class_name, len2); @@ -717,7 +744,7 @@ yy20: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 721 "ext/standard/var_unserializer.c" +#line 748 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { @@ -742,7 +769,7 @@ yy27: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 627 "ext/standard/var_unserializer.re" +#line 652 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); @@ -750,7 +777,7 @@ yy27: return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 754 "ext/standard/var_unserializer.c" +#line 781 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; @@ -771,7 +798,7 @@ yy34: yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; -#line 607 "ext/standard/var_unserializer.re" +#line 632 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -791,7 +818,7 @@ yy34: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 795 "ext/standard/var_unserializer.c" +#line 822 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; @@ -812,7 +839,7 @@ yy41: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 578 "ext/standard/var_unserializer.re" +#line 603 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -841,7 +868,7 @@ yy41: ZVAL_STRINGL(*rval, str, len, 0); return 1; } -#line 845 "ext/standard/var_unserializer.c" +#line 872 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; @@ -862,7 +889,7 @@ yy48: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 550 "ext/standard/var_unserializer.re" +#line 575 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -890,7 +917,7 @@ yy48: ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 894 "ext/standard/var_unserializer.c" +#line 921 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { @@ -978,7 +1005,7 @@ yy61: } yy63: ++YYCURSOR; -#line 540 "ext/standard/var_unserializer.re" +#line 565 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: @@ -988,7 +1015,7 @@ use_double: ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 992 "ext/standard/var_unserializer.c" +#line 1019 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { @@ -1047,7 +1074,7 @@ yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 525 "ext/standard/var_unserializer.re" +#line 550 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -1062,7 +1089,7 @@ yy73: return 1; } -#line 1066 "ext/standard/var_unserializer.c" +#line 1093 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; @@ -1089,7 +1116,7 @@ yy79: if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; -#line 498 "ext/standard/var_unserializer.re" +#line 523 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1116,7 +1143,7 @@ yy79: ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 1120 "ext/standard/var_unserializer.c" +#line 1147 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1124,24 +1151,24 @@ yy83: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 491 "ext/standard/var_unserializer.re" +#line 516 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 1135 "ext/standard/var_unserializer.c" +#line 1162 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 484 "ext/standard/var_unserializer.re" +#line 509 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 1145 "ext/standard/var_unserializer.c" +#line 1172 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { @@ -1164,7 +1191,7 @@ yy91: if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; -#line 461 "ext/standard/var_unserializer.re" +#line 486 "ext/standard/var_unserializer.re" { long id; @@ -1179,7 +1206,7 @@ yy91: if (*rval == *rval_ref) return 0; if (*rval != NULL) { - zval_ptr_dtor(rval); + var_push_dtor_no_addref(var_hash, rval); } *rval = *rval_ref; Z_ADDREF_PP(rval); @@ -1187,7 +1214,7 @@ yy91: return 1; } -#line 1191 "ext/standard/var_unserializer.c" +#line 1218 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { @@ -1210,7 +1237,7 @@ yy97: if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; -#line 440 "ext/standard/var_unserializer.re" +#line 465 "ext/standard/var_unserializer.re" { long id; @@ -1231,9 +1258,9 @@ yy97: return 1; } -#line 1235 "ext/standard/var_unserializer.c" +#line 1262 "ext/standard/var_unserializer.c" } -#line 787 "ext/standard/var_unserializer.re" +#line 814 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 4d99cbfd78..76c501e1b5 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -24,6 +24,7 @@ /* {{{ reference-handling for unserializer: var_* */ #define VAR_ENTRIES_MAX 1024 +#define VAR_ENTRIES_DBG 0 typedef struct { zval *data[VAR_ENTRIES_MAX]; @@ -34,7 +35,7 @@ typedef struct { static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) { var_entries *var_hash = (*var_hashx)->last; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_push(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif @@ -58,7 +59,7 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval) PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) { var_entries *var_hash = (*var_hashx)->last_dtor; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval)); #endif @@ -80,11 +81,35 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval) var_hash->data[var_hash->used_slots++] = *rval; } +PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval) +{ + var_entries *var_hash = (*var_hashx)->last_dtor; +#if VAR_ENTRIES_DBG + fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval)); +#endif + + if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) { + var_hash = emalloc(sizeof(var_entries)); + var_hash->used_slots = 0; + var_hash->next = 0; + + if (!(*var_hashx)->first_dtor) { + (*var_hashx)->first_dtor = var_hash; + } else { + ((var_entries *) (*var_hashx)->last_dtor)->next = var_hash; + } + + (*var_hashx)->last_dtor = var_hash; + } + + var_hash->data[var_hash->used_slots++] = *rval; +} + PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval) { long i; var_entries *var_hash = (*var_hashx)->first; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_replace(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(nzval)); #endif @@ -102,7 +127,7 @@ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **n static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store) { var_entries *var_hash = (*var_hashx)->first; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_access(%ld): %ld\n", var_hash?var_hash->used_slots:-1L, id); #endif @@ -125,7 +150,7 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) void *next; long i; var_entries *var_hash = (*var_hashx)->first; -#if 0 +#if VAR_ENTRIES_DBG fprintf(stderr, "var_destroy(%ld)\n", var_hash?var_hash->used_slots:-1L); #endif @@ -472,7 +497,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) if (*rval == *rval_ref) return 0; if (*rval != NULL) { - zval_ptr_dtor(rval); + var_push_dtor_no_addref(var_hash, rval); } *rval = *rval_ref; Z_ADDREF_PP(rval); @@ -683,9 +708,9 @@ object ":" uiv ":" ["] { do { /* Try to find class directly */ - BG(serialize_lock) = 1; + BG(serialize_lock)++; if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (EG(exception)) { efree(class_name); return 0; @@ -693,7 +718,7 @@ object ":" uiv ":" ["] { ce = *pce; break; } - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (EG(exception)) { efree(class_name); @@ -713,9 +738,9 @@ object ":" uiv ":" ["] { args[0] = &arg_func_name; MAKE_STD_ZVAL(arg_func_name); ZVAL_STRING(arg_func_name, class_name, 1); - BG(serialize_lock) = 1; + BG(serialize_lock)++; if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (EG(exception)) { efree(class_name); zval_ptr_dtor(&user_func); @@ -729,7 +754,7 @@ object ":" uiv ":" ["] { zval_ptr_dtor(&arg_func_name); break; } - BG(serialize_lock) = 0; + BG(serialize_lock)--; if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } @@ -757,7 +782,9 @@ object ":" uiv ":" ["] { *p = YYCURSOR; if (custom_object) { - int ret = object_custom(UNSERIALIZE_PASSTHRU, ce); + int ret; + + ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { php_store_class_name(*rval, class_name, len2); diff --git a/ext/xmlrpc/tests/003.phpt b/ext/xmlrpc/tests/003.phpt new file mode 100644 index 0000000000..3d6796dbab --- /dev/null +++ b/ext/xmlrpc/tests/003.phpt @@ -0,0 +1,109 @@ +--TEST-- +xmlrpc_encode() Simple test encode array +--SKIPIF-- +<?php if (!extension_loaded("xmlrpc")) print "skip"; ?> +--FILE-- +<?php + +$params = array( + "one" => "red", + "two" => "blue", + "three" => "green" +); + +$response = xmlrpc_encode($params); +echo $response; + +$params = array( + "red", + "blue", + "green" +); + +$response = xmlrpc_encode($params); +echo $response; + +$params = array( + 0 => "red", + 1 => "blue", + 3 => "green" +); + +$response = xmlrpc_encode($params); +echo $response; + +--EXPECT-- +<?xml version="1.0" encoding="utf-8"?> +<params> +<param> + <value> + <struct> + <member> + <name>one</name> + <value> + <string>red</string> + </value> + </member> + <member> + <name>two</name> + <value> + <string>blue</string> + </value> + </member> + <member> + <name>three</name> + <value> + <string>green</string> + </value> + </member> + </struct> + </value> +</param> +</params> +<?xml version="1.0" encoding="utf-8"?> +<params> +<param> + <value> + <array> + <data> + <value> + <string>red</string> + </value> + <value> + <string>blue</string> + </value> + <value> + <string>green</string> + </value> + </data> + </array> + </value> +</param> +</params> +<?xml version="1.0" encoding="utf-8"?> +<params> +<param> + <value> + <struct> + <member> + <name>0</name> + <value> + <string>red</string> + </value> + </member> + <member> + <name>1</name> + <value> + <string>blue</string> + </value> + </member> + <member> + <name>3</name> + <value> + <string>green</string> + </value> + </member> + </struct> + </value> +</param> +</params>
\ No newline at end of file diff --git a/ext/xmlrpc/tests/004.phpt b/ext/xmlrpc/tests/004.phpt new file mode 100644 index 0000000000..04f3ef315e --- /dev/null +++ b/ext/xmlrpc/tests/004.phpt @@ -0,0 +1,19 @@ +--TEST-- +xmlrpc_encode() Simple test encode int +--SKIPIF-- +<?php if (!extension_loaded("xmlrpc")) print "skip"; ?> +--FILE-- +<?php + +$response = xmlrpc_encode(1); +echo $response; + +--EXPECT-- +<?xml version="1.0" encoding="utf-8"?> +<params> +<param> + <value> + <int>1</int> + </value> +</param> +</params>
\ No newline at end of file |
