mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-09 10:10:50 +00:00
Compare commits
113
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
197a7083df | ||
|
|
13389613fa | ||
|
|
f98f4875df | ||
|
|
b1680c5fe3 | ||
|
|
8cb114413f | ||
|
|
1e0f53278d | ||
|
|
d4f7e8cedc | ||
|
|
a1fdfa700b | ||
|
|
0a36d417e8 | ||
|
|
a04fac84e7 | ||
|
|
600402d986 | ||
|
|
340a06778c | ||
|
|
da3a807f22 | ||
|
|
454d297564 | ||
|
|
7a8ffcec7d | ||
|
|
29fa4d203a | ||
|
|
0826a54836 | ||
|
|
25f5a1b2e1 | ||
|
|
eebcfeb68e | ||
|
|
0a181ca27a | ||
|
|
9688071679 | ||
|
|
50f476591f | ||
|
|
39d8fc1edc | ||
|
|
206fd35a98 | ||
|
|
75cb678206 | ||
|
|
498eb8e052 | ||
|
|
688e56d0ac | ||
|
|
838951c2d6 | ||
|
|
bc7ea73da5 | ||
|
|
538f95b1b7 | ||
|
|
c483b59124 | ||
|
|
06bfada99b | ||
|
|
bccca0b53a | ||
|
|
4be867e910 | ||
|
|
a08847ab39 | ||
|
|
4adc08a403 | ||
|
|
5e4ee3d0bd | ||
|
|
eb1d1fe373 | ||
|
|
f448b0e6dd | ||
|
|
282355efd5 | ||
|
|
c93b461ad7 | ||
|
|
fc4cd598a2 | ||
|
|
703bbf5210 | ||
|
|
f901bec494 | ||
|
|
5787f91c55 | ||
|
|
8fc0bdfb0a | ||
|
|
797edd6211 | ||
|
|
e0e167e581 | ||
|
|
51e2015af3 | ||
|
|
71297a254b | ||
|
|
2c508c4d40 | ||
|
|
e857936518 | ||
|
|
988c3f9659 | ||
|
|
ae0585c98e | ||
|
|
a480bf8093 | ||
|
|
8309c04464 | ||
|
|
766f827e26 | ||
|
|
3ec37a74a2 | ||
|
|
78b0a85de6 | ||
|
|
67bb06cc9b | ||
|
|
729cd8bacd | ||
|
|
81396ea890 | ||
|
|
963e50c8c4 | ||
|
|
073b6ea818 | ||
|
|
d7c98ca1ac | ||
|
|
6dd85f83f7 | ||
|
|
84b6152842 | ||
|
|
9552cf6b84 | ||
|
|
2d858fbfb1 | ||
|
|
6d3d9104e6 | ||
|
|
7566742754 | ||
|
|
64b1085464 | ||
|
|
7b7d99839c | ||
|
|
3646604203 | ||
|
|
44a80b64b9 | ||
|
|
c34c523467 | ||
|
|
4f508003a9 | ||
|
|
03713ace23 | ||
|
|
ca7547c9e2 | ||
|
|
4ff2665509 | ||
|
|
3f8d21b922 | ||
|
|
8b7aaad7d6 | ||
|
|
958e3b93c3 | ||
|
|
06c9633b43 | ||
|
|
1bb2a4f91c | ||
|
|
3d09626f0d | ||
|
|
039ca4e219 | ||
|
|
8c04944b66 | ||
|
|
54fa0a69f8 | ||
|
|
51d76c346e | ||
|
|
675a9b2831 | ||
|
|
57257a4335 | ||
|
|
7e9479083d | ||
|
|
217b9e7b41 | ||
|
|
ab8177de2c | ||
|
|
86de4d7af6 | ||
|
|
3c939e3f69 | ||
|
|
aeb4f21549 | ||
|
|
067f7e4150 | ||
|
|
21f861225a | ||
|
|
9c673083cd | ||
|
|
fbf8c758fe | ||
|
|
4a89e726bd | ||
|
|
6a0b889f57 | ||
|
|
94af11d5e1 | ||
|
|
61ed904cec | ||
|
|
3f183bbcf8 | ||
|
|
072cfef1d5 | ||
|
|
491488d217 | ||
|
|
edb389730d | ||
|
|
6adfb8c962 | ||
|
|
4c1b3e3036 | ||
|
|
a33d0c3aae |
No files matched your search
@@ -11,9 +11,7 @@ end
|
||||
|
||||
define ____executor_globals
|
||||
if basic_functions_module.zts
|
||||
if !$tsrm_ls
|
||||
set $tsrm_ls = ts_resource_ex(0, 0)
|
||||
end
|
||||
set $tsrm_ls = _tsrm_ls_cache
|
||||
set $eg = ((zend_executor_globals*) (*((void ***) $tsrm_ls))[executor_globals_id-1])
|
||||
set $cg = ((zend_compiler_globals*) (*((void ***) $tsrm_ls))[compiler_globals_id-1])
|
||||
set $eg_ptr = $eg
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.01
|
||||
Copyright (c) 1999 - 2019 The PHP Group. All rights reserved.
|
||||
Copyright (c) 1999 - 2021 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,5 +1,120 @@
|
||||
PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
29 Apr 2021, PHP 7.4.18
|
||||
|
||||
- Core:
|
||||
. Fixed bug #80781 (Error handler that throws ErrorException infinite loop).
|
||||
(Nikita)
|
||||
. Fixed bug #75776 (Flushing streams with compression filter is broken). (cmb)
|
||||
|
||||
- Dba:
|
||||
. Fixed bug #80817 (dba_popen() may cause segfault during RSHUTDOWN). (cmb)
|
||||
|
||||
- DOM:
|
||||
. Fixed bug #66783 (UAF when appending DOMDocument to element). (cmb)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #80024 (Duplication of info about inherited socket after pool
|
||||
removing). (Jakub Zelenka)
|
||||
|
||||
- FTP:
|
||||
. Fixed bug #80880 (SSL_read on shutdown, ftp/proc_open). (cmb, Jakub
|
||||
Zelenka)
|
||||
|
||||
- Imap:
|
||||
. Fixed bug #80710 (imap_mail_compose() header injection). (cmb, Stas)
|
||||
|
||||
- Intl:
|
||||
. Fixed bug #80763 (msgfmt_format() does not accept DateTime references).
|
||||
(cmb)
|
||||
|
||||
- LibXML:
|
||||
. Fixed bug #51903 (simplexml_load_file() doesn't use HTTP headers). (cmb)
|
||||
. Fixed bug #73533 (Invalid memory access in php_libxml_xmlCheckUTF8). (cmb)
|
||||
|
||||
- MySQLnd:
|
||||
. Fixed bug #80713 (SegFault when disabling ATTR_EMULATE_PREPARES and
|
||||
MySQL 8.0). (Nikita)
|
||||
. Fixed bug #80837 (Calling stmt_store_result after fetch doesn't throw an
|
||||
error). (Kamil Tekiela)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #80805 (create simple class and get error in opcache.so). (Nikita)
|
||||
. Fixed bug #80950 (Variables become null in if statements). (Nikita)
|
||||
|
||||
- Pcntl:
|
||||
. Fixed bug #79812 (Potential integer overflow in pcntl_exec()). (cmb)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #80866 (preg_split ignores limit flag when pattern with \K has
|
||||
0-width fullstring match). (Kamil Tekiela)
|
||||
|
||||
- PDO_ODBC:
|
||||
. Fixed bug #80783 (PDO ODBC truncates BLOB records at every 256th byte).
|
||||
(cmb)
|
||||
|
||||
- PDO_pgsql:
|
||||
. Fixed bug #80892 (PDO::PARAM_INT is treated the same as PDO::PARAM_STR).
|
||||
(Matteo)
|
||||
|
||||
- phpdbg:
|
||||
. Fixed bug #80757 (Exit code is 0 when could not open file). (Felipe)
|
||||
|
||||
- Session:
|
||||
. Fixed bug #80774 (session_name() problem with backslash). (cmb)
|
||||
. Fixed bug #80889 (Cannot set save handler when save_handler is invalid).
|
||||
(cmb)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug #69668 (SOAP special XML characters in namespace URIs not
|
||||
encoded). (cmb)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #78719 (http wrapper silently ignores long Location headers).
|
||||
(cmb)
|
||||
. Fixed bug #80771 (phpinfo(INFO_CREDITS) displays nothing in CLI). (cmb)
|
||||
. Fixed bug #80838 (HTTP wrapper waits for HTTP 1 response after HTTP 101).
|
||||
(manuelm)
|
||||
. Fixed bug #80915 (Taking a reference to $_SERVER hides its values from
|
||||
phpinfo()). (Rowan Tommins)
|
||||
|
||||
04 Mar 2021, php 7.4.16
|
||||
|
||||
- Core:
|
||||
. Fixed #80706 (mail(): Headers after Bcc headers may be ignored). (cmb)
|
||||
|
||||
- MySQLnd:
|
||||
. Fixed bug #78680 (mysqlnd's mysql_clear_password does not transmit
|
||||
null-terminated password). (Daniel Black)
|
||||
|
||||
- MySQLi:
|
||||
. Fixed bug #74779 (x() and y() truncating floats to integers). (cmb)
|
||||
|
||||
- OPcache:
|
||||
. Fixed bug #80682 (opcache doesn't honour pcre.jit option). (Remi)
|
||||
|
||||
- OpenSSL:
|
||||
. Fixed bug #80747 (Providing RSA key size < 512 generates key that crash
|
||||
PHP). (Nikita)
|
||||
|
||||
- Phar:
|
||||
. Fixed bug #75850 (Unclear error message wrt. __halt_compiler() w/o
|
||||
semicolon) (cmb)
|
||||
. Fixed bug #70091 (Phar does not mark UTF-8 filenames in ZIP archives). (cmb)
|
||||
. Fixed bug #53467 (Phar cannot compress large archives). (cmb, lserni)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug#80719 (Iterating after failed ArrayObject::setIteratorClass()
|
||||
causes Segmentation fault). (Nikita)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #80654 (file_get_contents() maxlen fails above (2**31)-1 bytes).
|
||||
(cmb)
|
||||
|
||||
- Zip:
|
||||
. Fixed bug #80648 (Fix for bug 79296 should be based on runtime version).
|
||||
(cmb, Remi)
|
||||
|
||||
04 Feb 2021, PHP 7.4.15
|
||||
|
||||
- Core:
|
||||
@@ -28,10 +143,6 @@ PHP NEWS
|
||||
. Fixed bug #69279 (Compressed ZIP Phar extractTo() creates garbage files).
|
||||
(cmb)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug #80672 (Null Dereference in SoapClient). (CVE-2021-21702) (cmb,
|
||||
Stas)
|
||||
|
||||
07 Jan 2021, PHP 7.4.14
|
||||
|
||||
- Core:
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
HT iterator should be destroyed if array becomes empty during array_splice
|
||||
--FILE--
|
||||
<?php
|
||||
$a=[4];
|
||||
$i = 0;
|
||||
foreach ($a as &$r) {
|
||||
var_dump($r);
|
||||
$a = array_splice($a, 0);
|
||||
if (++$i == 2) break;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
int(4)
|
||||
int(4)
|
||||
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
Bug #80781: Error handler that throws ErrorException infinite loop
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function handle(int $severity, string $message, string $file, int $line): bool {
|
||||
if((error_reporting() & $severity) !== 0) {
|
||||
throw new \ErrorException($message, 0, $severity, $file, $line);
|
||||
}
|
||||
|
||||
return true; // stfu operator
|
||||
}
|
||||
|
||||
set_error_handler('handle');
|
||||
|
||||
function getPlugin(string $plugin) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$array = [];
|
||||
if (isset($array[$data]) or getPlugin($data)) {
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught ErrorException: Illegal offset type in isset or empty in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): handle(2, 'Illegal offset ...', %s, %d, Array)
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Symtable cache slots may be acquired while cleaning symtable
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
// Must be larger than the symtable cache.
|
||||
static $max = 40;
|
||||
function __destruct() {
|
||||
if (self::$max-- < 0) return;
|
||||
$x = 'y';
|
||||
$$x = new a;
|
||||
}
|
||||
}
|
||||
new A;
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
+1
-1
@@ -1099,7 +1099,7 @@ static zend_always_inline void zend_mm_free_pages_ex(zend_mm_heap *heap, zend_mm
|
||||
/* this setting may be not accurate */
|
||||
chunk->free_tail = page_num;
|
||||
}
|
||||
if (free_chunk && chunk->free_pages == ZEND_MM_PAGES - ZEND_MM_FIRST_PAGE) {
|
||||
if (free_chunk && chunk != heap->main_chunk && chunk->free_pages == ZEND_MM_PAGES - ZEND_MM_FIRST_PAGE) {
|
||||
zend_mm_delete_chunk(heap, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-7
@@ -51,11 +51,11 @@
|
||||
# define ZEND_VM_FP_GLOBAL_REG "%r14"
|
||||
# define ZEND_VM_IP_GLOBAL_REG "%r15"
|
||||
# elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__powerpc64__)
|
||||
# define ZEND_VM_FP_GLOBAL_REG "r28"
|
||||
# define ZEND_VM_IP_GLOBAL_REG "r29"
|
||||
# define ZEND_VM_FP_GLOBAL_REG "r14"
|
||||
# define ZEND_VM_IP_GLOBAL_REG "r15"
|
||||
# elif defined(__IBMC__) && ZEND_GCC_VERSION >= 4002 && defined(__powerpc64__)
|
||||
# define ZEND_VM_FP_GLOBAL_REG "r28"
|
||||
# define ZEND_VM_IP_GLOBAL_REG "r29"
|
||||
# define ZEND_VM_FP_GLOBAL_REG "r14"
|
||||
# define ZEND_VM_IP_GLOBAL_REG "r15"
|
||||
# elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__aarch64__)
|
||||
# define ZEND_VM_FP_GLOBAL_REG "x27"
|
||||
# define ZEND_VM_IP_GLOBAL_REG "x28"
|
||||
@@ -3437,12 +3437,13 @@ ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_val
|
||||
|
||||
ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */
|
||||
{
|
||||
/* Clean before putting into the cache, since clean could call dtors,
|
||||
* which could use the cached hash. Also do this before the check for
|
||||
* available cache slots, as those may be used by a dtor as well. */
|
||||
zend_symtable_clean(symbol_table);
|
||||
if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
|
||||
zend_array_destroy(symbol_table);
|
||||
} else {
|
||||
/* clean before putting into the cache, since clean
|
||||
could call dtors, which could use cached hash */
|
||||
zend_symtable_clean(symbol_table);
|
||||
*(EG(symtable_cache_ptr)++) = symbol_table;
|
||||
}
|
||||
}
|
||||
@@ -4554,6 +4555,7 @@ static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame(uint
|
||||
if (check_exception) { \
|
||||
OPLINE = EX(opline) + (skip); \
|
||||
} else { \
|
||||
ZEND_ASSERT(!EG(exception)); \
|
||||
OPLINE = opline + (skip); \
|
||||
} \
|
||||
ZEND_VM_CONTINUE()
|
||||
|
||||
+1
-1
@@ -1630,10 +1630,10 @@ ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
|
||||
} else if (EXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
|
||||
goto free_ht;
|
||||
}
|
||||
zend_hash_iterators_remove(ht);
|
||||
SET_INCONSISTENT(HT_DESTROYED);
|
||||
efree(HT_GET_DATA_ADDR(ht));
|
||||
free_ht:
|
||||
zend_hash_iterators_remove(ht);
|
||||
FREE_HASHTABLE(ht);
|
||||
}
|
||||
|
||||
|
||||
@@ -6937,6 +6937,10 @@ ZEND_VM_C_LABEL(num_index_prop):
|
||||
ZEND_VM_C_GOTO(isset_again);
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
ZEND_VM_C_GOTO(isset_dim_obj_exit);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
|
||||
@@ -6302,6 +6302,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -8496,6 +8500,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -10949,6 +10957,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -14985,6 +14997,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -16402,6 +16418,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -17689,6 +17709,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -41505,6 +41529,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -44950,6 +44978,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
@@ -50123,6 +50155,10 @@ num_index_prop:
|
||||
goto isset_again;
|
||||
} else {
|
||||
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
result = 0;
|
||||
goto isset_dim_obj_exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(opline->extended_value & ZEND_ISEMPTY)) {
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
- script: |
|
||||
git clone https://github.com/laravel/framework.git --branch=master --depth=1
|
||||
cd framework
|
||||
php7.3 /usr/bin/composer install --no-progress
|
||||
php7.4 /usr/bin/composer install --no-progress
|
||||
export USE_ZEND_ALLOC=0
|
||||
sed -i 's/$exit = true/$exit = false/g' vendor/phpunit/phpunit/src/TextUI/Command.php
|
||||
# Avoid test using exit(), which thus leaks.
|
||||
@@ -61,8 +61,8 @@ jobs:
|
||||
- script: |
|
||||
git clone https://github.com/symfony/symfony.git --depth=1
|
||||
cd symfony
|
||||
php7.3 /usr/bin/composer install --no-progress
|
||||
php7.3 ./phpunit install
|
||||
php7.4 /usr/bin/composer install --no-progress
|
||||
php7.4 ./phpunit install
|
||||
export USE_ZEND_ALLOC=0
|
||||
export USE_TRACKED_ALLOC=1
|
||||
export ASAN_OPTIONS=exitcode=139
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
displayName: 'Test Amphp'
|
||||
condition: or(succeeded(), failed())
|
||||
- script: |
|
||||
php7.3 /usr/bin/composer create-project symfony/symfony-demo symfony_demo --no-progress
|
||||
php7.4 /usr/bin/composer create-project symfony/symfony-demo symfony_demo --no-progress
|
||||
cd symfony_demo
|
||||
export USE_ZEND_ALLOC=0
|
||||
export USE_TRACKED_ALLOC=1
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ parameters:
|
||||
jobs:
|
||||
- job: ${{ parameters.configurationName }}
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: 'ubuntu-20.04'
|
||||
steps:
|
||||
- template: apt.yml
|
||||
- script: |
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice.
|
||||
dnl ----------------------------------------------------------------------------
|
||||
|
||||
AC_PREREQ([2.68])
|
||||
AC_INIT([PHP],[7.4.15],[https://bugs.php.net],[php],[https://www.php.net])
|
||||
AC_INIT([PHP],[7.4.18],[https://bugs.php.net],[php],[https://www.php.net])
|
||||
AC_CONFIG_SRCDIR([main/php_version.h])
|
||||
AC_CONFIG_AUX_DIR([build])
|
||||
AC_PRESERVE_HELP_ORDER
|
||||
@@ -568,7 +568,7 @@ dnl Fix for these systems is already included in GCC 7, but not on GCC 6.
|
||||
dnl
|
||||
dnl At least some versions of FreeBSD seem to have buggy ifunc support, see
|
||||
dnl bug #77284. Conservatively don't use ifuncs on FreeBSD.
|
||||
AS_CASE([$host_alias], [*-*-*android*|*-*-*uclibc*|*-*-*musl*|*freebsd*], [true], [
|
||||
AS_CASE([$host_alias], [*-*-*android*|*-*-*uclibc*|*-*-*musl*|*freebsd*|*openbsd*], [true], [
|
||||
AX_GCC_FUNC_ATTRIBUTE([ifunc])
|
||||
AX_GCC_FUNC_ATTRIBUTE([target])
|
||||
])
|
||||
|
||||
+10
-3
@@ -41,6 +41,7 @@ typedef struct _php_bz2_filter_data {
|
||||
enum strm_status status; /* Decompress option */
|
||||
unsigned int small_footprint : 1; /* Decompress option */
|
||||
unsigned int expect_concatenated : 1; /* Decompress option */
|
||||
unsigned int is_flushed : 1; /* only for compression */
|
||||
|
||||
int persistent;
|
||||
} php_bz2_filter_data;
|
||||
@@ -228,6 +229,8 @@ static php_stream_filter_status_t php_bz2_compress_filter(
|
||||
bucket = php_stream_bucket_make_writeable(buckets_in->head);
|
||||
|
||||
while (bin < bucket->buflen) {
|
||||
int flush_mode;
|
||||
|
||||
desired = bucket->buflen - bin;
|
||||
if (desired > data->inbuf_len) {
|
||||
desired = data->inbuf_len;
|
||||
@@ -235,7 +238,9 @@ static php_stream_filter_status_t php_bz2_compress_filter(
|
||||
memcpy(data->strm.next_in, bucket->buf + bin, desired);
|
||||
data->strm.avail_in = desired;
|
||||
|
||||
status = BZ2_bzCompress(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : (flags & PSFS_FLAG_FLUSH_INC ? BZ_FLUSH : BZ_RUN));
|
||||
flush_mode = flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : (flags & PSFS_FLAG_FLUSH_INC ? BZ_FLUSH : BZ_RUN);
|
||||
data->is_flushed = flush_mode != BZ_RUN;
|
||||
status = BZ2_bzCompress(&(data->strm), flush_mode);
|
||||
if (status != BZ_RUN_OK && status != BZ_FLUSH_OK && status != BZ_FINISH_OK) {
|
||||
/* Something bad happened */
|
||||
php_stream_bucket_delref(bucket);
|
||||
@@ -261,11 +266,12 @@ static php_stream_filter_status_t php_bz2_compress_filter(
|
||||
php_stream_bucket_delref(bucket);
|
||||
}
|
||||
|
||||
if (flags & PSFS_FLAG_FLUSH_CLOSE) {
|
||||
if (flags & PSFS_FLAG_FLUSH_CLOSE || ((flags & PSFS_FLAG_FLUSH_INC) && !data->is_flushed)) {
|
||||
/* Spit it out! */
|
||||
status = BZ_FINISH_OK;
|
||||
while (status == BZ_FINISH_OK) {
|
||||
status = BZ2_bzCompress(&(data->strm), BZ_FINISH);
|
||||
status = BZ2_bzCompress(&(data->strm), (flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : BZ_FLUSH));
|
||||
data->is_flushed = 1;
|
||||
if (data->strm.avail_out < data->outbuf_len) {
|
||||
size_t bucketlen = data->outbuf_len - data->strm.avail_out;
|
||||
|
||||
@@ -381,6 +387,7 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
|
||||
}
|
||||
|
||||
status = BZ2_bzCompressInit(&(data->strm), blockSize100k, 0, workFactor);
|
||||
data->is_flushed = 1;
|
||||
fops = &php_bz2_compress_ops;
|
||||
} else {
|
||||
status = BZ_DATA_ERROR;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
Bug #75776 (Flushing streams with compression filter is broken)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('bz2')) die('skip bz2 extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$text = str_repeat('0123456789abcdef', 1000);
|
||||
|
||||
$temp = fopen('php://temp', 'r+');
|
||||
stream_filter_append($temp, 'bzip2.compress', STREAM_FILTER_WRITE);
|
||||
fwrite($temp, $text);
|
||||
|
||||
rewind($temp);
|
||||
|
||||
var_dump(bin2hex(stream_get_contents($temp)));
|
||||
var_dump(ftell($temp));
|
||||
|
||||
fclose($temp);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(144) "425a68343141592653599fe7bbbf0001f389007fe03f002000902980026826aa80003ea9061520c6a41954833a9069520d6a41b54837a9071520e6a41d5483ba9079520f6a41f548"
|
||||
int(72)
|
||||
@@ -2207,6 +2207,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
|
||||
#endif
|
||||
|
||||
prop = zend_read_property(curl_CURLFile_class, current, "name", sizeof("name")-1, 0, &rv);
|
||||
ZVAL_DEREF(prop);
|
||||
if (Z_TYPE_P(prop) != IS_STRING) {
|
||||
php_error_docref(NULL, E_WARNING, "Invalid filename for key %s", ZSTR_VAL(string_key));
|
||||
} else {
|
||||
@@ -2217,10 +2218,12 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
|
||||
}
|
||||
|
||||
prop = zend_read_property(curl_CURLFile_class, current, "mime", sizeof("mime")-1, 0, &rv);
|
||||
ZVAL_DEREF(prop);
|
||||
if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
|
||||
type = Z_STRVAL_P(prop);
|
||||
}
|
||||
prop = zend_read_property(curl_CURLFile_class, current, "postname", sizeof("postname")-1, 0, &rv);
|
||||
ZVAL_DEREF(prop);
|
||||
if (Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
|
||||
filename = Z_STRVAL_P(prop);
|
||||
}
|
||||
|
||||
+2681
-2482
File diff suppressed because it is too large.
Load diff
+2
-2
@@ -972,9 +972,9 @@ restart:
|
||||
zend_bool close_both;
|
||||
|
||||
close_both = (info->fp != info->lock.fp);
|
||||
php_stream_close(info->lock.fp);
|
||||
php_stream_free(info->lock.fp, persistent ? PHP_STREAM_FREE_CLOSE_PERSISTENT : PHP_STREAM_FREE_CLOSE);
|
||||
if (close_both) {
|
||||
php_stream_close(info->fp);
|
||||
php_stream_free(info->fp, persistent ? PHP_STREAM_FREE_CLOSE_PERSISTENT : PHP_STREAM_FREE_CLOSE);
|
||||
}
|
||||
info->fp = NULL;
|
||||
info->lock.fp = NULL;
|
||||
|
||||
+7
-3
@@ -1302,9 +1302,13 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child)
|
||||
{
|
||||
xmlNodePtr nodep;
|
||||
|
||||
if (parent == NULL || child == NULL || child->doc != parent->doc) {
|
||||
return SUCCESS;
|
||||
}
|
||||
if (parent == NULL || child == NULL || child->doc != parent->doc) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (child->type == XML_DOCUMENT_NODE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
nodep = parent;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ require_once __DIR__ .'/skipif.inc';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$filename = __DIR__."/tmp_savehtmlfile".time().".html";
|
||||
$filename = __DIR__."/DOMDocument_saveHTMLFile_basic.html";
|
||||
$doc = new DOMDocument('1.0');
|
||||
$root = $doc->createElement('html');
|
||||
$root = $doc->appendChild($root);
|
||||
|
||||
@@ -9,7 +9,7 @@ require_once __DIR__ .'/skipif.inc';
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$filename = __DIR__."/tmp_savehtmlfile".time().".html";
|
||||
$filename = __DIR__."/DOMDocument_saveHTMLFile_formatOutput.html";
|
||||
$doc = new DOMDocument('1.0');
|
||||
$doc->formatOutput = true;
|
||||
$root = $doc->createElement('html');
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Bug #66783 (UAF when appending DOMDocument to element)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('dom')) die('skip dom extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$doc = new DomDocument;
|
||||
$doc->loadXML('<root></root>');
|
||||
$e = $doc->createElement('e');
|
||||
try {
|
||||
$e->appendChild($doc);
|
||||
} catch (DOMException $ex) {
|
||||
echo $ex->getMessage(), PHP_EOL;
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Hierarchy Request Error
|
||||
@@ -1931,6 +1931,12 @@ static void ftp_ssl_shutdown(ftpbuf_t *ftp, php_socket_t fd, SSL *ssl_handle) {
|
||||
/* SSL wants a write. Really odd. Let's bail out. */
|
||||
done = 1;
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
/* most likely the peer closed the connection without
|
||||
sending a close_notify shutdown alert;
|
||||
bail out to avoid raising a spurious warning */
|
||||
done = 1;
|
||||
break;
|
||||
default:
|
||||
if ((sslerror = ERR_get_error())) {
|
||||
ERR_error_string_n(sslerror, buf, sizeof(buf));
|
||||
|
||||
@@ -3551,6 +3551,23 @@ PHP_FUNCTION(imap_fetch_overview)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_bool header_injection(zend_string *str, zend_bool adrlist)
|
||||
{
|
||||
char *p = ZSTR_VAL(str);
|
||||
|
||||
while ((p = strpbrk(p, "\r\n")) != NULL) {
|
||||
if (!(p[0] == '\r' && p[1] == '\n')
|
||||
/* adrlists do not support folding, but swallow trailing line breaks */
|
||||
&& !((adrlist && p[1] == '\0')
|
||||
/* other headers support folding */
|
||||
|| !adrlist && (p[1] == ' ' || p[1] == '\t'))) {
|
||||
return 1;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* {{{ proto string imap_mail_compose(array envelope, array body)
|
||||
Create a MIME message based on given envelope and body sections */
|
||||
PHP_FUNCTION(imap_mail_compose)
|
||||
@@ -3571,6 +3588,13 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
return;
|
||||
}
|
||||
|
||||
#define CHECK_HEADER_INJECTION(zstr, adrlist, header) \
|
||||
if (header_injection(zstr, adrlist)) { \
|
||||
php_error_docref(NULL, E_WARNING, "header injection attempt in " header); \
|
||||
RETVAL_FALSE; \
|
||||
goto done; \
|
||||
}
|
||||
|
||||
#define PHP_RFC822_PARSE_ADRLIST(target, value) \
|
||||
str_copy = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); \
|
||||
rfc822_parse_adrlist(target, str_copy, "NO HOST"); \
|
||||
@@ -3579,46 +3603,57 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
env = mail_newenvelope();
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "remail", sizeof("remail") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "remail");
|
||||
env->remail = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "return_path", sizeof("return_path") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "return_path");
|
||||
PHP_RFC822_PARSE_ADRLIST(&env->return_path, pvalue);
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "date", sizeof("date") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "date");
|
||||
env->date = (unsigned char*)cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "from", sizeof("from") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "from");
|
||||
PHP_RFC822_PARSE_ADRLIST(&env->from, pvalue);
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "reply_to", sizeof("reply_to") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "reply_to");
|
||||
PHP_RFC822_PARSE_ADRLIST(&env->reply_to, pvalue);
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "in_reply_to", sizeof("in_reply_to") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "in_reply_to");
|
||||
env->in_reply_to = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "subject", sizeof("subject") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "subject");
|
||||
env->subject = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "to", sizeof("to") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "to");
|
||||
PHP_RFC822_PARSE_ADRLIST(&env->to, pvalue);
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "cc", sizeof("cc") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "cc");
|
||||
PHP_RFC822_PARSE_ADRLIST(&env->cc, pvalue);
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "bcc", sizeof("bcc") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "bcc");
|
||||
PHP_RFC822_PARSE_ADRLIST(&env->bcc, pvalue);
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "message_id", sizeof("message_id") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "message_id");
|
||||
env->message_id=cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
|
||||
@@ -3629,6 +3664,7 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pvalue), env_data) {
|
||||
custom_headers_param = mail_newbody_parameter();
|
||||
convert_to_string_ex(env_data);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(env_data), 0, "custom_headers");
|
||||
custom_headers_param->value = (char *) fs_get(Z_STRLEN_P(env_data) + 1);
|
||||
custom_headers_param->attribute = NULL;
|
||||
memcpy(custom_headers_param->value, Z_STRVAL_P(env_data), Z_STRLEN_P(env_data) + 1);
|
||||
@@ -3667,6 +3703,7 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset");
|
||||
tmp_param = mail_newbody_parameter();
|
||||
tmp_param->value = cpystr(Z_STRVAL_P(pvalue));
|
||||
tmp_param->attribute = cpystr("CHARSET");
|
||||
@@ -3679,9 +3716,11 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
SEPARATE_ARRAY(pvalue);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
|
||||
if (key == NULL) continue;
|
||||
CHECK_HEADER_INJECTION(key, 0, "body disposition key");
|
||||
disp_param = mail_newbody_parameter();
|
||||
disp_param->attribute = cpystr(ZSTR_VAL(key));
|
||||
convert_to_string_ex(disp_data);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value");
|
||||
disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1);
|
||||
memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
|
||||
disp_param->next = tmp_param;
|
||||
@@ -3692,18 +3731,22 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype");
|
||||
bod->subtype = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id");
|
||||
bod->id = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description");
|
||||
bod->description = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type");
|
||||
bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1);
|
||||
memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1);
|
||||
}
|
||||
@@ -3713,9 +3756,11 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
SEPARATE_ARRAY(pvalue);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
|
||||
if (key == NULL) continue;
|
||||
CHECK_HEADER_INJECTION(key, 0, "body type.parameters key");
|
||||
disp_param = mail_newbody_parameter();
|
||||
disp_param->attribute = cpystr(ZSTR_VAL(key));
|
||||
convert_to_string_ex(disp_data);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value");
|
||||
disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1);
|
||||
memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
|
||||
disp_param->next = tmp_param;
|
||||
@@ -3746,6 +3791,7 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5");
|
||||
bod->md5 = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
} else if (Z_TYPE_P(data) == IS_ARRAY && topbod->type == TYPEMULTIPART) {
|
||||
@@ -3778,6 +3824,7 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset");
|
||||
tmp_param = mail_newbody_parameter();
|
||||
tmp_param->value = (char *) fs_get(Z_STRLEN_P(pvalue) + 1);
|
||||
memcpy(tmp_param->value, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue) + 1);
|
||||
@@ -3791,9 +3838,11 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
SEPARATE_ARRAY(pvalue);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
|
||||
if (key == NULL) continue;
|
||||
CHECK_HEADER_INJECTION(key, 0, "body type.parameters key");
|
||||
disp_param = mail_newbody_parameter();
|
||||
disp_param->attribute = cpystr(ZSTR_VAL(key));
|
||||
convert_to_string_ex(disp_data);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value");
|
||||
disp_param->value = (char *)fs_get(Z_STRLEN_P(disp_data) + 1);
|
||||
memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
|
||||
disp_param->next = tmp_param;
|
||||
@@ -3804,18 +3853,22 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype");
|
||||
bod->subtype = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id");
|
||||
bod->id = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description");
|
||||
bod->description = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type");
|
||||
bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1);
|
||||
memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1);
|
||||
}
|
||||
@@ -3825,9 +3878,11 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
SEPARATE_ARRAY(pvalue);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
|
||||
if (key == NULL) continue;
|
||||
CHECK_HEADER_INJECTION(key, 0, "body disposition key");
|
||||
disp_param = mail_newbody_parameter();
|
||||
disp_param->attribute = cpystr(ZSTR_VAL(key));
|
||||
convert_to_string_ex(disp_data);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value");
|
||||
disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1);
|
||||
memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
|
||||
disp_param->next = tmp_param;
|
||||
@@ -3858,6 +3913,7 @@ PHP_FUNCTION(imap_mail_compose)
|
||||
}
|
||||
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) {
|
||||
convert_to_string_ex(pvalue);
|
||||
CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5");
|
||||
bod->md5 = cpystr(Z_STRVAL_P(pvalue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
Bug #80710 (imap_mail_compose() header injection) - MIME Splitting Attack
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("imap")) die("skip imap extension not available");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$envelope["from"]= "joe@example.com\n From : X-INJECTED";
|
||||
$envelope["to"] = "foo@example.com\nFrom: X-INJECTED";
|
||||
$envelope["cc"] = "bar@example.com\nFrom: X-INJECTED";
|
||||
$envelope["subject"] = "bar@example.com\n\n From : X-INJECTED";
|
||||
$envelope["x-remail"] = "bar@example.com\nFrom: X-INJECTED";
|
||||
$envelope["something"] = "bar@example.com\nFrom: X-INJECTED";
|
||||
|
||||
$part1["type"] = TYPEMULTIPART;
|
||||
$part1["subtype"] = "mixed";
|
||||
|
||||
$part2["type"] = TYPEAPPLICATION;
|
||||
$part2["encoding"] = ENCBINARY;
|
||||
$part2["subtype"] = "octet-stream\nContent-Type: X-INJECTED";
|
||||
$part2["description"] = "some file\nContent-Type: X-INJECTED";
|
||||
$part2["contents.data"] = "ABC\nContent-Type: X-INJECTED";
|
||||
|
||||
$part3["type"] = TYPETEXT;
|
||||
$part3["subtype"] = "plain";
|
||||
$part3["description"] = "description3";
|
||||
$part3["contents.data"] = "contents.data3\n\n\n\t";
|
||||
|
||||
$body[1] = $part1;
|
||||
$body[2] = $part2;
|
||||
$body[3] = $part3;
|
||||
|
||||
echo imap_mail_compose($envelope, $body);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: imap_mail_compose(): header injection attempt in from in %s on line %d
|
||||
@@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
Bug #80710 (imap_mail_compose() header injection) - Remail
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("imap")) die("skip imap extension not available");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$envelope["from"]= "joe@example.com\n From : X-INJECTED";
|
||||
$envelope["to"] = "foo@example.com\nFrom: X-INJECTED";
|
||||
$envelope["cc"] = "bar@example.com\nFrom: X-INJECTED";
|
||||
$envelope["subject"] = "bar@example.com\n\n From : X-INJECTED";
|
||||
$envelope["remail"] = "X-INJECTED-REMAIL: X-INJECTED\nFrom: X-INJECTED-REMAIL-FROM"; //<--- Injected as first hdr
|
||||
$envelope["something"] = "bar@example.com\nFrom: X-INJECTED";
|
||||
|
||||
$part1["type"] = TYPEMULTIPART;
|
||||
$part1["subtype"] = "mixed";
|
||||
|
||||
$part2["type"] = TYPEAPPLICATION;
|
||||
$part2["encoding"] = ENCBINARY;
|
||||
$part2["subtype"] = "octet-stream\nContent-Type: X-INJECTED";
|
||||
$part2["description"] = "some file\nContent-Type: X-INJECTED";
|
||||
$part2["contents.data"] = "ABC\nContent-Type: X-INJECTED";
|
||||
|
||||
$part3["type"] = TYPETEXT;
|
||||
$part3["subtype"] = "plain";
|
||||
$part3["description"] = "description3";
|
||||
$part3["contents.data"] = "contents.data3\n\n\n\t";
|
||||
|
||||
$body[1] = $part1;
|
||||
$body[2] = $part2;
|
||||
$body[3] = $part3;
|
||||
|
||||
echo imap_mail_compose($envelope, $body);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: imap_mail_compose(): header injection attempt in remail in %s on line %d
|
||||
@@ -175,6 +175,7 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func)
|
||||
return ZEND_NAN;
|
||||
}
|
||||
|
||||
try_again:
|
||||
switch (Z_TYPE_P(z)) {
|
||||
case IS_STRING:
|
||||
type = is_numeric_string(Z_STRVAL_P(z), Z_STRLEN_P(z), &lv, &rv, 0);
|
||||
@@ -227,6 +228,9 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func)
|
||||
efree(message);
|
||||
}
|
||||
break;
|
||||
case IS_REFERENCE:
|
||||
z = Z_REFVAL_P(z);
|
||||
goto try_again;
|
||||
default:
|
||||
spprintf(&message, 0, "%s: invalid PHP type for date", func);
|
||||
intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #80763 (msgfmt_format() does not accept DateTime references)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('intl')) die('skip intl extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$today = new DateTime('2021-02-17 12:00:00');
|
||||
$formatter = new \MessageFormatter('en_US', 'Today is {today, date, full}.');
|
||||
$params = ['today' => $today];
|
||||
array_walk($params, fn() => 1);
|
||||
var_dump($formatter->format($params));
|
||||
?>
|
||||
--EXPECT--
|
||||
string(38) "Today is Wednesday, February 17, 2021."
|
||||
+49
-1
@@ -409,6 +409,54 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Check if there's been an external transport protocol with an encoding information */
|
||||
if (enc == XML_CHAR_ENCODING_NONE) {
|
||||
php_stream *s = (php_stream *) context;
|
||||
|
||||
if (Z_TYPE(s->wrapperdata) == IS_ARRAY) {
|
||||
zval *header;
|
||||
|
||||
ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) {
|
||||
const char buf[] = "Content-Type:";
|
||||
if (Z_TYPE_P(header) == IS_STRING &&
|
||||
!zend_binary_strncasecmp(Z_STRVAL_P(header), Z_STRLEN_P(header), buf, sizeof(buf)-1, sizeof(buf)-1)) {
|
||||
char *needle = estrdup("charset=");
|
||||
char *haystack = estrndup(Z_STRVAL_P(header), Z_STRLEN_P(header));
|
||||
char *encoding = php_stristr(haystack, needle, Z_STRLEN_P(header), sizeof("charset=")-1);
|
||||
|
||||
if (encoding) {
|
||||
char *end;
|
||||
|
||||
encoding += sizeof("charset=")-1;
|
||||
if (*encoding == '"') {
|
||||
encoding++;
|
||||
}
|
||||
end = strchr(encoding, ';');
|
||||
if (end == NULL) {
|
||||
end = encoding + strlen(encoding);
|
||||
}
|
||||
end--; /* end == encoding-1 isn't a buffer underrun */
|
||||
while (*end == ' ' || *end == '\t') {
|
||||
end--;
|
||||
}
|
||||
if (*end == '"') {
|
||||
end--;
|
||||
}
|
||||
if (encoding >= end) continue;
|
||||
*(end+1) = '\0';
|
||||
enc = xmlParseCharEncoding(encoding);
|
||||
if (enc <= XML_CHAR_ENCODING_NONE) {
|
||||
enc = XML_CHAR_ENCODING_NONE;
|
||||
}
|
||||
}
|
||||
efree(haystack);
|
||||
efree(needle);
|
||||
break; /* found content-type */
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the Input buffer front-end. */
|
||||
ret = xmlAllocParserInputBuffer(enc);
|
||||
if (ret != NULL) {
|
||||
@@ -1134,7 +1182,7 @@ static PHP_FUNCTION(libxml_set_external_entity_loader)
|
||||
/* {{{ Common functions shared by extensions */
|
||||
int php_libxml_xmlCheckUTF8(const unsigned char *s)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
unsigned char c;
|
||||
|
||||
for (i = 0; (c = s[i++]);) {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
Bug #51903 (simplexml_load_file() doesn't use HTTP headers)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('simplexml')) die('skip simplexml extension not available');
|
||||
if (@!include "./ext/standard/tests/http/server.inc") die('skip server.inc not available');
|
||||
http_server_skipif('tcp://127.0.0.1:12342');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require "./ext/standard/tests/http/server.inc";
|
||||
$responses = [
|
||||
"data://text/plain,HTTP/1.1 200 OK\r\n"
|
||||
. "Content-Type: text/xml; charset=ISO-8859-1\r\n\r\n"
|
||||
. "<?xml version=\"1.0\"?>\n"
|
||||
. "<root>\xE4\xF6\xFC</root>\n",
|
||||
"data://text/plain,HTTP/1.1 200 OK\r\n"
|
||||
. "Content-Type: text/xml; charset=ISO-8859-1; foo=bar\r\n\r\n"
|
||||
. "<?xml version=\"1.0\"?>\n"
|
||||
. "<root>\xE4\xF6\xFC</root>\n",
|
||||
"data://text/plain,HTTP/1.1 200 OK\r\n"
|
||||
. "Content-Type: text/xml; charset=\"ISO-8859-1\" ; foo=bar\r\n\r\n"
|
||||
. "<?xml version=\"1.0\"?>\n"
|
||||
. "<root>\xE4\xF6\xFC</root>\n",
|
||||
];
|
||||
$pid = http_server('tcp://127.0.0.1:12342', $responses);
|
||||
|
||||
for ($i = 0; $i < count($responses); $i++) {
|
||||
$sxe = simplexml_load_file('http://127.0.0.1:12342/');
|
||||
echo "$sxe\n";
|
||||
}
|
||||
|
||||
http_server_kill($pid);
|
||||
?>
|
||||
--EXPECT--
|
||||
äöü
|
||||
äöü
|
||||
äöü
|
||||
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
Bug #74779 (x() and y() truncating floats to integers)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
require_once('skipifconnectfailure.inc');
|
||||
if (!setlocale(LC_NUMERIC, "de_DE", "de_DE.UTF-8", "de-DE")) die('skip locale not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("connect.inc");
|
||||
|
||||
if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
|
||||
printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
}
|
||||
|
||||
if (!setlocale(LC_NUMERIC, "de_DE", "de_DE.UTF-8", "de-DE")) {
|
||||
echo "[002] Cannot set locale\n";
|
||||
}
|
||||
|
||||
if (!$link->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true)) {
|
||||
printf("[003] [%d] %s\n", $link->errno, $link->error);
|
||||
}
|
||||
|
||||
if (!$result = $link->query("SELECT ST_Y(Point(56.7, 53.34))")) {
|
||||
printf("[004] [%d] %s\n", $link->errno, $link->error);
|
||||
}
|
||||
|
||||
if (!$array = $result->fetch_array(MYSQLI_ASSOC)) {
|
||||
printf("[005] [%d] %s\n", $link->errno, $link->error);
|
||||
}
|
||||
|
||||
var_dump($array);
|
||||
|
||||
mysqli_close($link);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
["ST_Y(Point(56.7, 53.34))"]=>
|
||||
float(53,34)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
--TEST--
|
||||
Bug #80837 Calling stmt_store_result after fetch doesn't throw an error
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once 'skipif.inc';
|
||||
require_once 'skipifconnectfailure.inc';
|
||||
if (!defined('MYSQLI_STORE_RESULT_COPY_DATA')) die('skip requires mysqlnd');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once "connect.inc";
|
||||
|
||||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
|
||||
$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
|
||||
|
||||
$mysqli->query('DROP TABLE IF EXISTS test');
|
||||
$mysqli->query('CREATE TABLE test (b int)');
|
||||
$mysqli->query('INSERT INTO test VALUES (1),(2),(3)');
|
||||
|
||||
$statement = $mysqli->prepare("SELECT b FROM test");
|
||||
$statement->execute();
|
||||
$statement->bind_result($name);
|
||||
$statement->fetch();
|
||||
try {
|
||||
$statement->store_result();
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
||||
$mysqli->close();
|
||||
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require_once "clean_table.inc";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Commands out of sync; you can't run this command now
|
||||
@@ -19,8 +19,8 @@ if (!$res = $link->query("SHOW PLUGINS"))
|
||||
|
||||
$have_pam = false;
|
||||
while ($row = $res->fetch_assoc()) {
|
||||
if (isset($row['Name']) && ('mysql_clear_password' == $row['Name'])) {
|
||||
$have_pam = true;
|
||||
if (isset($row['Name']) && in_array($row['Name'], array('pam', 'authentication_pam', 'auth_pam_compat'))) {
|
||||
$have_pam = $row['Name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,54 @@ $res->close();
|
||||
if (!$have_pam)
|
||||
die("SKIP Server PAM plugin not installed");
|
||||
|
||||
if ($have_pam == 'pam') {
|
||||
/* MariaDB - needs system variable pam_use_cleartext_plugin=ON to be set */
|
||||
if (!$res = mysqli_query($link, 'SHOW GLOBAL VARIABLES LIKE "pam_use_cleartext_plugin"'))
|
||||
die(sprintf("SKIP MariaDB probe of GLOBAL VARIABLES failed [%d] %s\n",
|
||||
mysqli_errno($link), mysqli_error($link)));
|
||||
$pam_use_cleartext_plugin = mysqli_fetch_row($res);
|
||||
mysqli_free_result($res);
|
||||
if (!$pam_use_cleartext_plugin or $pam_use_cleartext_plugin[1]!='ON')
|
||||
die("SKIP Server setting pam_use_cleartext_plugin!=ON");
|
||||
|
||||
$pam_service = file_get_contents('/etc/pam.d/mysql');
|
||||
} elseif ($have_pam == 'authentication_pam') {
|
||||
/*
|
||||
required MySQL syntax:
|
||||
https://dev.mysql.com/doc/refman/8.0/en/pam-pluggable-authentication.html#pam-pluggable-authentication-usage
|
||||
*/
|
||||
$have_pam .= " AS 'mysql-unix'";
|
||||
$pam_service = file_get_contents('/etc/pam.d/mysql-unix');
|
||||
} else {
|
||||
$pam_service = file_get_contents('/etc/pam.d/mysql');
|
||||
}
|
||||
$auth = 0;
|
||||
$account = 0;
|
||||
foreach (explode("\n", $pam_service) as $line)
|
||||
{
|
||||
if (preg_match('/^auth/', $line)) {
|
||||
$auth = 1;
|
||||
} elseif (preg_match('/^account/', $line)) {
|
||||
$account = 1;
|
||||
}
|
||||
}
|
||||
if (!$auth) {
|
||||
die("SKIP pam service file missing 'auth' directive");
|
||||
}
|
||||
if (!$account) {
|
||||
die("SKIP pam service file missing 'account' directive");
|
||||
}
|
||||
|
||||
if (!posix_getpwnam('pamtest')) {
|
||||
die("SKIP no pamtest user");
|
||||
}
|
||||
/* Password of user 'pamtest' should be set to 'pamtest' */
|
||||
|
||||
mysqli_query($link, 'DROP USER pamtest');
|
||||
mysqli_query($link, 'DROP USER pamtest@localhost');
|
||||
|
||||
if (!mysqli_query($link, 'CREATE USER pamtest@"%" IDENTIFIED WITH mysql_clear_password') ||
|
||||
!mysqli_query($link, 'CREATE USER pamtest@"localhost" IDENTIFIED WITH mysql_clear_password')) {
|
||||
if (!mysqli_query($link, "CREATE USER pamtest@'%' IDENTIFIED WITH $have_pam") ||
|
||||
!mysqli_query($link, "CREATE USER pamtest@'localhost' IDENTIFIED WITH $have_pam")) {
|
||||
printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link));
|
||||
mysqli_close($link);
|
||||
die("skip CREATE USER failed");
|
||||
@@ -60,8 +102,8 @@ max_execution_time=240
|
||||
require_once('table.inc');
|
||||
|
||||
if (!$link = my_mysqli_connect($host, 'pamtest', 'pamtest', $db, $port, $socket)) {
|
||||
printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $user, $db, $port, $socket);
|
||||
printf("[001] Cannot connect to the server using host=%s, user=pamtest, passwd=pamtest dbname=%s, port=%s, socket=%s\n",
|
||||
$host, $db, $port, $socket);
|
||||
} else {
|
||||
|
||||
if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
|
||||
@@ -88,6 +130,4 @@ max_execution_time=240
|
||||
mysqli_query($link, 'DROP USER pamtest@localhost');
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mysqli_real_connect(): (28000/1045): Access denied for user %s
|
||||
[001] Cannot connect to the server using host=%s
|
||||
done!
|
||||
@@ -652,7 +652,11 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self,
|
||||
if (passwd && passwd_len) {
|
||||
ret = (zend_uchar*) zend_strndup(passwd, passwd_len);
|
||||
}
|
||||
*auth_data_len = passwd_len;
|
||||
/*
|
||||
Trailing null required. bug#78680
|
||||
https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_authentication_methods_clear_text_password.html
|
||||
*/
|
||||
*auth_data_len = passwd_len + 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s)
|
||||
|
||||
/* Nothing to store for UPSERT/LOAD DATA*/
|
||||
if (!mysqlnd_stmt_check_state(stmt)) {
|
||||
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
|
||||
SET_CLIENT_ERROR(stmt->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -1216,8 +1216,9 @@ php_mysqlnd_rset_field_read(MYSQLND_CONN_DATA * conn, void * _packet)
|
||||
DBG_RETURN(PASS);
|
||||
} else if (EODATA_MARKER == *p && packet->header.size < 8) {
|
||||
/* Premature EOF. That should be COM_FIELD_LIST. But we don't support COM_FIELD_LIST anymore, thus this should not happen */
|
||||
DBG_INF("Premature EOF. That should be COM_FIELD_LIST");
|
||||
DBG_RETURN(PASS);
|
||||
DBG_ERR("Premature EOF. That should be COM_FIELD_LIST");
|
||||
php_error_docref(NULL, E_WARNING, "Premature EOF in result field metadata");
|
||||
DBG_RETURN(FAIL);
|
||||
}
|
||||
|
||||
meta = packet->metadata;
|
||||
@@ -1679,7 +1680,7 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_ROW_BUFFER * row_buffer, zval *
|
||||
zend_uchar save = *(p + len);
|
||||
/* We have to make it ASCIIZ temporarily */
|
||||
*(p + len) = '\0';
|
||||
ZVAL_DOUBLE(current_field, atof((char *) p));
|
||||
ZVAL_DOUBLE(current_field, zend_strtod((char *) p, NULL));
|
||||
*(p + len) = save;
|
||||
}
|
||||
#endif /* MYSQLND_STRING_TO_INT_CONVERSION */
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.01
|
||||
Copyright (c) 1999 - 2019 The PHP Group. All rights reserved.
|
||||
Copyright (c) 1999 - 2021 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -368,6 +368,10 @@ static zend_bool try_remove_var_def(context *ctx, int free_var, int use_chain, z
|
||||
return 0;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool may_be_refcounted(uint32_t type) {
|
||||
return (type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) != 0;
|
||||
}
|
||||
|
||||
/* Returns whether the instruction has been DCEd */
|
||||
static zend_bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
|
||||
zend_ssa *ssa = ctx->ssa;
|
||||
@@ -379,16 +383,15 @@ static zend_bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
|
||||
}
|
||||
|
||||
/* We mark FREEs as dead, but they're only really dead if the destroyed var is dead */
|
||||
if (opline->opcode == ZEND_FREE
|
||||
&& (ssa->var_info[ssa_op->op1_use].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))
|
||||
if (opline->opcode == ZEND_FREE && may_be_refcounted(ssa->var_info[ssa_op->op1_use].type)
|
||||
&& !is_var_dead(ctx, ssa_op->op1_use)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))&& !is_var_dead(ctx, ssa_op->op1_use)) {
|
||||
if (!try_remove_var_def(ctx, ssa_op->op1_use, ssa_op->op1_use_chain, opline)) {
|
||||
if (ssa->var_info[ssa_op->op1_use].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)
|
||||
&& opline->opcode != ZEND_CASE) {
|
||||
if (may_be_refcounted(ssa->var_info[ssa_op->op1_use].type)
|
||||
&& opline->opcode != ZEND_CASE) {
|
||||
free_var = ssa_op->op1_use;
|
||||
free_var_type = opline->op1_type;
|
||||
}
|
||||
@@ -396,7 +399,7 @@ static zend_bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
|
||||
}
|
||||
if ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) && !is_var_dead(ctx, ssa_op->op2_use)) {
|
||||
if (!try_remove_var_def(ctx, ssa_op->op2_use, ssa_op->op2_use_chain, opline)) {
|
||||
if (ssa->var_info[ssa_op->op2_use].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
|
||||
if (may_be_refcounted(ssa->var_info[ssa_op->op2_use].type)) {
|
||||
if (free_var >= 0) {
|
||||
// TODO: We can't free two vars. Keep instruction alive.
|
||||
zend_bitset_excl(ctx->instr_dead, opline - ctx->op_array->opcodes);
|
||||
@@ -503,6 +506,17 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reor
|
||||
ctx.phi_dead = alloca(sizeof(zend_ulong) * ctx.phi_worklist_len);
|
||||
memset(ctx.phi_dead, 0xff, sizeof(zend_ulong) * ctx.phi_worklist_len);
|
||||
|
||||
/* Mark non-CV phis as live. Even if the result is unused, we generally cannot remove one
|
||||
* of the producing instructions, as it combines producing the result with control flow.
|
||||
* This can be made more precise if there are any cases where this is not the case. */
|
||||
FOREACH_PHI(phi) {
|
||||
if (phi->var >= op_array->last_var
|
||||
&& may_be_refcounted(ssa->var_info[phi->ssa_var].type)) {
|
||||
zend_bitset_excl(ctx.phi_dead, phi->ssa_var);
|
||||
add_phi_sources_to_worklists(&ctx, phi, 0);
|
||||
}
|
||||
} FOREACH_PHI_END();
|
||||
|
||||
/* Mark reacable instruction without side effects as dead */
|
||||
int b = ssa->cfg.blocks_count;
|
||||
while (b > 0) {
|
||||
|
||||
@@ -1040,7 +1040,7 @@ static const func_info_t func_infos[] = {
|
||||
F1("curl_version", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_STRING | MAY_BE_ARRAY_OF_ARRAY),
|
||||
F0("curl_setopt", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
|
||||
F0("curl_setopt_array", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
|
||||
FN("curl_exec", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING),
|
||||
FN("curl_exec", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE | MAY_BE_STRING),
|
||||
F1("curl_getinfo", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING | MAY_BE_LONG | MAY_BE_DOUBLE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY),
|
||||
F1("curl_error", MAY_BE_NULL | MAY_BE_STRING),
|
||||
F0("curl_errno", MAY_BE_NULL | MAY_BE_LONG),
|
||||
|
||||
@@ -1947,6 +1947,18 @@ static void add_usages(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset
|
||||
if (op->op2_def >= 0) {
|
||||
zend_bitset_incl(worklist, op->op2_def);
|
||||
}
|
||||
} else if (use + 1 < op_array->last
|
||||
&& op_array->opcodes[use + 1].opcode == ZEND_OP_DATA) {
|
||||
op++;
|
||||
if (op->result_def >= 0) {
|
||||
zend_bitset_incl(worklist, op->result_def);
|
||||
}
|
||||
if (op->op1_def >= 0) {
|
||||
zend_bitset_incl(worklist, op->op1_def);
|
||||
}
|
||||
if (op->op2_def >= 0) {
|
||||
zend_bitset_incl(worklist, op->op2_def);
|
||||
}
|
||||
}
|
||||
use = zend_ssa_next_use(ssa->ops, var, use);
|
||||
} while (use >= 0);
|
||||
@@ -2141,7 +2153,7 @@ static uint32_t assign_dim_result_type(
|
||||
|
||||
/* For binary ops that have compound assignment operators */
|
||||
static uint32_t binary_op_result_type(
|
||||
zend_ssa *ssa, zend_uchar opcode, uint32_t t1, uint32_t t2, uint32_t result_var,
|
||||
zend_ssa *ssa, zend_uchar opcode, uint32_t t1, uint32_t t2, int result_var,
|
||||
zend_long optimization_level) {
|
||||
uint32_t tmp = 0;
|
||||
uint32_t t1_type = (t1 & MAY_BE_ANY) | (t1 & MAY_BE_UNDEF ? MAY_BE_NULL : 0);
|
||||
@@ -2159,7 +2171,8 @@ static uint32_t binary_op_result_type(
|
||||
switch (opcode) {
|
||||
case ZEND_ADD:
|
||||
if (t1_type == MAY_BE_LONG && t2_type == MAY_BE_LONG) {
|
||||
if (!ssa->var_info[result_var].has_range ||
|
||||
if (result_var < 0 ||
|
||||
!ssa->var_info[result_var].has_range ||
|
||||
ssa->var_info[result_var].range.underflow ||
|
||||
ssa->var_info[result_var].range.overflow) {
|
||||
/* may overflow */
|
||||
@@ -2185,7 +2198,8 @@ static uint32_t binary_op_result_type(
|
||||
case ZEND_SUB:
|
||||
case ZEND_MUL:
|
||||
if (t1_type == MAY_BE_LONG && t2_type == MAY_BE_LONG) {
|
||||
if (!ssa->var_info[result_var].has_range ||
|
||||
if (result_var < 0 ||
|
||||
!ssa->var_info[result_var].has_range ||
|
||||
ssa->var_info[result_var].range.underflow ||
|
||||
ssa->var_info[result_var].range.overflow) {
|
||||
/* may overflow */
|
||||
@@ -2627,7 +2641,8 @@ static int zend_update_type_info(const zend_op_array *op_array,
|
||||
}
|
||||
|
||||
tmp |= binary_op_result_type(
|
||||
ssa, opline->extended_value, t1, t2, ssa_ops[i].op1_def, optimization_level);
|
||||
ssa, opline->extended_value, t1, t2,
|
||||
opline->opcode == ZEND_ASSIGN_OP ? ssa_ops[i].op1_def : -1, optimization_level);
|
||||
if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY)) {
|
||||
tmp |= MAY_BE_RC1;
|
||||
}
|
||||
|
||||
@@ -774,14 +774,15 @@ static inline void kill_all_lockers(struct flock *mem_usage_check)
|
||||
/* so that other process won't try to force while we are busy cleaning up */
|
||||
ZCSG(force_restart_time) = 0;
|
||||
while (mem_usage_check->l_pid > 0) {
|
||||
/* Clear previous errno, reset success and tries */
|
||||
/* Try SIGTERM first, switch to SIGKILL if not successful. */
|
||||
int signal = SIGTERM;
|
||||
errno = 0;
|
||||
success = 0;
|
||||
tries = 10;
|
||||
|
||||
while (tries--) {
|
||||
zend_accel_error(ACCEL_LOG_WARNING, "Attempting to kill locker %d", mem_usage_check->l_pid);
|
||||
if (kill(mem_usage_check->l_pid, SIGKILL)) {
|
||||
if (kill(mem_usage_check->l_pid, signal)) {
|
||||
if (errno == ESRCH) {
|
||||
/* Process died before the signal was sent */
|
||||
success = 1;
|
||||
@@ -800,6 +801,8 @@ static inline void kill_all_lockers(struct flock *mem_usage_check)
|
||||
break;
|
||||
}
|
||||
usleep(10000);
|
||||
/* If SIGTERM was not sufficient, use SIGKILL. */
|
||||
signal = SIGKILL;
|
||||
}
|
||||
if (!success) {
|
||||
/* errno is not ESRCH or we ran out of tries to kill the locker */
|
||||
|
||||
@@ -80,7 +80,7 @@ void zend_shared_alloc_create_lock(void)
|
||||
{
|
||||
memory_mutex = CreateMutex(NULL, FALSE, create_name_with_username(ACCEL_MUTEX_NAME));
|
||||
if (!memory_mutex) {
|
||||
zend_accel_error(ACCEL_LOG_FATAL, "Cannot create mutex");
|
||||
zend_accel_error(ACCEL_LOG_FATAL, "Cannot create mutex (error %u)", GetLastError());
|
||||
return;
|
||||
}
|
||||
ReleaseMutex(memory_mutex);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #80805: create simple class and get error in opcache.so
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test {
|
||||
public int $foo;
|
||||
public function __construct()
|
||||
{
|
||||
$this->foo = 2;
|
||||
}
|
||||
public function inc(): int
|
||||
{
|
||||
return $this->foo += 2;
|
||||
}
|
||||
}
|
||||
|
||||
$test = new Test();
|
||||
var_dump($test->foo);
|
||||
$test->inc();
|
||||
var_dump($test->foo);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(2)
|
||||
int(4)
|
||||
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Incorrect DCE of FREE of COALESCE
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test(?string $str) {
|
||||
$str ?? $str = '';
|
||||
return strlen($str);
|
||||
}
|
||||
|
||||
$foo = 'foo';
|
||||
$foo .= 'bar';
|
||||
var_dump(test($foo));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(6)
|
||||
@@ -185,10 +185,12 @@ static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_PCRE_JIT_SUPPORT
|
||||
if (0 > pcre2_jit_compile(it->re, PCRE2_JIT_COMPLETE)) {
|
||||
/* Don't return here, even JIT could fail to compile, the pattern is still usable. */
|
||||
pcre2_get_error_message(errnumber, pcre_error, sizeof(pcre_error));
|
||||
zend_accel_error(ACCEL_LOG_WARNING, "Blacklist JIT compilation failed, %s\n", pcre_error);
|
||||
if (PCRE_G(jit)) {
|
||||
if (0 > pcre2_jit_compile(it->re, PCRE2_JIT_COMPLETE)) {
|
||||
/* Don't return here, even JIT could fail to compile, the pattern is still usable. */
|
||||
pcre2_get_error_message(errnumber, pcre_error, sizeof(pcre_error));
|
||||
zend_accel_error(ACCEL_LOG_WARNING, "Blacklist JIT compilation failed, %s\n", pcre_error);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* prepare for the next iteration */
|
||||
|
||||
+26
-26
@@ -1064,6 +1064,17 @@ static inline int php_openssl_config_check_syntax(const char * section_label, co
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static char *php_openssl_conf_get_string(
|
||||
LHASH_OF(CONF_VALUE) *conf, const char *group, const char *name) {
|
||||
char *str = CONF_get_string(conf, group, name);
|
||||
if (str == NULL) {
|
||||
/* OpenSSL reports an error if a configuration value is not found.
|
||||
* However, we don't want to generate errors for optional configuration. */
|
||||
ERR_clear_error();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static int php_openssl_add_oid_section(struct php_x509_request * req) /* {{{ */
|
||||
{
|
||||
char * str;
|
||||
@@ -1071,9 +1082,8 @@ static int php_openssl_add_oid_section(struct php_x509_request * req) /* {{{ */
|
||||
CONF_VALUE * cnf;
|
||||
int i;
|
||||
|
||||
str = CONF_get_string(req->req_config, NULL, "oid_section");
|
||||
str = php_openssl_conf_get_string(req->req_config, NULL, "oid_section");
|
||||
if (str == NULL) {
|
||||
php_openssl_store_errors();
|
||||
return SUCCESS;
|
||||
}
|
||||
sktmp = CONF_get_section(req->req_config, str);
|
||||
@@ -1158,10 +1168,8 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
|
||||
}
|
||||
|
||||
/* read in the oids */
|
||||
str = CONF_get_string(req->req_config, NULL, "oid_file");
|
||||
if (str == NULL) {
|
||||
php_openssl_store_errors();
|
||||
} else if (!php_openssl_open_base_dir_chk(str)) {
|
||||
str = php_openssl_conf_get_string(req->req_config, NULL, "oid_file");
|
||||
if (str != NULL && !php_openssl_open_base_dir_chk(str)) {
|
||||
BIO *oid_bio = BIO_new_file(str, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
|
||||
if (oid_bio) {
|
||||
OBJ_create_objects(oid_bio);
|
||||
@@ -1173,11 +1181,11 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
|
||||
return FAILURE;
|
||||
}
|
||||
SET_OPTIONAL_STRING_ARG("digest_alg", req->digest_name,
|
||||
CONF_get_string(req->req_config, req->section_name, "default_md"));
|
||||
php_openssl_conf_get_string(req->req_config, req->section_name, "default_md"));
|
||||
SET_OPTIONAL_STRING_ARG("x509_extensions", req->extensions_section,
|
||||
CONF_get_string(req->req_config, req->section_name, "x509_extensions"));
|
||||
php_openssl_conf_get_string(req->req_config, req->section_name, "x509_extensions"));
|
||||
SET_OPTIONAL_STRING_ARG("req_extensions", req->request_extensions_section,
|
||||
CONF_get_string(req->req_config, req->section_name, "req_extensions"));
|
||||
php_openssl_conf_get_string(req->req_config, req->section_name, "req_extensions"));
|
||||
SET_OPTIONAL_LONG_ARG("private_key_bits", req->priv_key_bits,
|
||||
CONF_get_number(req->req_config, req->section_name, "default_bits"));
|
||||
|
||||
@@ -1186,11 +1194,9 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
|
||||
if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), "encrypt_key", sizeof("encrypt_key")-1)) != NULL) {
|
||||
req->priv_key_encrypt = Z_TYPE_P(item) == IS_TRUE ? 1 : 0;
|
||||
} else {
|
||||
str = CONF_get_string(req->req_config, req->section_name, "encrypt_rsa_key");
|
||||
str = php_openssl_conf_get_string(req->req_config, req->section_name, "encrypt_rsa_key");
|
||||
if (str == NULL) {
|
||||
str = CONF_get_string(req->req_config, req->section_name, "encrypt_key");
|
||||
/* it is sure that there are some errrors as str was NULL for encrypt_rsa_key */
|
||||
php_openssl_store_errors();
|
||||
str = php_openssl_conf_get_string(req->req_config, req->section_name, "encrypt_key");
|
||||
}
|
||||
if (str != NULL && strcmp(str, "no") == 0) {
|
||||
req->priv_key_encrypt = 0;
|
||||
@@ -1218,12 +1224,10 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
|
||||
|
||||
/* digest alg */
|
||||
if (req->digest_name == NULL) {
|
||||
req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
|
||||
req->digest_name = php_openssl_conf_get_string(req->req_config, req->section_name, "default_md");
|
||||
}
|
||||
if (req->digest_name != NULL) {
|
||||
req->digest = req->md_alg = EVP_get_digestbyname(req->digest_name);
|
||||
} else {
|
||||
php_openssl_store_errors();
|
||||
}
|
||||
if (req->md_alg == NULL) {
|
||||
req->md_alg = req->digest = EVP_sha1();
|
||||
@@ -1245,10 +1249,8 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
|
||||
#endif
|
||||
|
||||
/* set the string mask */
|
||||
str = CONF_get_string(req->req_config, req->section_name, "string_mask");
|
||||
if (str == NULL) {
|
||||
php_openssl_store_errors();
|
||||
} else if (!ASN1_STRING_set_default_mask_asc(str)) {
|
||||
str = php_openssl_conf_get_string(req->req_config, req->section_name, "string_mask");
|
||||
if (str != NULL && !ASN1_STRING_set_default_mask_asc(str)) {
|
||||
php_error_docref(NULL, E_WARNING, "Invalid global string mask setting %s", str);
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -3138,9 +3140,8 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
|
||||
php_openssl_store_errors();
|
||||
return FAILURE;
|
||||
}
|
||||
attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
|
||||
attr_sect = php_openssl_conf_get_string(req->req_config, req->section_name, "attributes");
|
||||
if (attr_sect == NULL) {
|
||||
php_openssl_store_errors();
|
||||
attr_sk = NULL;
|
||||
} else {
|
||||
attr_sk = CONF_get_section(req->req_config, attr_sect);
|
||||
@@ -3994,10 +3995,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
|
||||
return NULL;
|
||||
}
|
||||
|
||||
randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
|
||||
if (randfile == NULL) {
|
||||
php_openssl_store_errors();
|
||||
}
|
||||
randfile = php_openssl_conf_get_string(req->req_config, req->section_name, "RANDFILE");
|
||||
php_openssl_load_rand_file(randfile, &egdsocket, &seeded);
|
||||
|
||||
if ((req->priv_key = EVP_PKEY_new()) != NULL) {
|
||||
@@ -4021,6 +4019,8 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
|
||||
PHP_OPENSSL_RAND_ADD_TIME();
|
||||
if (rsaparam == NULL || !RSA_generate_key_ex(rsaparam, req->priv_key_bits, bne, NULL)) {
|
||||
php_openssl_store_errors();
|
||||
RSA_free(rsaparam);
|
||||
rsaparam = NULL;
|
||||
}
|
||||
BN_free(bne);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,51 @@ Bug #62890 (default_socket_timeout=-1 causes connection to timeout)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('openssl')) die('skip openssl extension not available');
|
||||
if (getenv('SKIP_ONLINE_TESTS')) die('skip online test');
|
||||
if (!function_exists("proc_open")) die("skip no proc_open");
|
||||
?>
|
||||
--INI--
|
||||
default_socket_timeout=-1
|
||||
--FILE--
|
||||
<?php
|
||||
$clientCtx = stream_context_create(['ssl' => ['verify_peer' => false]]);
|
||||
var_dump((bool) file_get_contents('https://www.php.net', false, $clientCtx));
|
||||
$certFile = __DIR__ . DIRECTORY_SEPARATOR . 'bug62890.pem.tmp';
|
||||
|
||||
$serverCode = <<<'CODE'
|
||||
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
|
||||
$ctx = stream_context_create(['ssl' => [
|
||||
'local_cert' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
$server = stream_socket_server('tls://127.0.0.1:64321', $errno, $errstr, $flags, $ctx);
|
||||
phpt_notify();
|
||||
@stream_socket_accept($server, 3);
|
||||
CODE;
|
||||
$serverCode = sprintf($serverCode, $certFile);
|
||||
|
||||
$clientCode = <<<'CODE'
|
||||
$flags = STREAM_CLIENT_CONNECT;
|
||||
$ctx = stream_context_create(['ssl' => [
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
phpt_wait();
|
||||
|
||||
$client = stream_socket_client("tls://127.0.0.1:64321", $errno, $errstr, 3, $flags, $ctx);
|
||||
var_dump($client);
|
||||
CODE;
|
||||
|
||||
include 'CertificateGenerator.inc';
|
||||
$certificateGenerator = new CertificateGenerator();
|
||||
$certificateGenerator->saveNewCertAsFileWithKey('bug62890', $certFile);
|
||||
|
||||
include 'ServerClientTestCase.inc';
|
||||
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug62890.pem.tmp');
|
||||
?>
|
||||
--EXPECTF--
|
||||
resource(%d) of type (stream)
|
||||
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
Bug #80747: Providing RSA key size < 512 generates key that crash PHP
|
||||
--FILE--
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip openssl not loaded");
|
||||
if (OPENSSL_VERSION_NUMBER < 0x10100000) die("skip OpenSSL >= v1.1.0 required");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$conf = array(
|
||||
'config' => __DIR__ . DIRECTORY_SEPARATOR . 'openssl.cnf',
|
||||
'private_key_bits' => 511,
|
||||
);
|
||||
var_dump(openssl_pkey_new($conf));
|
||||
while ($e = openssl_error_string()) {
|
||||
echo $e, "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
error:%s:key size too small
|
||||
@@ -14,7 +14,8 @@ $serverCode = <<<'CODE'
|
||||
$serverUri = "ssl://127.0.0.1:64321";
|
||||
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
|
||||
$serverCtx = stream_context_create(['ssl' => [
|
||||
'local_cert' => '%s'
|
||||
'local_cert' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
|
||||
@@ -36,6 +37,7 @@ $clientCode = <<<'CODE'
|
||||
'cafile' => '%s',
|
||||
'peer_name' => '%s',
|
||||
'capture_session_meta' => true,
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
phpt_wait();
|
||||
|
||||
@@ -14,7 +14,8 @@ $serverCode = <<<'CODE'
|
||||
$serverUri = "ssl://127.0.0.1:64321";
|
||||
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
|
||||
$serverCtx = stream_context_create(['ssl' => [
|
||||
'local_cert' => '%s'
|
||||
'local_cert' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
|
||||
@@ -34,6 +35,7 @@ $clientCode = <<<'CODE'
|
||||
'verify_peer' => true,
|
||||
'cafile' => '%s',
|
||||
'peer_name' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
phpt_wait();
|
||||
|
||||
@@ -14,7 +14,8 @@ $serverCode = <<<'CODE'
|
||||
$serverUri = "ssl://127.0.0.1:64321";
|
||||
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
|
||||
$serverCtx = stream_context_create(['ssl' => [
|
||||
'local_cert' => '%s'
|
||||
'local_cert' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
|
||||
@@ -35,6 +36,7 @@ $clientCode = <<<'CODE'
|
||||
'verify_peer' => true,
|
||||
'cafile' => '%s',
|
||||
'peer_name' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
phpt_wait();
|
||||
|
||||
@@ -17,8 +17,9 @@ $serverCode = <<<'CODE'
|
||||
$serverCtx = stream_context_create(['ssl' => [
|
||||
'local_cert' => '%s',
|
||||
|
||||
// Only accept TLSv1.2 connections
|
||||
// Only accept TLSv1.0 and TLSv1.2 connections
|
||||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_SERVER | STREAM_CRYPTO_METHOD_TLSv1_2_SERVER,
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
|
||||
@@ -39,6 +40,7 @@ $clientCode = <<<'CODE'
|
||||
'verify_peer' => true,
|
||||
'cafile' => '%s',
|
||||
'peer_name' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
phpt_wait();
|
||||
|
||||
@@ -16,6 +16,7 @@ $serverCode = <<<'CODE'
|
||||
$serverCtx = stream_context_create(['ssl' => [
|
||||
'local_cert' => '%s',
|
||||
'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_0_SERVER,
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
|
||||
@@ -36,6 +37,7 @@ $clientCode = <<<'CODE'
|
||||
'verify_peer' => true,
|
||||
'cafile' => '%s',
|
||||
'peer_name' => '%s',
|
||||
'security_level' => 1,
|
||||
]]);
|
||||
|
||||
phpt_wait();
|
||||
|
||||
+3
-2
@@ -955,7 +955,7 @@ PHP_FUNCTION(pcntl_exec)
|
||||
int envc = 0, envi = 0;
|
||||
char **argv = NULL, **envp = NULL;
|
||||
char **current_arg, **pair;
|
||||
int pair_length;
|
||||
size_t pair_length;
|
||||
zend_string *key;
|
||||
char *path;
|
||||
size_t path_len;
|
||||
@@ -1015,8 +1015,9 @@ PHP_FUNCTION(pcntl_exec)
|
||||
}
|
||||
|
||||
/* Length of element + equal sign + length of key + null */
|
||||
ZEND_ASSERT(Z_STRLEN_P(element) < SIZE_MAX && ZSTR_LEN(key) < SIZE_MAX);
|
||||
*pair = safe_emalloc(Z_STRLEN_P(element) + 1, sizeof(char), ZSTR_LEN(key) + 1);
|
||||
pair_length = Z_STRLEN_P(element) + ZSTR_LEN(key) + 2;
|
||||
*pair = emalloc(pair_length);
|
||||
strlcpy(*pair, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
|
||||
strlcat(*pair, "=", pair_length);
|
||||
strlcat(*pair, Z_STRVAL_P(element), pair_length);
|
||||
|
||||
@@ -9,6 +9,9 @@ pcntl: SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// Clear mask
|
||||
pcntl_sigprocmask(SIG_SETMASK, array(), $prev);
|
||||
|
||||
pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD,SIGTERM), $old);
|
||||
var_dump(count($old));
|
||||
pcntl_sigprocmask(SIG_BLOCK, array(SIGINT), $old);
|
||||
@@ -19,7 +22,9 @@ pcntl_sigprocmask(SIG_SETMASK, array(SIGINT), $old);
|
||||
var_dump(count($old));
|
||||
pcntl_sigprocmask(SIG_SETMASK, array(), $old);
|
||||
var_dump(count($old));
|
||||
pcntl_sigprocmask(SIG_SETMASK, array(), $old);
|
||||
|
||||
// Restore previous mask
|
||||
pcntl_sigprocmask(SIG_SETMASK, $prev, $old);
|
||||
var_dump(count($old));
|
||||
|
||||
?>
|
||||
|
||||
+5
-1
@@ -767,8 +767,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
|
||||
zend_hash_add_ptr(&char_tables, _k, (void *)tables);
|
||||
zend_string_release(_k);
|
||||
}
|
||||
pcre2_set_character_tables(cctx, tables);
|
||||
}
|
||||
pcre2_set_character_tables(cctx, tables);
|
||||
|
||||
/* Set extra options for the compile context. */
|
||||
if (PHP_PCRE_DEFAULT_EXTRA_COPTIONS != extra_coptions) {
|
||||
@@ -2644,6 +2644,10 @@ matched:
|
||||
the match again at the same point. If this fails (picked up above) we
|
||||
advance to the next character. */
|
||||
if (start_offset == offsets[0]) {
|
||||
/* Get next piece if no limit or limit not yet reached and something matched*/
|
||||
if (limit_val != -1 && limit_val <= 1) {
|
||||
break;
|
||||
}
|
||||
count = pcre2_match(pce->re, (PCRE2_SPTR)subject, ZSTR_LEN(subject_str), start_offset,
|
||||
PCRE2_NO_UTF_CHECK | PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED, match_data, mctx);
|
||||
if (count >= 0) {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #80866 preg_split ignores limit flag when pattern with \K has 0-width fullstring match
|
||||
--FILE--
|
||||
<?php
|
||||
var_export(preg_split('~.{3}\K~', 'abcdefghijklm', 3));
|
||||
?>
|
||||
--EXPECT--
|
||||
array (
|
||||
0 => 'abc',
|
||||
1 => 'def',
|
||||
2 => 'ghijklm',
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Changing LC_CTYPE back to C
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!setlocale(LC_CTYPE, "de_DE", "de-DE")) die("skip requires de_DE locale");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(setlocale(LC_CTYPE, "de_DE", "de-DE") !== false);
|
||||
var_dump(preg_match('/\w/', "\xe4"));
|
||||
var_dump(setlocale(LC_CTYPE, "C") !== false);
|
||||
var_dump(preg_match('/\w/', "\xe4"));
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
int(1)
|
||||
bool(true)
|
||||
int(0)
|
||||
@@ -652,6 +652,7 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong
|
||||
|
||||
/* if it is a column containing "long" data, perform late binding now */
|
||||
if (C->is_long) {
|
||||
SQLLEN orig_fetched_len = SQL_NULL_DATA;
|
||||
zend_ulong used = 0;
|
||||
char *buf;
|
||||
RETCODE rc;
|
||||
@@ -662,18 +663,20 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong
|
||||
|
||||
rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, C->data,
|
||||
256, &C->fetched_len);
|
||||
orig_fetched_len = C->fetched_len;
|
||||
|
||||
if (rc == SQL_SUCCESS) {
|
||||
if (rc == SQL_SUCCESS && C->fetched_len < 256) {
|
||||
/* all the data fit into our little buffer;
|
||||
* jump down to the generic bound data case */
|
||||
goto in_data;
|
||||
}
|
||||
|
||||
if (rc == SQL_SUCCESS_WITH_INFO) {
|
||||
if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS) {
|
||||
/* this is a 'long column'
|
||||
|
||||
read the column in 255 byte blocks until the end of the column is reached, reassembling those blocks
|
||||
in order into the output buffer
|
||||
in order into the output buffer; 255 bytes are an optimistic assumption, since the driver may assert
|
||||
more or less NUL bytes at the end; we cater to that later, if actual length information is available
|
||||
|
||||
this loop has to work whether or not SQLGetData() provides the total column length.
|
||||
calling SQLDescribeCol() or other, specifically to get the column length, then doing a single read
|
||||
@@ -687,10 +690,17 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong
|
||||
do {
|
||||
C->fetched_len = 0;
|
||||
/* read block. 256 bytes => 255 bytes are actually read, the last 1 is NULL */
|
||||
rc = SQLGetData(S->stmt, colno+1, SQL_C_CHAR, buf2, 256, &C->fetched_len);
|
||||
rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, buf2, 256, &C->fetched_len);
|
||||
|
||||
/* adjust `used` in case we have length info from the driver */
|
||||
if (orig_fetched_len >= 0 && C->fetched_len >= 0) {
|
||||
SQLLEN fixed_used = orig_fetched_len - C->fetched_len;
|
||||
ZEND_ASSERT(fixed_used <= used + 1);
|
||||
used = fixed_used;
|
||||
}
|
||||
|
||||
/* resize output buffer and reassemble block */
|
||||
if (rc==SQL_SUCCESS_WITH_INFO) {
|
||||
if (rc==SQL_SUCCESS_WITH_INFO || (rc==SQL_SUCCESS && C->fetched_len > 255)) {
|
||||
/* point 5, in section "Retrieving Data with SQLGetData" in http://msdn.microsoft.com/en-us/library/windows/desktop/ms715441(v=vs.85).aspx
|
||||
states that if SQL_SUCCESS_WITH_INFO, fetched_len will be > 255 (greater than buf2's size)
|
||||
(if a driver fails to follow that and wrote less than 255 bytes to buf2, this will AV or read garbage into buf) */
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
Bug #80783 (PDO ODBC truncates BLOB records at every 256th byte)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_odbc')) die('skip pdo_odbc extension not available');
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->exec("CREATE TABLE bug80783 (name IMAGE)");
|
||||
|
||||
$string = str_repeat("0123456789", 50);
|
||||
$db->exec("INSERT INTO bug80783 VALUES('$string')");
|
||||
|
||||
$stmt = $db->prepare("SELECT name FROM bug80783");
|
||||
$stmt->bindColumn(1, $data, PDO::PARAM_LOB);
|
||||
$stmt->execute();
|
||||
$stmt->fetch(PDO::FETCH_BOUND);
|
||||
|
||||
var_dump($data === bin2hex($string));
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->exec("DROP TABLE bug80783");
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Bug #80783 (PDO ODBC truncates BLOB records at every 256th byte)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo_odbc')) die('skip pdo_odbc extension not available');
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->exec("CREATE TABLE bug80783a (name NVARCHAR(MAX))");
|
||||
|
||||
$string = str_repeat("0123456789", 50);
|
||||
$db->exec("INSERT INTO bug80783a VALUES('$string')");
|
||||
|
||||
$stmt = $db->prepare("SELECT name FROM bug80783a");
|
||||
$stmt->setAttribute(PDO::ODBC_ATTR_ASSUME_UTF8, true);
|
||||
$stmt->bindColumn(1, $data, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$stmt->fetch(PDO::FETCH_BOUND);
|
||||
|
||||
var_dump($data === $string);
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
require 'ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->exec("DROP TABLE bug80783a");
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -54,6 +54,19 @@
|
||||
#define VARCHARLABEL "varchar"
|
||||
#define VARCHAROID 1043
|
||||
|
||||
#define PG_INT32_MIN (-0x7FFFFFFF-1)
|
||||
#define PG_INT32_MAX (0x7FFFFFFF)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define strtoll(s, f, b) _atoi64(s)
|
||||
#elif !defined(HAVE_STRTOLL)
|
||||
# if defined(HAVE_ATOLL)
|
||||
# define strtoll(s, f, b) atoll(s)
|
||||
# else
|
||||
# define strtoll(s, f, b) strtol(s, f, b)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static int pgsql_stmt_dtor(pdo_stmt_t *stmt)
|
||||
@@ -390,7 +403,16 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
|
||||
S->param_formats[param->paramno] = 0;
|
||||
}
|
||||
|
||||
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
|
||||
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT) {
|
||||
/* we need to check if the number requires bigints */
|
||||
long long val = strtoll(Z_STRVAL_P(parameter), NULL, 10);
|
||||
|
||||
if (val > PG_INT32_MAX || val < PG_INT32_MIN) {
|
||||
S->param_types[param->paramno] = INT8OID;
|
||||
} else {
|
||||
S->param_types[param->paramno] = INT4OID;
|
||||
}
|
||||
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
|
||||
S->param_types[param->paramno] = 0;
|
||||
S->param_formats[param->paramno] = 1;
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
--TEST--
|
||||
Bug #80892 PDO::PARAM_INT is treated the same as PDO::PARAM_STR
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||
require __DIR__ . '/config.inc';
|
||||
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require __DIR__ . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
|
||||
/** @var PDO $db */
|
||||
$db = PDOTest::test_factory(__DIR__ . '/common.phpt');
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
|
||||
$db->exec("CREATE OR REPLACE FUNCTION bug80892 (x bigint) RETURNS varchar AS $$ SELECT 'bigint' $$ LANGUAGE sql");
|
||||
$db->exec("CREATE OR REPLACE FUNCTION bug80892 (x int) RETURNS varchar AS $$ SELECT 'int' $$ LANGUAGE sql");
|
||||
$db->exec("CREATE OR REPLACE FUNCTION bug80892 (x text) RETURNS varchar AS $$ SELECT 'text' $$ LANGUAGE sql");
|
||||
|
||||
// Sanity check
|
||||
var_dump($db->query("SELECT bug80892(2147483648)")->fetchColumn());
|
||||
var_dump($db->query("SELECT bug80892(1)")->fetchColumn());
|
||||
var_dump($db->query("SELECT bug80892('1')")->fetchColumn());
|
||||
|
||||
// No binding
|
||||
$stmt = $db->prepare("SELECT bug80892(?)");
|
||||
$stmt->execute([1]);
|
||||
var_dump($stmt->fetchColumn());
|
||||
|
||||
// Bind int value as string
|
||||
$stmt = $db->prepare("SELECT bug80892(?)");
|
||||
$stmt->bindValue(1, 1, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchColumn());
|
||||
|
||||
// Bind int value as int
|
||||
$stmt = $db->prepare("SELECT bug80892(?)");
|
||||
$stmt->bindValue(1, 1, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchColumn());
|
||||
|
||||
// Bind string value as int
|
||||
$stmt = $db->prepare("SELECT bug80892(?)");
|
||||
$stmt->bindValue(1, '1', PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchColumn());
|
||||
|
||||
// Bind bigint string value as int
|
||||
$stmt = $db->prepare("SELECT bug80892(?)");
|
||||
$stmt->bindValue(1, '2147483648', PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchColumn());
|
||||
|
||||
// Bind negative bigint (string on 32bit) as int
|
||||
$stmt = $db->prepare("SELECT bug80892(?)");
|
||||
$stmt->bindValue(1, PHP_INT_SIZE == 4 ? '-33333333333' : -33333333333, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
var_dump($stmt->fetchColumn());
|
||||
|
||||
$db->exec("DROP FUNCTION bug80892 (bigint)");
|
||||
$db->exec("DROP FUNCTION bug80892 (int)");
|
||||
$db->exec("DROP FUNCTION bug80892 (text)");
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(6) "bigint"
|
||||
string(3) "int"
|
||||
string(4) "text"
|
||||
string(4) "text"
|
||||
string(4) "text"
|
||||
string(3) "int"
|
||||
string(3) "int"
|
||||
string(6) "bigint"
|
||||
string(6) "bigint"
|
||||
+9
-6
@@ -1424,9 +1424,10 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||
}
|
||||
pgsql = (PGconn *) le->ptr;
|
||||
#if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
|
||||
if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 7.2) {
|
||||
/* consider to use php_version_compare() here */
|
||||
if (PQprotocolVersion(pgsql) >= 3 && zend_strtod(PQparameterStatus(pgsql, "server_version"), NULL) >= 7.2) {
|
||||
#else
|
||||
if (atof(PG_VERSION) >= 7.2) {
|
||||
if (zend_strtod(PG_VERSION, NULL) >= 7.2) {
|
||||
#endif
|
||||
pg_result = PQexec(pgsql, "RESET ALL;");
|
||||
PQclear(pg_result);
|
||||
@@ -5326,9 +5327,10 @@ PHP_FUNCTION(pg_get_notify)
|
||||
add_index_string(return_value, 0, pgsql_notify->relname);
|
||||
add_index_long(return_value, 1, pgsql_notify->be_pid);
|
||||
#if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
|
||||
if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 9.0) {
|
||||
/* consider to use php_version_compare() here */
|
||||
if (PQprotocolVersion(pgsql) >= 3 && zend_strtod(PQparameterStatus(pgsql, "server_version"), NULL) >= 9.0) {
|
||||
#else
|
||||
if (atof(PG_VERSION) >= 9.0) {
|
||||
if (zend_strtod(PG_VERSION) >= 9.0, NULL) {
|
||||
#endif
|
||||
#if HAVE_PQPARAMETERSTATUS
|
||||
add_index_string(return_value, 2, pgsql_notify->extra);
|
||||
@@ -5339,9 +5341,10 @@ PHP_FUNCTION(pg_get_notify)
|
||||
add_assoc_string(return_value, "message", pgsql_notify->relname);
|
||||
add_assoc_long(return_value, "pid", pgsql_notify->be_pid);
|
||||
#if HAVE_PQPROTOCOLVERSION && HAVE_PQPARAMETERSTATUS
|
||||
if (PQprotocolVersion(pgsql) >= 3 && atof(PQparameterStatus(pgsql, "server_version")) >= 9.0) {
|
||||
/* consider to use php_version_compare() here */
|
||||
if (PQprotocolVersion(pgsql) >= 3 && zend_strtod(PQparameterStatus(pgsql, "server_version"), NULL) >= 9.0) {
|
||||
#else
|
||||
if (atof(PG_VERSION) >= 9.0) {
|
||||
if (zend_strtod(PG_VERSION, NULL) >= 9.0) {
|
||||
#endif
|
||||
#if HAVE_PQPARAMETERSTATUS
|
||||
add_assoc_string(return_value, "payload", pgsql_notify->extra);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
.TH PHAR 1 "2019" "The PHP Group" "User Commands"
|
||||
.TH PHAR 1 "2021" "The PHP Group" "User Commands"
|
||||
.SH NAME
|
||||
phar, phar.phar \- PHAR (PHP archive) command line tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
+42
-18
@@ -2508,6 +2508,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
smart_str main_metadata_str = {0};
|
||||
int free_user_stub, free_fp = 1, free_ufp = 1;
|
||||
int manifest_hack = 0;
|
||||
php_stream *shared_cfp = NULL;
|
||||
|
||||
if (phar->is_persistent) {
|
||||
if (error) {
|
||||
@@ -2602,7 +2603,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
if (error) {
|
||||
spprintf(error, 0, "illegal stub for phar \"%s\"", phar->fname);
|
||||
spprintf(error, 0, "illegal stub for phar \"%s\" (__HALT_COMPILER(); is missing)", phar->fname);
|
||||
}
|
||||
if (free_user_stub) {
|
||||
zend_string_free(suser_stub);
|
||||
@@ -2788,10 +2789,13 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* create new file that holds the compressed version */
|
||||
/* create new file that holds the compressed versions */
|
||||
/* work around inability to specify freedom in write and strictness
|
||||
in read count */
|
||||
entry->cfp = php_stream_fopen_tmpfile();
|
||||
if (shared_cfp == NULL) {
|
||||
shared_cfp = php_stream_fopen_tmpfile();
|
||||
}
|
||||
entry->cfp = shared_cfp;
|
||||
if (!entry->cfp) {
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to create temporary file");
|
||||
@@ -2800,8 +2804,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
/* for real phars, header_offset is unused; we misuse it here to store the offset in the temp file */
|
||||
ZEND_ASSERT(entry->header_offset == 0);
|
||||
entry->header_offset = php_stream_tell(entry->cfp);
|
||||
php_stream_flush(file);
|
||||
if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) {
|
||||
if (closeoldfile) {
|
||||
@@ -2811,7 +2818,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
php_stream_filter_append((&entry->cfp->writefilters), filter);
|
||||
if (SUCCESS != php_stream_copy_to_stream_ex(file, entry->cfp, entry->uncompressed_filesize, NULL)) {
|
||||
@@ -2822,15 +2829,14 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"", entry->filename, phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
php_stream_filter_flush(filter, 1);
|
||||
php_stream_flush(entry->cfp);
|
||||
php_stream_filter_remove(filter, 1);
|
||||
php_stream_seek(entry->cfp, 0, SEEK_END);
|
||||
entry->compressed_filesize = (uint32_t) php_stream_tell(entry->cfp);
|
||||
entry->compressed_filesize = ((uint32_t) php_stream_tell(entry->cfp)) - entry->header_offset;
|
||||
/* generate crc on compressed file */
|
||||
php_stream_rewind(entry->cfp);
|
||||
entry->old_flags = entry->flags;
|
||||
entry->is_modified = 1;
|
||||
global_flags |= (entry->flags & PHAR_ENT_COMPRESSION_MASK);
|
||||
@@ -2886,7 +2892,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
spprintf(error, 0, "unable to write manifest header of new phar \"%s\"", phar->fname);
|
||||
}
|
||||
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
phar->alias_len = restore_alias_len;
|
||||
@@ -2907,7 +2913,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
spprintf(error, 0, "unable to write manifest meta-data of new phar \"%s\"", phar->fname);
|
||||
}
|
||||
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
smart_str_free(&main_metadata_str);
|
||||
|
||||
@@ -2942,7 +2948,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
spprintf(error, 0, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", entry->filename, phar->fname);
|
||||
}
|
||||
}
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* set the manifest meta-data:
|
||||
@@ -2975,7 +2981,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
spprintf(error, 0, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", entry->filename, phar->fname);
|
||||
}
|
||||
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
/* Hack - see bug #65028, add padding byte to the end of the manifest */
|
||||
@@ -2991,7 +2997,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
spprintf(error, 0, "unable to write manifest padding byte");
|
||||
}
|
||||
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3004,7 +3010,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
|
||||
if (entry->cfp) {
|
||||
file = entry->cfp;
|
||||
php_stream_rewind(file);
|
||||
php_stream_seek(file, entry->header_offset, SEEK_SET);
|
||||
} else {
|
||||
file = phar_get_efp(entry, 0);
|
||||
if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 0)) {
|
||||
@@ -3015,7 +3021,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3027,7 +3033,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, phar->fname);
|
||||
}
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* this will have changed for all files that have either changed compression or been modified */
|
||||
@@ -3044,14 +3050,14 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
spprintf(error, 0, "unable to write contents of file \"%s\" to new phar \"%s\"", entry->filename, phar->fname);
|
||||
}
|
||||
|
||||
return EOF;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
entry->is_modified = 0;
|
||||
|
||||
if (entry->cfp) {
|
||||
php_stream_close(entry->cfp);
|
||||
entry->cfp = NULL;
|
||||
entry->header_offset = 0;
|
||||
}
|
||||
|
||||
if (entry->fp_type == PHAR_MOD) {
|
||||
@@ -3067,6 +3073,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (shared_cfp != NULL) {
|
||||
php_stream_close(shared_cfp);
|
||||
shared_cfp = NULL;
|
||||
}
|
||||
|
||||
/* append signature */
|
||||
if (global_flags & PHAR_HDR_SIGNATURE) {
|
||||
char sig_buf[4];
|
||||
@@ -3196,6 +3207,19 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return EOF;
|
||||
|
||||
cleanup:
|
||||
if (shared_cfp != NULL) {
|
||||
php_stream_close(shared_cfp);
|
||||
}
|
||||
ZEND_HASH_FOREACH_PTR(&phar->manifest, entry) {
|
||||
if (entry->cfp) {
|
||||
entry->cfp = NULL;
|
||||
entry->header_offset = 0;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
return EOF;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -3,6 +3,7 @@ Bug #69279 (Compressed ZIP Phar extractTo() creates garbage files)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('phar')) die('skip phar extension not available');
|
||||
if (!extension_loaded('zlib')) die('skip zlib extension not available');
|
||||
?>
|
||||
--INI--
|
||||
phar.readonly=0
|
||||
|
||||
@@ -3,6 +3,7 @@ Bug #69279 (Compressed ZIP Phar extractTo() creates garbage files)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('phar')) die('skip phar extension not available');
|
||||
if (!extension_loaded('zlib')) die('skip zlib extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
--TEST--
|
||||
Bug #70091 (Phar does not mark UTF-8 filenames in ZIP archives)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('phar')) die('skip phar extension not available');
|
||||
if (!extension_loaded('zlib')) die('skip zlib extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$phar = new PharData(__DIR__ . '/bug70091.zip');
|
||||
$phar->addFromString('föö', '');
|
||||
$phar->addFromString('foo', '');
|
||||
unset($phar);
|
||||
|
||||
$stream = fopen(__DIR__ . '/bug70091.zip', 'r');
|
||||
|
||||
$data = fread($stream, 8);
|
||||
var_dump(unpack('H8sig/@6/nflags', $data));
|
||||
|
||||
fseek($stream, 53);
|
||||
$data = fread($stream, 8);
|
||||
var_dump(unpack('H8sig/@6/nflags', $data));
|
||||
|
||||
fseek($stream, 104);
|
||||
$data = fread($stream, 10);
|
||||
var_dump(unpack('H8sig/@8/nflags', $data));
|
||||
|
||||
fseek($stream, 173);
|
||||
$data = fread($stream, 10);
|
||||
var_dump(unpack('H8sig/@8/nflags', $data));
|
||||
?>
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
["sig"]=>
|
||||
string(8) "504b0304"
|
||||
["flags"]=>
|
||||
int(8)
|
||||
}
|
||||
array(2) {
|
||||
["sig"]=>
|
||||
string(8) "504b0304"
|
||||
["flags"]=>
|
||||
int(8)
|
||||
}
|
||||
array(2) {
|
||||
["sig"]=>
|
||||
string(8) "504b0102"
|
||||
["flags"]=>
|
||||
int(8)
|
||||
}
|
||||
array(2) {
|
||||
["sig"]=>
|
||||
string(8) "504b0102"
|
||||
["flags"]=>
|
||||
int(8)
|
||||
}
|
||||
--CLEAN--
|
||||
<?php
|
||||
@unlink(__DIR__ . '/bug70091.zip');
|
||||
?>
|
||||
@@ -3,6 +3,7 @@ Bug #79912 (Phar::decompressFiles not working)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('phar')) die('skip phar extension is not available');
|
||||
if (!extension_loaded('zlib')) die('skip zlib extension not available');
|
||||
?>
|
||||
--INI--
|
||||
phar.readonly=0
|
||||
|
||||
@@ -48,7 +48,7 @@ __HALT_COMPILER();
|
||||
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
|
||||
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
|
||||
bool(true)
|
||||
Exception: illegal stub for phar "%sphar_stub_error.phar.php"
|
||||
Exception: illegal stub for phar "%sphar_stub_error.phar.php" (__HALT_COMPILER(); is missing)
|
||||
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
|
||||
bool(true)
|
||||
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
|
||||
|
||||
@@ -829,6 +829,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
|
||||
zend_off_t offset;
|
||||
int not_really_modified = 0;
|
||||
p = (struct _phar_zip_pass*) arg;
|
||||
uint16_t general_purpose_flags;
|
||||
|
||||
if (entry->is_mounted) {
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
@@ -878,6 +879,11 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
|
||||
memcpy(central.datestamp, local.datestamp, sizeof(local.datestamp));
|
||||
PHAR_SET_16(central.filename_len, entry->filename_len + (entry->is_dir ? 1 : 0));
|
||||
PHAR_SET_16(local.filename_len, entry->filename_len + (entry->is_dir ? 1 : 0));
|
||||
// set language encoding flag (all filenames have to be UTF-8 anyway)
|
||||
general_purpose_flags = PHAR_GET_16(central.flags);
|
||||
PHAR_SET_16(central.flags, general_purpose_flags | (1 << 11));
|
||||
general_purpose_flags = PHAR_GET_16(local.flags);
|
||||
PHAR_SET_16(local.flags, general_purpose_flags | (1 << 11));
|
||||
PHAR_SET_32(central.offset, php_stream_tell(p->filefp));
|
||||
|
||||
/* do extra field for perms later */
|
||||
|
||||
+12
-2
@@ -563,22 +563,32 @@ PHP_FUNCTION(posix_setegid)
|
||||
#ifdef HAVE_GETGROUPS
|
||||
PHP_FUNCTION(posix_getgroups)
|
||||
{
|
||||
gid_t gidlist[NGROUPS_MAX];
|
||||
gid_t *gidlist;
|
||||
int result;
|
||||
int i;
|
||||
|
||||
PHP_POSIX_NO_ARGS;
|
||||
|
||||
if ((result = getgroups(NGROUPS_MAX, gidlist)) < 0) {
|
||||
/* MacOS may return more than NGROUPS_MAX groups.
|
||||
* Fetch the actual number of groups and create an appropriate allocation. */
|
||||
if ((result = getgroups(0, NULL)) < 0) {
|
||||
POSIX_G(last_error) = errno;
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
gidlist = emalloc(sizeof(gid_t) * result);
|
||||
if ((result = getgroups(result, gidlist)) < 0) {
|
||||
POSIX_G(last_error) = errno;
|
||||
efree(gidlist);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
array_init(return_value);
|
||||
|
||||
for (i=0; i<result; i++) {
|
||||
add_next_index_long(return_value, gidlist[i]);
|
||||
}
|
||||
efree(gidlist);
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
@@ -1534,6 +1534,11 @@ ZEND_METHOD(reflection_function, __construct)
|
||||
}
|
||||
}
|
||||
|
||||
if (intern->ptr) {
|
||||
zval_ptr_dtor(&intern->obj);
|
||||
zval_ptr_dtor(reflection_prop_name(object));
|
||||
}
|
||||
|
||||
ZVAL_STR_COPY(reflection_prop_name(object), fptr->common.function_name);
|
||||
intern->ptr = fptr;
|
||||
intern->ref_type = REF_TYPE_FUNCTION;
|
||||
@@ -2073,6 +2078,10 @@ ZEND_METHOD(reflection_generator, __construct)
|
||||
return;
|
||||
}
|
||||
|
||||
if (intern->ce) {
|
||||
zval_ptr_dtor(&intern->obj);
|
||||
}
|
||||
|
||||
intern->ref_type = REF_TYPE_GENERATOR;
|
||||
Z_ADDREF_P(generator);
|
||||
ZVAL_OBJ(&intern->obj, Z_OBJ_P(generator));
|
||||
|
||||
+29
-27
@@ -1261,13 +1261,11 @@ static void php_session_remove_cookie(void) {
|
||||
zend_llist_element *next;
|
||||
zend_llist_element *current;
|
||||
char *session_cookie;
|
||||
zend_string *e_session_name;
|
||||
size_t session_cookie_len;
|
||||
size_t len = sizeof("Set-Cookie")-1;
|
||||
|
||||
e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)));
|
||||
spprintf(&session_cookie, 0, "Set-Cookie: %s=", ZSTR_VAL(e_session_name));
|
||||
zend_string_free(e_session_name);
|
||||
ZEND_ASSERT(strpbrk(PS(session_name), "=,; \t\r\n\013\014") == NULL);
|
||||
spprintf(&session_cookie, 0, "Set-Cookie: %s=", PS(session_name));
|
||||
|
||||
session_cookie_len = strlen(session_cookie);
|
||||
current = l->head;
|
||||
@@ -1299,7 +1297,7 @@ static int php_session_send_cookie(void) /* {{{ */
|
||||
{
|
||||
smart_str ncookie = {0};
|
||||
zend_string *date_fmt = NULL;
|
||||
zend_string *e_session_name, *e_id;
|
||||
zend_string *e_id;
|
||||
|
||||
if (SG(headers_sent)) {
|
||||
const char *output_start_filename = php_output_get_start_filename();
|
||||
@@ -1313,16 +1311,20 @@ static int php_session_send_cookie(void) /* {{{ */
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* URL encode session_name and id because they might be user supplied */
|
||||
e_session_name = php_url_encode(PS(session_name), strlen(PS(session_name)));
|
||||
/* Prevent broken Set-Cookie header, because the session_name might be user supplied */
|
||||
if (strpbrk(PS(session_name), "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
|
||||
php_error_docref(NULL, E_WARNING, "session.name cannot contain any of the following '=,; \\t\\r\\n\\013\\014'");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* URL encode id because it might be user supplied */
|
||||
e_id = php_url_encode(ZSTR_VAL(PS(id)), ZSTR_LEN(PS(id)));
|
||||
|
||||
smart_str_appendl(&ncookie, "Set-Cookie: ", sizeof("Set-Cookie: ")-1);
|
||||
smart_str_appendl(&ncookie, ZSTR_VAL(e_session_name), ZSTR_LEN(e_session_name));
|
||||
smart_str_appendl(&ncookie, PS(session_name), strlen(PS(session_name)));
|
||||
smart_str_appendc(&ncookie, '=');
|
||||
smart_str_appendl(&ncookie, ZSTR_VAL(e_id), ZSTR_LEN(e_id));
|
||||
|
||||
zend_string_release_ex(e_session_name, 0);
|
||||
zend_string_release_ex(e_id, 0);
|
||||
|
||||
if (PS(cookie_lifetime) > 0) {
|
||||
@@ -1921,13 +1923,24 @@ static PHP_FUNCTION(session_module_name)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static inline void set_user_save_handler_ini(void) {
|
||||
zend_string *ini_name, *ini_val;
|
||||
|
||||
ini_name = zend_string_init("session.save_handler", sizeof("session.save_handler") - 1, 0);
|
||||
ini_val = zend_string_init("user", sizeof("user") - 1, 0);
|
||||
PS(set_handler) = 1;
|
||||
zend_alter_ini_entry(ini_name, ini_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
PS(set_handler) = 0;
|
||||
zend_string_release_ex(ini_val, 0);
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
}
|
||||
|
||||
/* {{{ proto bool session_set_save_handler(string open, string close, string read, string write, string destroy, string gc, string create_sid)
|
||||
Sets user-level functions */
|
||||
static PHP_FUNCTION(session_set_save_handler)
|
||||
{
|
||||
zval *args = NULL;
|
||||
int i, num_args, argc = ZEND_NUM_ARGS();
|
||||
zend_string *ini_name, *ini_val;
|
||||
|
||||
if (PS(session_status) == php_session_active) {
|
||||
php_error_docref(NULL, E_WARNING, "Cannot change save handler when session is active");
|
||||
@@ -2029,14 +2042,8 @@ static PHP_FUNCTION(session_set_save_handler)
|
||||
remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") - 1);
|
||||
}
|
||||
|
||||
if (PS(mod) && PS(session_status) != php_session_active && PS(mod) != &ps_mod_user) {
|
||||
ini_name = zend_string_init("session.save_handler", sizeof("session.save_handler") - 1, 0);
|
||||
ini_val = zend_string_init("user", sizeof("user") - 1, 0);
|
||||
PS(set_handler) = 1;
|
||||
zend_alter_ini_entry(ini_name, ini_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
PS(set_handler) = 0;
|
||||
zend_string_release_ex(ini_val, 0);
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (PS(session_status) != php_session_active && (!PS(mod) || PS(mod) != &ps_mod_user)) {
|
||||
set_user_save_handler_ini();
|
||||
}
|
||||
|
||||
RETURN_TRUE;
|
||||
@@ -2064,14 +2071,8 @@ static PHP_FUNCTION(session_set_save_handler)
|
||||
}
|
||||
}
|
||||
|
||||
if (PS(mod) && PS(mod) != &ps_mod_user) {
|
||||
ini_name = zend_string_init("session.save_handler", sizeof("session.save_handler") - 1, 0);
|
||||
ini_val = zend_string_init("user", sizeof("user") - 1, 0);
|
||||
PS(set_handler) = 1;
|
||||
zend_alter_ini_entry(ini_name, ini_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
|
||||
PS(set_handler) = 0;
|
||||
zend_string_release_ex(ini_val, 0);
|
||||
zend_string_release_ex(ini_name, 0);
|
||||
if (!PS(mod) || PS(mod) != &ps_mod_user) {
|
||||
set_user_save_handler_ini();
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
@@ -2854,7 +2855,8 @@ static int php_rinit_session(zend_bool auto_start) /* {{{ */
|
||||
{
|
||||
php_rinit_session_globals();
|
||||
|
||||
if (PS(mod) == NULL) {
|
||||
PS(mod) = NULL;
|
||||
{
|
||||
char *value;
|
||||
|
||||
value = zend_ini_string("session.save_handler", sizeof("session.save_handler") - 1, 0);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #80774 (session_name() problem with backslash)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('session')) die("skip session extension not available");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
session_name("foo\\bar");
|
||||
session_id('12345');
|
||||
session_start();
|
||||
?>
|
||||
--EXPECTHEADERS--
|
||||
Set-Cookie: foo\bar=12345; path=/
|
||||
--EXPECT--
|
||||
@@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
Bug #80889 (Cannot set save handler when save_handler is invalid)
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--INI--
|
||||
session.save_handler=whatever
|
||||
--FILE--
|
||||
<?php
|
||||
class DummyHandler implements SessionHandlerInterface {
|
||||
public function open($savePath, $sessionName) {
|
||||
return true;
|
||||
}
|
||||
public function close() {
|
||||
return true;
|
||||
}
|
||||
public function read($id) {
|
||||
return '';
|
||||
}
|
||||
public function write($id, $data) {
|
||||
return true;
|
||||
}
|
||||
public function destroy($id) {
|
||||
return true;
|
||||
}
|
||||
public function gc($maxlifetime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$initHandler = ini_get('session.save_handler');
|
||||
session_set_save_handler(new DummyHandler());
|
||||
$setHandler = ini_get('session.save_handler');
|
||||
var_dump($initHandler, $setHandler);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(8) "whatever"
|
||||
string(4) "user"
|
||||
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Bug #80889 (Cannot set save handler when save_handler is invalid)
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--INI--
|
||||
session.save_handler=whatever
|
||||
--FILE--
|
||||
<?php
|
||||
$initHandler = ini_get('session.save_handler');
|
||||
session_set_save_handler(
|
||||
function ($savePath, $sessionName) {
|
||||
return true;
|
||||
},
|
||||
function () {
|
||||
return true;
|
||||
},
|
||||
function ($id) {
|
||||
return '';
|
||||
},
|
||||
function ($id, $data) {
|
||||
return true;
|
||||
},
|
||||
function ($id) {
|
||||
return true;
|
||||
},
|
||||
function ($maxlifetime) {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
$setHandler = ini_get('session.save_handler');
|
||||
var_dump($initHandler, $setHandler);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(8) "whatever"
|
||||
string(4) "user"
|
||||
@@ -48,6 +48,8 @@ string(9) "PHPSESSID"
|
||||
bool(true)
|
||||
string(9) "PHPSESSID"
|
||||
string(9) "PHPSESSID"
|
||||
|
||||
Warning: session_start(): session.name cannot contain any of the following '=,; \t\r\n\013\014' in %s on line %d
|
||||
bool(true)
|
||||
string(1) " "
|
||||
bool(true)
|
||||
@@ -55,6 +57,8 @@ string(1) " "
|
||||
|
||||
Warning: session_name(): session.name cannot be a numeric or empty '' in %s on line %d
|
||||
string(1) " "
|
||||
|
||||
Warning: session_start(): session.name cannot contain any of the following '=,; \t\r\n\013\014' in %s on line %d
|
||||
bool(true)
|
||||
string(1) " "
|
||||
bool(true)
|
||||
|
||||
@@ -3381,6 +3381,7 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns)
|
||||
} else {
|
||||
smart_str prefix = {0};
|
||||
int num = ++SOAP_GLOBAL(cur_uniq_ns);
|
||||
xmlChar *enc_ns;
|
||||
|
||||
while (1) {
|
||||
smart_str_appendl(&prefix, "ns", 2);
|
||||
@@ -3394,7 +3395,9 @@ xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns)
|
||||
num = ++SOAP_GLOBAL(cur_uniq_ns);
|
||||
}
|
||||
|
||||
xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), BAD_CAST(prefix.s ? ZSTR_VAL(prefix.s) : ""));
|
||||
enc_ns = xmlEncodeSpecialChars(node->doc, BAD_CAST(ns));
|
||||
xmlns = xmlNewNs(node->doc->children, enc_ns, BAD_CAST(prefix.s ? ZSTR_VAL(prefix.s) : ""));
|
||||
xmlFree(enc_ns);
|
||||
smart_str_free(&prefix);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -741,9 +741,8 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
|
||||
zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
|
||||
zend_hash_init(&ctx.services, 0, NULL, NULL, 0);
|
||||
|
||||
load_wsdl_ex(this_ptr, struri, &ctx, 0);
|
||||
zend_try {
|
||||
|
||||
load_wsdl_ex(this_ptr, struri, &ctx, 0);
|
||||
schema_pass2(&ctx);
|
||||
|
||||
n = zend_hash_num_elements(&ctx.services);
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #69668 (SOAP: special XML characters in namespace URIs not encoded)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require_once('skipif.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class MySoapClient extends SoapClient {
|
||||
public function __doRequest($request, $location, $action, $version, $one_way = 0) {
|
||||
echo $request, PHP_EOL;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
$client = new MySoapClient(__DIR__ . '/bug69668.wsdl', [
|
||||
'trace' => true,
|
||||
'exceptions' => true,
|
||||
'cache_wsdl' => WSDL_CACHE_NONE,
|
||||
]);
|
||||
|
||||
$client->test();
|
||||
?>
|
||||
--EXPECT--
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/69668.php?a=a&b=b" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test/></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://localhost/69668.php?a=a&b=b" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" name="TestService" targetNamespace="http://localhost/69668.php?a=a&b=b">
|
||||
<types>
|
||||
<xsd:schema targetNamespace="http://localhost/69668.php?a=a&b=b" />
|
||||
</types>
|
||||
<portType name="TestServicePort">
|
||||
<operation name="test">
|
||||
<documentation>test</documentation>
|
||||
<input message="tns:testIn" />
|
||||
<output message="tns:testOut" />
|
||||
</operation>
|
||||
</portType>
|
||||
<binding name="TestServiceBinding" type="tns:TestServicePort">
|
||||
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||
<operation name="test">
|
||||
<soap:operation soapAction="http://localhost/69668.php?a=a&b=b#test" />
|
||||
<input>
|
||||
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/69668.php?a=a&b=b" />
|
||||
</input>
|
||||
<output>
|
||||
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/69668.php?a=a&b=b" />
|
||||
</output>
|
||||
</operation>
|
||||
</binding>
|
||||
<service name="TestServiceService">
|
||||
<port name="TestServicePort" binding="tns:TestServiceBinding">
|
||||
<soap:address location="http://localhost/69668.php?a=a&b=b" />
|
||||
</port>
|
||||
</service>
|
||||
<message name="testIn" />
|
||||
<message name="testOut">
|
||||
<part name="return" type="xsd:string" />
|
||||
</message>
|
||||
</definitions>
|
||||
+2
-2
@@ -1179,7 +1179,7 @@ SPL_METHOD(Array, __construct)
|
||||
spl_array_object *intern;
|
||||
zval *array;
|
||||
zend_long ar_flags = 0;
|
||||
zend_class_entry *ce_get_iterator = spl_ce_Iterator;
|
||||
zend_class_entry *ce_get_iterator = spl_ce_ArrayIterator;
|
||||
|
||||
if (ZEND_NUM_ARGS() == 0) {
|
||||
return; /* nothing to do */
|
||||
@@ -1232,7 +1232,7 @@ SPL_METHOD(Array, setIteratorClass)
|
||||
{
|
||||
zval *object = ZEND_THIS;
|
||||
spl_array_object *intern = Z_SPLARRAY_P(object);
|
||||
zend_class_entry * ce_get_iterator = spl_ce_Iterator;
|
||||
zend_class_entry *ce_get_iterator = spl_ce_ArrayIterator;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_CLASS(ce_get_iterator)
|
||||
|
||||
+3
-19
@@ -1677,15 +1677,7 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval
|
||||
static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter)
|
||||
{
|
||||
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
|
||||
|
||||
if (!Z_ISUNDEF(iterator->intern.data)) {
|
||||
zval *object = &iterator->intern.data;
|
||||
zval_ptr_dtor(object);
|
||||
}
|
||||
/* Otherwise we were called from the owning object free storage handler as
|
||||
* it sets iterator->intern.data to IS_UNDEF.
|
||||
* We don't even need to destroy iterator->current as we didn't add a
|
||||
* reference to it in move_forward or get_iterator */
|
||||
zval_ptr_dtor(&iterator->intern.data);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1747,16 +1739,8 @@ static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter)
|
||||
static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter)
|
||||
{
|
||||
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
|
||||
|
||||
if (!Z_ISUNDEF(iterator->intern.data)) {
|
||||
zval *object = &iterator->intern.data;
|
||||
zval_ptr_dtor(object);
|
||||
} else {
|
||||
if (!Z_ISUNDEF(iterator->current)) {
|
||||
zval_ptr_dtor(&iterator->current);
|
||||
ZVAL_UNDEF(&iterator->current);
|
||||
}
|
||||
}
|
||||
zval_ptr_dtor(&iterator->intern.data);
|
||||
zval_ptr_dtor(&iterator->current);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -20,6 +20,6 @@ try {
|
||||
?>
|
||||
--EXPECT--
|
||||
Bad iterator type:
|
||||
ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'Exception' given(6)
|
||||
ArrayObject::__construct() expects parameter 3 to be a class name derived from ArrayIterator, 'Exception' given(6)
|
||||
Non-existent class:
|
||||
ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'nonExistentClassName' given(13)
|
||||
ArrayObject::__construct() expects parameter 3 to be a class name derived from ArrayIterator, 'nonExistentClassName' given(13)
|
||||
@@ -43,14 +43,14 @@ try {
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from Iterator, 'nonExistentClass' given in %s on line 4
|
||||
Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from ArrayIterator, 'nonExistentClass' given in %s on line %d
|
||||
a=>1
|
||||
b=>2
|
||||
c=>3
|
||||
|
||||
Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from Iterator, 'stdClass' given in %s on line 14
|
||||
Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from ArrayIterator, 'stdClass' given in %s on line %d
|
||||
a=>1
|
||||
b=>2
|
||||
c=>3
|
||||
string(113) "ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'nonExistentClass' given"
|
||||
string(105) "ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'stdClass' given"
|
||||
string(118) "ArrayObject::__construct() expects parameter 3 to be a class name derived from ArrayIterator, 'nonExistentClass' given"
|
||||
string(110) "ArrayObject::__construct() expects parameter 3 to be a class name derived from ArrayIterator, 'stdClass' given"
|
||||
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #80719: Iterating after failed ArrayObject::setIteratorClass() causes Segmentation fault
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$array = new ArrayObject([42]);
|
||||
$array->setIteratorClass(FilterIterator::class);
|
||||
foreach ($array as $v) {
|
||||
var_dump($v);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from ArrayIterator, 'FilterIterator' given in %s on line %d
|
||||
int(42)
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Don't leak when breaking from FilesystemIterator
|
||||
--FILE--
|
||||
<?php
|
||||
$iterator = new FilesystemIterator(__DIR__);
|
||||
foreach ($iterator as $value) {
|
||||
break;
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
@@ -564,10 +564,6 @@ PHP_FUNCTION(file_get_contents)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (maxlen > INT_MAX) {
|
||||
php_error_docref(NULL, E_WARNING, "maxlen truncated from " ZEND_LONG_FMT " to %d bytes", maxlen, INT_MAX);
|
||||
maxlen = INT_MAX;
|
||||
}
|
||||
if ((contents = php_stream_copy_to_mem(stream, maxlen, 0)) != NULL) {
|
||||
RETVAL_STR(contents);
|
||||
} else {
|
||||
|
||||
@@ -680,7 +680,7 @@ finish:
|
||||
/* status codes of 1xx are "informational", and will be followed by a real response
|
||||
* e.g "100 Continue". RFC 7231 states that unexpected 1xx status MUST be parsed,
|
||||
* and MAY be ignored. As such, we need to skip ahead to the "real" status*/
|
||||
if (response_code >= 100 && response_code < 200) {
|
||||
if (response_code >= 100 && response_code < 200 && response_code != 101) {
|
||||
/* consume lines until we find a line starting 'HTTP/1' */
|
||||
while (
|
||||
!php_stream_eof(stream)
|
||||
@@ -732,24 +732,16 @@ finish:
|
||||
|
||||
/* read past HTTP headers */
|
||||
|
||||
http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE);
|
||||
|
||||
while (!php_stream_eof(stream)) {
|
||||
size_t http_header_line_length;
|
||||
|
||||
if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') {
|
||||
if (http_header_line != NULL) {
|
||||
efree(http_header_line);
|
||||
}
|
||||
if ((http_header_line = php_stream_get_line(stream, NULL, 0, &http_header_line_length)) && *http_header_line != '\n' && *http_header_line != '\r') {
|
||||
char *e = http_header_line + http_header_line_length - 1;
|
||||
char *http_header_value;
|
||||
if (*e != '\n') {
|
||||
do { /* partial header */
|
||||
if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) == NULL) {
|
||||
php_stream_wrapper_log_error(wrapper, options, "Failed to read HTTP headers");
|
||||
goto out;
|
||||
}
|
||||
e = http_header_line + http_header_line_length - 1;
|
||||
} while (*e != '\n');
|
||||
continue;
|
||||
}
|
||||
|
||||
while (e >= http_header_line && (*e == '\n' || *e == '\r')) {
|
||||
e--;
|
||||
}
|
||||
|
||||
+2
-2
@@ -176,7 +176,7 @@ static ZEND_COLD void php_print_gpcse_array(char *name, uint32_t name_length)
|
||||
key = zend_string_init(name, name_length, 0);
|
||||
zend_is_auto_global(key);
|
||||
|
||||
if ((data = zend_hash_find(&EG(symbol_table), key)) != NULL && (Z_TYPE_P(data) == IS_ARRAY)) {
|
||||
if ((data = zend_hash_find_deref(&EG(symbol_table), key)) != NULL && (Z_TYPE_P(data) == IS_ARRAY)) {
|
||||
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), num_key, string_key, tmp) {
|
||||
if (!sapi_module.phpinfo_as_text) {
|
||||
php_info_print("<tr>");
|
||||
@@ -1000,7 +1000,7 @@ PHPAPI ZEND_COLD void php_print_info(int flag)
|
||||
}
|
||||
|
||||
|
||||
if ((flag & PHP_INFO_CREDITS) && !sapi_module.phpinfo_as_text) {
|
||||
if (flag & PHP_INFO_CREDITS) {
|
||||
php_info_print_hr();
|
||||
php_print_credits(PHP_CREDITS_ALL & ~PHP_CREDITS_FULLPAGE);
|
||||
}
|
||||
|
||||
@@ -456,10 +456,6 @@ PHP_FUNCTION(stream_get_contents)
|
||||
}
|
||||
}
|
||||
|
||||
if (maxlen > INT_MAX) {
|
||||
php_error_docref(NULL, E_WARNING, "maxlen truncated from " ZEND_LONG_FMT " to %d bytes", maxlen, INT_MAX);
|
||||
maxlen = INT_MAX;
|
||||
}
|
||||
if ((contents = php_stream_copy_to_mem(stream, maxlen, 0))) {
|
||||
RETURN_STR(contents);
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
Bug #80915: Taking a reference to $_SERVER hides its values from phpinfo()
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$_ENV = [];
|
||||
$_SERVER = [ 'test' => 'test' ];
|
||||
|
||||
$reference =& $_SERVER;
|
||||
|
||||
phpinfo(INFO_VARIABLES);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
phpinfo()
|
||||
|
||||
PHP Variables
|
||||
|
||||
Variable => Value
|
||||
$_SERVER['test'] => test
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #80771 (phpinfo(INFO_CREDITS) displays nothing in CLI)
|
||||
--FILE--
|
||||
<?php
|
||||
ob_start();
|
||||
phpinfo(INFO_CREDITS);
|
||||
$info = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
phpcredits();
|
||||
$credits = ob_get_clean();
|
||||
|
||||
var_dump(strpos($info, $credits) !== false);
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #78719 (http wrapper silently ignores long Location headers)
|
||||
--SKIPIF--
|
||||
<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?>
|
||||
--INI--
|
||||
allow_url_fopen=1
|
||||
--FILE--
|
||||
<?php
|
||||
require 'server.inc';
|
||||
|
||||
$url = str_repeat('*', 2000);
|
||||
$responses = array(
|
||||
"data://text/plain,HTTP/1.0 302 Ok\r\nLocation: $url\r\n\r\nBody",
|
||||
);
|
||||
$pid = http_server("tcp://127.0.0.1:12342", $responses, $output);
|
||||
|
||||
$context = stream_context_create(['http' => ['follow_location' => 0]]);
|
||||
$stream = fopen('http://127.0.0.1:12342/', 'r', false, $context);
|
||||
var_dump(stream_get_contents($stream));
|
||||
var_dump(stream_get_meta_data($stream)['wrapper_data'][1] === "Location: $url");
|
||||
|
||||
http_server_kill($pid);
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(4) "Body"
|
||||
bool(true)
|
||||
@@ -0,0 +1,41 @@
|
||||
--TEST--
|
||||
Bug #80838 (HTTP wrapper waits for HTTP 1 response after HTTP 101)
|
||||
--INI--
|
||||
allow_url_fopen=1
|
||||
--SKIPIF--
|
||||
<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require 'server.inc';
|
||||
|
||||
$responses = [
|
||||
"data://text/plain,HTTP/1.1 101 Switching Protocols\r\nHeader1: Value1\r\nHeader2: Value2\r\n\r\n"
|
||||
. "Hello from another protocol"
|
||||
];
|
||||
|
||||
$pid = http_server('tcp://127.0.0.1:12342', $responses);
|
||||
|
||||
$options = [
|
||||
'http' => [
|
||||
'ignore_errors' => true
|
||||
],
|
||||
];
|
||||
|
||||
$ctx = stream_context_create($options);
|
||||
|
||||
$fd = fopen('http://127.0.0.1:12342/', 'rb', false, $ctx);
|
||||
fclose($fd);
|
||||
var_dump($http_response_header);
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(32) "HTTP/1.1 101 Switching Protocols"
|
||||
[1]=>
|
||||
string(15) "Header1: Value1"
|
||||
[2]=>
|
||||
string(15) "Header2: Value2"
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
--TEST--
|
||||
Bug #72964 (White space not unfolded for CC/Bcc headers)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (PHP_OS_FAMILY !== 'Windows') die('skip Windows only test');
|
||||
if (getenv("SKIP_SLOW_TESTS")) die('skip slow test');
|
||||
require_once __DIR__ . '/mail_skipif.inc';
|
||||
?>
|
||||
--INI--
|
||||
SMTP=localhost
|
||||
smtp_port=25
|
||||
--FILE--
|
||||
<?php
|
||||
require_once __DIR__ . '/mail_include.inc';
|
||||
|
||||
function find_and_delete_message($username, $subject) {
|
||||
global $default_mailbox, $password;
|
||||
|
||||
$imap_stream = imap_open($default_mailbox, $username, $password);
|
||||
if ($imap_stream === false) {
|
||||
die("Cannot connect to IMAP server $server: " . imap_last_error() . "\n");
|
||||
}
|
||||
|
||||
$found = false;
|
||||
$repeat_count = 20; // we will repeat a max of 20 times
|
||||
while (!$found && $repeat_count > 0) {
|
||||
// sleep for a while to allow msg to be delivered
|
||||
sleep(1);
|
||||
|
||||
$num_messages = imap_check($imap_stream)->Nmsgs;
|
||||
for ($i = $num_messages; $i > 0; $i--) {
|
||||
$info = imap_headerinfo($imap_stream, $i);
|
||||
if ($info->subject === $subject) {
|
||||
$header = imap_fetchheader($imap_stream, $i);
|
||||
echo "X-Mailer header found: ";
|
||||
var_dump(strpos($header, 'X-Mailer: bug80706') !== false);
|
||||
imap_delete($imap_stream, $i);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$repeat_count--;
|
||||
}
|
||||
|
||||
imap_close($imap_stream, CL_EXPUNGE);
|
||||
return $found;
|
||||
}
|
||||
|
||||
$to = "{$users[1]}@$domain";
|
||||
$subject = bin2hex(random_bytes(16));
|
||||
$message = 'hello';
|
||||
$headers = "From: webmaster@example.com\r\n"
|
||||
. "Bcc: {$users[2]}@$domain\r\n"
|
||||
. "X-Mailer: bug80706";
|
||||
|
||||
$res = mail($to, $subject, $message, $headers);
|
||||
if ($res !== true) {
|
||||
die("TEST FAILED : Unable to send test email\n");
|
||||
} else {
|
||||
echo "Message sent OK\n";
|
||||
}
|
||||
|
||||
foreach ([$users[1], $users[2]] as $user) {
|
||||
if (!find_and_delete_message("$user@$domain", $subject)) {
|
||||
echo "TEST FAILED: email not delivered\n";
|
||||
} else {
|
||||
echo "TEST PASSED: Message sent and deleted OK\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Message sent OK
|
||||
X-Mailer header found: bool(true)
|
||||
TEST PASSED: Message sent and deleted OK
|
||||
X-Mailer header found: bool(true)
|
||||
TEST PASSED: Message sent and deleted OK
|
||||
@@ -0,0 +1,93 @@
|
||||
--TEST--
|
||||
Bug #80751 (Comma in recipient name breaks email delivery)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (PHP_OS_FAMILY !== 'Windows') die('skip Windows only test');
|
||||
if (getenv("SKIP_SLOW_TESTS")) die('skip slow test');
|
||||
require_once __DIR__ . '/mail_skipif.inc';
|
||||
?>
|
||||
--INI--
|
||||
SMTP=localhost
|
||||
smtp_port=25
|
||||
--FILE--
|
||||
<?php
|
||||
require_once __DIR__ . '/mail_include.inc';
|
||||
|
||||
function find_and_delete_message($username, $subject) {
|
||||
global $default_mailbox, $password;
|
||||
|
||||
$imap_stream = imap_open($default_mailbox, $username, $password);
|
||||
if ($imap_stream === false) {
|
||||
die("Cannot connect to IMAP server $server: " . imap_last_error() . "\n");
|
||||
}
|
||||
|
||||
$found = false;
|
||||
$repeat_count = 20; // we will repeat a max of 20 times
|
||||
while (!$found && $repeat_count > 0) {
|
||||
// sleep for a while to allow msg to be delivered
|
||||
sleep(1);
|
||||
|
||||
$num_messages = imap_check($imap_stream)->Nmsgs;
|
||||
for ($i = $num_messages; $i > 0; $i--) {
|
||||
$info = imap_headerinfo($imap_stream, $i);
|
||||
if ($info->subject === $subject) {
|
||||
$header = imap_fetchheader($imap_stream, $i);
|
||||
echo "Return-Path header found: ";
|
||||
var_dump(strpos($header, 'Return-Path: joe@example.com') !== false);
|
||||
echo "To header found: ";
|
||||
var_dump(strpos($header, 'To: "<bob@example.com>" <info@mail.local>') !== false);
|
||||
echo "From header found: ";
|
||||
var_dump(strpos($header, 'From: "<bob@example.com>" <joe@example.com>') !== false);
|
||||
echo "Cc header found: ";
|
||||
var_dump(strpos($header, 'Cc: "Lastname, Firstname\\\\" <admin@mail.local>') !== false);
|
||||
imap_delete($imap_stream, $i);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$repeat_count--;
|
||||
}
|
||||
|
||||
imap_close($imap_stream, CL_EXPUNGE);
|
||||
return $found;
|
||||
}
|
||||
|
||||
$to = "\"<bob@example.com>\" <{$users[1]}@$domain>";
|
||||
$subject = bin2hex(random_bytes(16));
|
||||
$message = 'hello';
|
||||
$headers = "From: \"<bob@example.com>\" <joe@example.com>\r\n"
|
||||
. "Cc: \"Lastname, Firstname\\\\\" <{$users[2]}@$domain>\r\n"
|
||||
. "Bcc: \"Firstname \\\"Ni,ck\\\" Lastname\" <{$users[3]}@$domain>\r\n";
|
||||
|
||||
$res = mail($to, $subject, $message, $headers);
|
||||
if ($res !== true) {
|
||||
die("TEST FAILED : Unable to send test email\n");
|
||||
} else {
|
||||
echo "Message sent OK\n";
|
||||
}
|
||||
|
||||
foreach ([$users[1], $users[2], $users[3]] as $user) {
|
||||
if (!find_and_delete_message("$user@$domain", $subject)) {
|
||||
echo "TEST FAILED: email not delivered\n";
|
||||
} else {
|
||||
echo "TEST PASSED: Message sent and deleted OK\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Message sent OK
|
||||
Return-Path header found: bool(true)
|
||||
To header found: bool(true)
|
||||
From header found: bool(true)
|
||||
Cc header found: bool(true)
|
||||
TEST PASSED: Message sent and deleted OK
|
||||
Return-Path header found: bool(true)
|
||||
To header found: bool(true)
|
||||
From header found: bool(true)
|
||||
Cc header found: bool(true)
|
||||
TEST PASSED: Message sent and deleted OK
|
||||
Return-Path header found: bool(true)
|
||||
To header found: bool(true)
|
||||
From header found: bool(true)
|
||||
Cc header found: bool(true)
|
||||
TEST PASSED: Message sent and deleted OK
|
||||
Loaded 100 of 120 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user