mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-08 09:47:30 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd3656d9fd | ||
|
|
83cb78416b | ||
|
|
d27b4824e6 | ||
|
|
70523ce41f | ||
|
|
903b1828dc | ||
|
|
b7dc3d9039 | ||
|
|
53c1b48574 | ||
|
|
40235e7eef | ||
|
|
1a98878bfe | ||
|
|
704a0ab0c9 | ||
|
|
aa74c30466 | ||
|
|
ad63bd169b | ||
|
|
69bab6e5a5 | ||
|
|
bec68d59a2 | ||
|
|
b6b15fc65c | ||
|
|
43e6fd1e2b | ||
|
|
f95b27c6f6 | ||
|
|
0cad701374 | ||
|
|
cc5c51e7f0 | ||
|
|
bec22af8d7 | ||
|
|
b15bfb9129 | ||
|
|
49b5ffe48c | ||
|
|
3759c6316d | ||
|
|
d2037b1bd4 | ||
|
|
af4143753f | ||
|
|
fd1ffa4692 | ||
|
|
27f168cf63 | ||
|
|
90318fbcbe | ||
|
|
35c80583f0 | ||
|
|
e46b3c3e70 | ||
|
|
e359812ce3 | ||
|
|
236522529c | ||
|
|
3d0a0f801b | ||
|
|
e2ef4e9e2f | ||
|
|
d19b6aa5ba | ||
|
|
d153fbc5a9 | ||
|
|
36a7d9fca4 | ||
|
|
9977de0028 | ||
|
|
78d24429f2 | ||
|
|
6b73e692c9 | ||
|
|
d91b643c87 | ||
|
|
1210c3b960 | ||
|
|
66b32f25d5 | ||
|
|
cb5af4e8a0 | ||
|
|
f80ad18afa | ||
|
|
506a764089 | ||
|
|
2c3933821f | ||
|
|
6c631ccfef | ||
|
|
a30b919872 | ||
|
|
18a9ae412f | ||
|
|
44494c09bc | ||
|
|
3891e0d13a | ||
|
|
3fc1bdc81c | ||
|
|
cd94cf60a2 | ||
|
|
ff2b5bda59 | ||
|
|
5da0579259 | ||
|
|
7faaf5a89a | ||
|
|
9bf11045db | ||
|
|
06b130579e | ||
|
|
fc9cdb723b | ||
|
|
f83c207d60 | ||
|
|
1bdd97a601 | ||
|
|
6d8892aacd | ||
|
|
91c6fb881e | ||
|
|
3309f2fbb9 | ||
|
|
57d5dc5688 | ||
|
|
e561d4100b | ||
|
|
16609880f8 | ||
|
|
70239ea1d3 | ||
|
|
7ddfe73e69 | ||
|
|
3e31ae5d70 | ||
|
|
bfbfb9dabd | ||
|
|
dcba479848 | ||
|
|
37ca6a7a2a | ||
|
|
ad0acc0aa9 | ||
|
|
fe202d99c8 | ||
|
|
191e15309f | ||
|
|
5d21a15cc3 | ||
|
|
68892410f7 | ||
|
|
4831e150c5 | ||
|
|
cedee4408b | ||
|
|
fb4c811835 | ||
|
|
ce73841cdc | ||
|
|
ccf051c317 | ||
|
|
0b8414832e | ||
|
|
2549f7d220 | ||
|
|
295c66911f | ||
|
|
4450288344 | ||
|
|
d1bce98597 | ||
|
|
06fa35568e | ||
|
|
fd4c42efab | ||
|
|
a7ada30ac6 | ||
|
|
3a04adce82 | ||
|
|
b2f49c69b1 | ||
|
|
e9aa0337ab | ||
|
|
bfadd9fdaf | ||
|
|
ac12cc85aa | ||
|
|
f0ccd9ffc6 | ||
|
|
d20053a556 | ||
|
|
6088713216 | ||
|
|
7b1a4e2400 | ||
|
|
ec8457d982 | ||
|
|
6fe75f9e45 | ||
|
|
e90bce7f08 | ||
|
|
6c44a71e4a | ||
|
|
f9a755d0d2 | ||
|
|
5ae49c43dc | ||
|
|
9a9eed472b | ||
|
|
e1b4cabbd6 | ||
|
|
a2f3ec1777 | ||
|
|
619c4e9f2e | ||
|
|
e05c6a25f9 | ||
|
|
9b1950b005 | ||
|
|
5611058766 | ||
|
|
917952453c | ||
|
|
14047b50b4 | ||
|
|
e9c0367fdc | ||
|
|
3e1eff251b | ||
|
|
ea0f26420d | ||
|
|
7f551c728c | ||
|
|
1e7f1b90e8 | ||
|
|
8ed3b74a0c | ||
|
|
d07a6fdedf | ||
|
|
354a1c27aa | ||
|
|
3b53d28e60 | ||
|
|
d2d1a50b04 | ||
|
|
5477d68300 | ||
|
|
a61d24e4d8 | ||
|
|
ce72bc6b65 | ||
|
|
1aa30bb71c | ||
|
|
f31d7ca85e | ||
|
|
b67ca4f07c | ||
|
|
8f13599a64 | ||
|
|
6615b9c287 | ||
|
|
c7a86a38a3 | ||
|
|
ed1df9d135 | ||
|
|
b55715d61a | ||
|
|
8e5a2096a9 | ||
|
|
7b8212f4d1 | ||
|
|
a90ac8b5b2 | ||
|
|
bdac9ef10d | ||
|
|
08a3062816 | ||
|
|
d7b5954f28 | ||
|
|
0a25b41f6d | ||
|
|
eea61cda7d | ||
|
|
805a330681 | ||
|
|
d1d692abe7 | ||
|
|
588db7cecf | ||
|
|
0c6a68fa36 | ||
|
|
a2b8a62abf | ||
|
|
0d5be6ce91 | ||
|
|
9ec1525eb5 | ||
|
|
31fe6cfe76 | ||
|
|
7b0ed8975d | ||
|
|
54bed8d2ea | ||
|
|
9f02f9fd5c | ||
|
|
4029c0b6a2 | ||
|
|
0f811bb7b6 | ||
|
|
56a5d0bd91 | ||
|
|
849c49a714 | ||
|
|
731eeb8dec | ||
|
|
002983e463 | ||
|
|
f7755163b7 | ||
|
|
dc1cd3daf2 | ||
|
|
b8fdaa7c42 | ||
|
|
f6efe70505 | ||
|
|
01a4de5c58 | ||
|
|
da5fbb8c36 | ||
|
|
c83af86f8b | ||
|
|
887a7b5714 | ||
|
|
a22bd7a3a8 | ||
|
|
3d5b6f234e | ||
|
|
bc8f292c05 | ||
|
|
d2a86e1c0f | ||
|
|
682d28abf7 | ||
|
|
c684d32fb8 | ||
|
|
9efaac30ae | ||
|
|
f3ab302270 | ||
|
|
f3aefc6d07 | ||
|
|
d8b7728b0e | ||
|
|
88460c017a | ||
|
|
e12c069d33 | ||
|
|
a2c87c7f29 | ||
|
|
263c587854 | ||
|
|
f030f34622 | ||
|
|
0dbb581cf4 | ||
|
|
9d8b913de5 | ||
|
|
0aa1a2c833 | ||
|
|
bc4cb277d3 | ||
|
|
66c35b083b | ||
|
|
402adc1df1 | ||
|
|
738016bd88 | ||
|
|
62a652a0d5 | ||
|
|
b7442f1bb8 | ||
|
|
0ecac37c40 | ||
|
|
40fe50daf6 | ||
|
|
218154e695 | ||
|
|
79f046f89e | ||
|
|
eb405a2192 | ||
|
|
7af270eb28 | ||
|
|
1e4cff9ddb | ||
|
|
6d3a2b4693 | ||
|
|
e177d26d0e | ||
|
|
7df8e4fc0a | ||
|
|
6ef6d31776 | ||
|
|
58e00df9fe | ||
|
|
72a2ab39ba | ||
|
|
7f9872387e | ||
|
|
e4d9d91462 | ||
|
|
ec2ecb7e12 | ||
|
|
e97577edde | ||
|
|
91d4d175ab | ||
|
|
85095dfd09 | ||
|
|
93740a2482 | ||
|
|
b8b880932e | ||
|
|
e68fd40e22 | ||
|
|
bb47fb0783 | ||
|
|
2e9dccef78 | ||
|
|
30ddfd49ed | ||
|
|
620a753185 | ||
|
|
da35fa2cb8 | ||
|
|
5c8d69bf6f | ||
|
|
cf65905974 | ||
|
|
a467a89f16 | ||
|
|
999370b756 | ||
|
|
a785ccd21a | ||
|
|
32e7b0864c | ||
|
|
4c55b1c16d | ||
|
|
963428a75d | ||
|
|
5686e6e33e | ||
|
|
78c9a53df7 | ||
|
|
a2de42041c | ||
|
|
c421d9afec | ||
|
|
661bce47ae | ||
|
|
d53e9c7392 | ||
|
|
fe2885d80a | ||
|
|
20c261b2fe | ||
|
|
09e522322a | ||
|
|
5ead86a35e | ||
|
|
a529826d95 | ||
|
|
41bc51ce2d | ||
|
|
7ef2fa6d0d | ||
|
|
f21c054903 | ||
|
|
ab8782d1e6 | ||
|
|
e072537e7f | ||
|
|
763a7b8ca3 | ||
|
|
b3a669bec1 | ||
|
|
623a11d7de | ||
|
|
433758ceb3 | ||
|
|
82fbaab53c | ||
|
|
4f03401628 | ||
|
|
da7add3525 | ||
|
|
54bf8c820f | ||
|
|
ad2d2e41de | ||
|
|
c4464526cd | ||
|
|
00cfa1a367 | ||
|
|
a573c0e9ed | ||
|
|
61eebb559e | ||
|
|
bd6eabd659 | ||
|
|
d209ccd4cc | ||
|
|
ab07bc1fff | ||
|
|
7e7ef44fab | ||
|
|
1307275b43 | ||
|
|
6eb83a63e1 | ||
|
|
3a04b507ec | ||
|
|
f167b06d4c | ||
|
|
7899f6a906 | ||
|
|
97f9fd6949 | ||
|
|
b419590893 | ||
|
|
217c05da52 | ||
|
|
e7d40afb7a | ||
|
|
82174e68b6 | ||
|
|
e3965913c4 | ||
|
|
c7920aba3e | ||
|
|
a7739be22f | ||
|
|
95c8f67a4c | ||
|
|
6814ba11bc | ||
|
|
58c25bf679 | ||
|
|
e7ce7c6bb2 | ||
|
|
e93259bb23 | ||
|
|
6818ca3c02 | ||
|
|
1fd32e9c2f | ||
|
|
f8850ccd85 | ||
|
|
ee4fa7d482 | ||
|
|
769d2d9b62 | ||
|
|
3e92365fa2 | ||
|
|
d9a3cb0b36 | ||
|
|
65ffdc2adf | ||
|
|
58cb3312d6 | ||
|
|
9177542b4d | ||
|
|
66bd861fcd | ||
|
|
0a416b3d97 | ||
|
|
5da591c529 | ||
|
|
59e76ec01d | ||
|
|
488544b336 | ||
|
|
0d88388912 | ||
|
|
41fb0eaa11 | ||
|
|
b6308f5b48 | ||
|
|
58c5df3d37 | ||
|
|
72bfb2523a | ||
|
|
0e836f523a | ||
|
|
007ac353dd | ||
|
|
609195e991 | ||
|
|
2cc1ab81c2 | ||
|
|
e3133e4db7 | ||
|
|
a976283c34 | ||
|
|
040196972c | ||
|
|
6ff0b24ef4 | ||
|
|
4c68aaabf1 | ||
|
|
3f00c9367d | ||
|
|
06f7c177c8 | ||
|
|
2694953ada | ||
|
|
6d60ed69a1 | ||
|
|
3e8d8f7fb3 | ||
|
|
e0f5d62bd6 | ||
|
|
e3f7c352dc | ||
|
|
8363df3703 | ||
|
|
759e841b24 | ||
|
|
44f87fbf36 | ||
|
|
8ac6fee856 | ||
|
|
5f0e62a3e5 | ||
|
|
5e824a88d0 | ||
|
|
254a5914ad | ||
|
|
7f0ab7c20c | ||
|
|
fa574ddd6f | ||
|
|
637713c1a4 | ||
|
|
700f876a1a | ||
|
|
c2fb85547d | ||
|
|
c39fb1fc4f | ||
|
|
3ead672394 | ||
|
|
8be12e770f | ||
|
|
5025eb05bd | ||
|
|
16cda039b5 | ||
|
|
006355c9fa | ||
|
|
4dc0662eca | ||
|
|
d63a7aa6cf | ||
|
|
7d001aff03 | ||
|
|
a890c5beb8 | ||
|
|
58d3dd466f | ||
|
|
19a44ffb7b | ||
|
|
019fd1d9ba | ||
|
|
9ad9cc71ff | ||
|
|
461e140afc | ||
|
|
af37d58cf7 | ||
|
|
4ac954ac3e | ||
|
|
fb3f078eeb | ||
|
|
e8768b338c | ||
|
|
1c22ace058 | ||
|
|
3b5475e9ee | ||
|
|
3c3d59aa39 | ||
|
|
4a72dd782d | ||
|
|
900d4cdb9e | ||
|
|
01c00953ff | ||
|
|
c814b34b1d | ||
|
|
66fda0cdb1 | ||
|
|
33c2b47de3 | ||
|
|
2cfb09caa7 | ||
|
|
831eba0eac | ||
|
|
bd2a00acdf | ||
|
|
5388143855 | ||
|
|
5c221bcd01 | ||
|
|
08089b575b | ||
|
|
e7ca69f1fa | ||
|
|
e5d8ac92a4 | ||
|
|
934691fabb | ||
|
|
af324e24df | ||
|
|
b3e0e555c8 | ||
|
|
74888bede8 | ||
|
|
4a6a9c79fd | ||
|
|
7a9c20f3fd | ||
|
|
2ec59b3ef3 | ||
|
|
961900fa17 | ||
|
|
b243f2feca |
No files matched your search
+1
-1
@@ -16,7 +16,7 @@ environment:
|
||||
PHP_BUILD_CACHE_BASE_DIR: c:\build-cache
|
||||
PHP_BUILD_OBJ_DIR: c:\obj
|
||||
PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk
|
||||
PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0beta3
|
||||
PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0beta5
|
||||
PHP_BUILD_CRT: vc15
|
||||
# ext and env setup for tests
|
||||
#MYSQL_TEST_PASSWD: Password12!
|
||||
|
||||
+17
-5
@@ -1,17 +1,19 @@
|
||||
# http://editorconfig.org/
|
||||
# https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*.{c,h,awk,w32,bat,mk,frag}]
|
||||
[*]
|
||||
tab_width = 4
|
||||
|
||||
[*.{c,h,y,awk,w32,bat,mk,frag,cpp}]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{php,phpt}]
|
||||
[*.{php,phpt,inc}]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
@@ -31,5 +33,15 @@ insert_final_newline = true
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = false
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 80
|
||||
|
||||
[COMMIT_EDITMSG]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
max_line_length = 80
|
||||
+2
-1
@@ -67,7 +67,8 @@ before_script:
|
||||
|
||||
# Run PHPs run-tests.php
|
||||
script:
|
||||
- ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120
|
||||
- ./sapi/cli/php run-tests.php -P -d extension=`pwd`/modules/zend_test.so $(if [ $ENABLE_DEBUG == 0 ]; then echo "-d opcache.enable_cli=1 -d zend_extension=`pwd`/modules/opcache.so"; fi) -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --offline --show-diff --show-slow 1000 --set-timeout 120
|
||||
- sapi/cli/php -d extension_dir=`pwd`/modules -r 'dl("zend_test");'
|
||||
|
||||
after_success:
|
||||
- ccache --show-stats
|
||||
@@ -1,5 +1,195 @@
|
||||
PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
30 May 2019, PHP 7.3.6
|
||||
|
||||
- cURL:
|
||||
. Implemented FR #72189 (Add missing CURL_VERSION_* constants). (Javier
|
||||
Spagnoletti)
|
||||
|
||||
- EXIF:
|
||||
. Fixed bug #77988 (heap-buffer-overflow on php_jpg_get16).
|
||||
(CVE-2019-11040) (Stas)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #77934 (php-fpm kill -USR2 not working). (Jakub Zelenka)
|
||||
. Fixed bug #77921 (static.php.net doesn't work anymore). (Peter Kokot)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #77943 (imageantialias($image, false); does not work). (cmb)
|
||||
. Fixed bug #77973 (Uninitialized read in gdImageCreateFromXbm).
|
||||
(CVE-2019-11038) (cmb)
|
||||
|
||||
- Iconv:
|
||||
. Fixed bug #78069 (Out-of-bounds read in iconv.c:_php_iconv_mime_decode()
|
||||
due to integer overflow). (CVE-2019-11039). (maris dot adam)
|
||||
|
||||
- JSON:
|
||||
. Fixed bug #77843 (Use after free with json serializer). (Nikita)
|
||||
|
||||
- Opcache:
|
||||
. Fixed possible crashes, because of inconsistent PCRE cache and opcache
|
||||
SHM reset. (Alexey Kalinin, Dmitry)
|
||||
|
||||
- PDO_MySQL:
|
||||
. Fixed bug #77944 (Wrong meta pdo_type for bigint on LLP64). (cmb)
|
||||
|
||||
- Reflection:
|
||||
. Fixed bug #75186 (Inconsistent reflection of Closure:::__invoke()). (Nikita)
|
||||
|
||||
- Session:
|
||||
. Fixed bug #77911 (Wrong warning for session.sid_bits_per_character). (cmb)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug #77945 (Segmentation fault when constructing SoapClient with
|
||||
WSDL_CACHE_BOTH). (Nikita)
|
||||
|
||||
- SPL:
|
||||
. Fixed bug #77024 (SplFileObject::__toString() may return array). (Craig
|
||||
Duncan)
|
||||
|
||||
- SQLite:
|
||||
. Fixed bug #77967 (Bypassing open_basedir restrictions via file uris). (Stas)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77931 (Warning for array_map mentions wrong type). (Nikita)
|
||||
. Fixed bug #78003 (strip_tags output change since PHP 7.3). (cmb)
|
||||
|
||||
02 May 2019, PHP 7.3.5
|
||||
|
||||
- Core:
|
||||
. Fixed bug #77903 (ArrayIterator stops iterating after offsetSet call).
|
||||
(Nikita)
|
||||
|
||||
- CLI:
|
||||
. Fixed bug #77794 (Incorrect Date header format in built-in server).
|
||||
(kelunik)
|
||||
|
||||
- EXIF
|
||||
. Fixed bug #77950 (Heap-buffer-overflow in _estrndup via exif_process_IFD_TAG).
|
||||
(CVE-2019-11036) (Stas)
|
||||
|
||||
- Interbase:
|
||||
. Fixed bug #72175 (Impossibility of creating multiple connections to
|
||||
Interbase with php 7.x). (Nikita)
|
||||
|
||||
- Intl:
|
||||
. Fixed bug #77895 (IntlDateFormatter::create fails in strict mode if $locale
|
||||
= null). (Nikita)
|
||||
|
||||
- LDAP:
|
||||
. Fixed bug #77869 (Core dump when using server controls) (mcmic)
|
||||
|
||||
- Mail
|
||||
. Fixed bug #77821 (Potential heap corruption in TSendMail()). (cmb)
|
||||
|
||||
- mbstring:
|
||||
. Implemented FR #72777 (Implement regex stack limits for mbregex functions).
|
||||
(Yasuo Ohgaki, Stas)
|
||||
|
||||
- MySQLi:
|
||||
. Fixed bug #77773 (Unbuffered queries leak memory - MySQLi / mysqlnd).
|
||||
(Nikita)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #77827 (preg_match does not ignore \r in regex flags). (requinix,
|
||||
cmb)
|
||||
|
||||
- PDO:
|
||||
. Fixed bug #77849 (Disable cloning of PDO handle/connection objects).
|
||||
(camporter)
|
||||
|
||||
- phpdbg:
|
||||
. Fixed bug #76801 (too many open files). (alekitto)
|
||||
. Fixed bug #77800 (phpdbg segfaults on listing some conditional breakpoints).
|
||||
(krakjoe)
|
||||
. Fixed bug #77805 (phpdbg build fails when readline is shared). (krakjoe)
|
||||
|
||||
- Reflection:
|
||||
. Fixed bug #77772 (ReflectionClass::getMethods(null) doesn't work). (Nikita)
|
||||
. Fixed bug #77882 (Different behavior: always calls destructor). (Nikita)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77793 (Segmentation fault in extract() when overwriting
|
||||
reference with itself). (Nikita)
|
||||
. Fixed bug #77844 (Crash due to null pointer in parse_ini_string with
|
||||
INI_SCANNER_TYPED). (Nikita)
|
||||
. Fixed bug #77853 (Inconsistent substr_compare behaviour with empty
|
||||
haystack). (Nikita)
|
||||
|
||||
04 Apr 2019, PHP 7.3.4
|
||||
|
||||
- Core:
|
||||
. Fixed bug #77738 (Nullptr deref in zend_compile_expr). (Laruence)
|
||||
. Fixed bug #77660 (Segmentation fault on break 2147483648). (Laruence)
|
||||
. Fixed bug #77652 (Anonymous classes can lose their interface information).
|
||||
(Nikita)
|
||||
. Fixed bug #77345 (Stack Overflow caused by circular reference in garbage
|
||||
collection). (Alexandru Patranescu, Nikita, Dmitry)
|
||||
. Fixed bug #76956 (Wrong value for 'syslog.filter' documented in php.ini).
|
||||
(cmb)
|
||||
|
||||
- Apache2Handler:
|
||||
. Fixed bug #77648 (BOM in sapi/apache2handler/php_functions.c). (cmb)
|
||||
|
||||
- Bcmath:
|
||||
. Fixed bug #77742 (bcpow() implementation related to gcc compiler
|
||||
optimization). (Nikita)
|
||||
|
||||
- CLI Server:
|
||||
. Fixed bug #77722 (Incorrect IP set to $_SERVER['REMOTE_ADDR'] on the
|
||||
localhost). (Nikita)
|
||||
|
||||
- COM:
|
||||
. Fixed bug #77578 (Crash when php unload). (cmb)
|
||||
|
||||
- EXIF:
|
||||
. Fixed bug #77753 (Heap-buffer-overflow in php_ifd_get32s). (CVE-2019-11034)
|
||||
(Stas)
|
||||
. Fixed bug #77831 (Heap-buffer-overflow in exif_iif_add_value).
|
||||
(CVE-2019-11035) (Stas)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #77677 (FPM fails to build on AIX due to missing WCOREDUMP).
|
||||
(Kevin Adler)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #77700 (Writing truecolor images as GIF ignores interlace flag).
|
||||
(cmb)
|
||||
|
||||
- MySQLi:
|
||||
. Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug #77743 (Incorrect pi node insertion for jmpznz with identical
|
||||
successors). (Nikita)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #76127 (preg_split does not raise an error on invalid UTF-8).
|
||||
(Nikita)
|
||||
|
||||
- Phar:
|
||||
. Fixed bug #77697 (Crash on Big_Endian platform). (Laruence)
|
||||
|
||||
- phpdbg:
|
||||
. Fixed bug #77767 (phpdbg break cmd aliases listed in help do not match
|
||||
actual aliases). (Miriam Lauter)
|
||||
|
||||
- sodium:
|
||||
. Fixed bug #77646 (sign_detached() strings not terminated). (Frank)
|
||||
|
||||
- SQLite3:
|
||||
. Added sqlite3.defensive INI directive. (BohwaZ)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #77664 (Segmentation fault when using undefined constant in
|
||||
custom wrapper). (Laruence)
|
||||
. Fixed bug #77669 (Crash in extract() when overwriting extracted array).
|
||||
(Nikita)
|
||||
. Fixed bug #76717 (var_export() does not create a parsable value for
|
||||
PHP_INT_MIN). (Nikita)
|
||||
. Fixed bug #77765 (FTP stream wrapper should set the directory as
|
||||
executable). (Vlad Temian)
|
||||
|
||||
07 Mar 2019, PHP 7.3.3
|
||||
|
||||
- Core:
|
||||
@@ -509,7 +699,7 @@ PHP NEWS
|
||||
- pgsql:
|
||||
. Added new error constants for pg_result_error(): PGSQL_DIAG_SCHEMA_NAME,
|
||||
PGSQL_DIAG_TABLE_NAME, PGSQL_DIAG_COLUMN_NAME, PGSQL_DIAG_DATATYPE_NAME,
|
||||
PGSQL_DIAG_CONSTRAINT_NAME and PGSQL_DIAG_SEVERITY_NONLOCALIZED. (Kalle)
|
||||
PGSQL_DIAG_CONSTRAINT_NAME and PGSQL_DIAG_SEVERITY_NONLOCALIZED. (Kalle)
|
||||
. Fixed bug #77047 (pg_convert has a broken regex for the 'TIME WITHOUT
|
||||
TIMEZONE' data type). (Andy Gajetzki)
|
||||
|
||||
|
||||
@@ -622,9 +622,11 @@ Curl:
|
||||
. CURL_SSLVERSION_MAX_TLSv1_2
|
||||
. CURL_SSLVERSION_MAX_TLSv1_3
|
||||
. CURL_SSLVERSION_TLSv1_3
|
||||
. CURL_VERSION_ALTSVC
|
||||
. CURL_VERSION_ASYNCHDNS
|
||||
. CURL_VERSION_BROTLI
|
||||
. CURL_VERSION_CONV
|
||||
. CURL_VERSION_CURLDEBUG
|
||||
. CURL_VERSION_DEBUG
|
||||
. CURL_VERSION_GSSAPI
|
||||
. CURL_VERSION_GSSNEGOTIATE
|
||||
@@ -634,6 +636,7 @@ Curl:
|
||||
. CURL_VERSION_MULTI_SSL
|
||||
. CURL_VERSION_NTLM
|
||||
. CURL_VERSION_NTLM_WB
|
||||
. CURL_VERSION_PSL
|
||||
. CURL_VERSION_SPNEGO
|
||||
. CURL_VERSION_SSPI
|
||||
. CURL_VERSION_TLSAUTH_SRP
|
||||
@@ -727,6 +730,10 @@ LDAP:
|
||||
. New INI to set syslog ident string which is prepended to every message. It
|
||||
is used only when error_log is set syslog.
|
||||
|
||||
- mbstring.regex_stack_limit
|
||||
. New INI directive (since 7.3.6) limiting stack depth of mbstring/oniguruma
|
||||
regular expressions.
|
||||
|
||||
========================================
|
||||
12. Windows Support
|
||||
========================================
|
||||
@@ -744,4 +751,3 @@ LDAP:
|
||||
|
||||
. The cyclic GC has been enhanced, which may result in considerable performance
|
||||
improvements.
|
||||
|
||||
@@ -46,7 +46,7 @@ elseif (PHP_OS == 'FreeBSD') {
|
||||
die('skip Not enough memory.');
|
||||
}
|
||||
} elseif (PHP_OS == "WINNT") {
|
||||
$s = trim(shell_exec("wmic OS get FreeVirtualMemory /Value 2>nil"));
|
||||
$s = trim(shell_exec("wmic OS get FreeVirtualMemory /Value 2>nul"));
|
||||
$freeMemory = explode('=', $s)[1]*1;
|
||||
|
||||
if ($freeMemory < 2.1*1024*1024) {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
Bug #77345 (Segmentation faults stack overflow in cyclic garbage collector) (Bug #77427)
|
||||
--INI--
|
||||
zend.enable_gc = 1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Node
|
||||
{
|
||||
/** @var Node */
|
||||
public $previous;
|
||||
/** @var Node */
|
||||
public $next;
|
||||
}
|
||||
|
||||
var_dump(gc_enabled());
|
||||
var_dump('start');
|
||||
|
||||
$firstNode = new Node();
|
||||
$firstNode->previous = $firstNode;
|
||||
$firstNode->next = $firstNode;
|
||||
|
||||
$circularDoublyLinkedList = $firstNode;
|
||||
|
||||
for ($i = 0; $i < 200000; $i++) {
|
||||
$currentNode = $circularDoublyLinkedList;
|
||||
$nextNode = $circularDoublyLinkedList->next;
|
||||
|
||||
$newNode = new Node();
|
||||
|
||||
$newNode->previous = $currentNode;
|
||||
$currentNode->next = $newNode;
|
||||
$newNode->next = $nextNode;
|
||||
$nextNode->previous = $newNode;
|
||||
|
||||
$circularDoublyLinkedList = $nextNode;
|
||||
}
|
||||
var_dump('end');
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
string(5) "start"
|
||||
string(3) "end"
|
||||
@@ -0,0 +1,48 @@
|
||||
--TEST--
|
||||
Bug #77345 (Segmentation faults stack overflow in cyclic garbage collector) (Bug #77427)
|
||||
--INI--
|
||||
zend.enable_gc = 1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Node
|
||||
{
|
||||
/** @var Node */
|
||||
public $previous;
|
||||
/** @var Node */
|
||||
public $next;
|
||||
}
|
||||
|
||||
var_dump(gc_enabled());
|
||||
var_dump('start');
|
||||
|
||||
function xxx() {
|
||||
$firstNode = new Node();
|
||||
$firstNode->previous = $firstNode;
|
||||
$firstNode->next = $firstNode;
|
||||
|
||||
$circularDoublyLinkedList = $firstNode;
|
||||
|
||||
for ($i = 0; $i < 300000; $i++) {
|
||||
$currentNode = $circularDoublyLinkedList;
|
||||
$nextNode = $circularDoublyLinkedList->next;
|
||||
|
||||
$newNode = new Node();
|
||||
|
||||
$newNode->previous = $currentNode;
|
||||
$currentNode->next = $newNode;
|
||||
$newNode->next = $nextNode;
|
||||
$nextNode->previous = $newNode;
|
||||
|
||||
$circularDoublyLinkedList = $nextNode;
|
||||
}
|
||||
}
|
||||
|
||||
xxx();
|
||||
gc_collect_cycles();
|
||||
|
||||
var_dump('end');
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
string(5) "start"
|
||||
string(3) "end"
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
return [
|
||||
'I' => function() {
|
||||
return new class implements I {};
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #77652: Anonymous classes can lose their interface information
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
interface I {}
|
||||
require __DIR__ . '/bug77652.inc';
|
||||
$data = require __DIR__ . '/bug77652.inc';
|
||||
print_r(class_implements($data['I']()));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Array
|
||||
(
|
||||
[I] => I
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Bug #77660 (Segmentation fault on break 2147483648)
|
||||
--SKIPIF--
|
||||
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
for(;;) break 2147483648;
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot 'break' 2147483648 levels in %sbug77660.php on line %d
|
||||
@@ -0,0 +1,8 @@
|
||||
--TEST--
|
||||
Bug #77738 (Nullptr deref in zend_compile_expr)
|
||||
--FILE--
|
||||
<?php
|
||||
__COMPILER_HALT_OFFSET__;
|
||||
; // <- important
|
||||
--EXPECTF--
|
||||
Warning: Use of undefined constant __COMPILER_HALT_OFFSET__ - assumed '__COMPILER_HALT_OFFSET__' %sbug77738.php on line %d
|
||||
@@ -0,0 +1,7 @@
|
||||
--TEST--
|
||||
Bug #77993 (Wrong parse error for invalid hex literal on Windows)
|
||||
--FILE--
|
||||
<?php
|
||||
0xg10;
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected 'xg10' (T_STRING) in %s on line %d
|
||||
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Calling exception getters when properties hold references
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyException extends Exception {
|
||||
public function __construct(&$refMsg, &$refCode, &$refFile, &$refLine) {
|
||||
$this->message =& $refMsg;
|
||||
$this->code =& $refCode;
|
||||
$this->file =& $refFile;
|
||||
$this->line =& $refLine;
|
||||
}
|
||||
}
|
||||
|
||||
$refMsg = "foo";
|
||||
$refCode = 0;
|
||||
$refFile = "foobar";
|
||||
$refLine = 42;
|
||||
$ex = new MyException($refMsg, $refCode, $refFile, $refLine);
|
||||
var_dump($ex->getMessage());
|
||||
var_dump($ex->getCode());
|
||||
var_dump($ex->getFile());
|
||||
var_dump($ex->getLine());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(3) "foo"
|
||||
int(0)
|
||||
string(6) "foobar"
|
||||
int(42)
|
||||
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Perform a packed to hash insert when the iterator is at the end of the array
|
||||
--FILE--
|
||||
|
||||
<?php
|
||||
$a = [];
|
||||
$a[1] = 1;
|
||||
foreach ($a as $k => &$v) {
|
||||
var_dump($v);
|
||||
if ($k == 1) $a[4] = 4;
|
||||
if ($k == 4) $a[2] = 2;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(4)
|
||||
int(2)
|
||||
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug object gc not working in shutdown
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set('memory_limit', '2M');
|
||||
register_shutdown_function(function () {
|
||||
for ($n = 1000 * 1000; $n--;) {
|
||||
new stdClass;
|
||||
}
|
||||
echo "OK\n";
|
||||
});
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
||||
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
The parent class is not necessarily the class of the prototype
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
function test(): B {}
|
||||
}
|
||||
class B extends A {}
|
||||
class C extends B {
|
||||
function test(): parent {}
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
#ifndef ZEND_H
|
||||
#define ZEND_H
|
||||
|
||||
#define ZEND_VERSION "3.3.3"
|
||||
#define ZEND_VERSION "3.3.6"
|
||||
|
||||
#define ZEND_ENGINE_3
|
||||
|
||||
|
||||
+22
-12
@@ -2051,13 +2051,13 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
|
||||
}
|
||||
|
||||
name_len = strlen(module->name);
|
||||
lcname = zend_string_alloc(name_len, 1);
|
||||
lcname = zend_string_alloc(name_len, module->type == MODULE_PERSISTENT);
|
||||
zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len);
|
||||
|
||||
lcname = zend_new_interned_string(lcname);
|
||||
if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) {
|
||||
zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
|
||||
zend_string_release_ex(lcname, 1);
|
||||
zend_string_release(lcname);
|
||||
return NULL;
|
||||
}
|
||||
module = module_ptr;
|
||||
@@ -2065,14 +2065,14 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
|
||||
|
||||
if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) {
|
||||
zend_hash_del(&module_registry, lcname);
|
||||
zend_string_release_ex(lcname, 1);
|
||||
zend_string_release(lcname);
|
||||
EG(current_module) = NULL;
|
||||
zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EG(current_module) = NULL;
|
||||
zend_string_release_ex(lcname, 1);
|
||||
zend_string_release(lcname);
|
||||
return module;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -2279,14 +2279,14 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
lowercase_name = zend_string_tolower_ex(internal_function->function_name, 1);
|
||||
lowercase_name = zend_string_tolower_ex(internal_function->function_name, type == MODULE_PERSISTENT);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name);
|
||||
reg_function = malloc(sizeof(zend_internal_function));
|
||||
memcpy(reg_function, &function, sizeof(zend_internal_function));
|
||||
if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) {
|
||||
unload=1;
|
||||
free(reg_function);
|
||||
zend_string_release_ex(lowercase_name, 1);
|
||||
zend_string_release(lowercase_name);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2378,7 +2378,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
|
||||
}
|
||||
ptr++;
|
||||
count++;
|
||||
zend_string_release_ex(lowercase_name, 1);
|
||||
zend_string_release(lowercase_name);
|
||||
}
|
||||
if (unload) { /* before unloading, display all remaining bad function in the module */
|
||||
if (scope) {
|
||||
@@ -2724,10 +2724,10 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
|
||||
class_entry->info.internal.module = EG(current_module);
|
||||
|
||||
if (class_entry->info.internal.builtin_functions) {
|
||||
zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT);
|
||||
zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, EG(current_module)->type);
|
||||
}
|
||||
|
||||
lowercase_name = zend_string_tolower_ex(orig_class_entry->name, 1);
|
||||
lowercase_name = zend_string_tolower_ex(orig_class_entry->name, EG(current_module)->type == MODULE_PERSISTENT);
|
||||
lowercase_name = zend_new_interned_string(lowercase_name);
|
||||
zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry);
|
||||
zend_string_release_ex(lowercase_name, 1);
|
||||
@@ -2786,6 +2786,11 @@ ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zen
|
||||
{
|
||||
zend_string *lcname;
|
||||
|
||||
/* TODO: Move this out of here in 7.4. */
|
||||
if (persistent && EG(current_module) && EG(current_module)->type == MODULE_TEMPORARY) {
|
||||
persistent = 0;
|
||||
}
|
||||
|
||||
if (name[0] == '\\') {
|
||||
lcname = zend_string_alloc(name_len-1, persistent);
|
||||
zend_str_tolower_copy(ZSTR_VAL(lcname), name+1, name_len-1);
|
||||
@@ -3696,6 +3701,11 @@ static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */
|
||||
return Z_STR_P(zv);
|
||||
}
|
||||
|
||||
static zend_always_inline zend_bool is_persistent_class(zend_class_entry *ce) {
|
||||
return (ce->type & ZEND_INTERNAL_CLASS)
|
||||
&& ce->info.internal.module->type == MODULE_PERSISTENT;
|
||||
}
|
||||
|
||||
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
|
||||
{
|
||||
zend_property_info *property_info, *property_info_ptr;
|
||||
@@ -3761,10 +3771,10 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
|
||||
if (access_type & ZEND_ACC_PUBLIC) {
|
||||
property_info->name = zend_string_copy(name);
|
||||
} else if (access_type & ZEND_ACC_PRIVATE) {
|
||||
property_info->name = zend_mangle_property_name(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
|
||||
property_info->name = zend_mangle_property_name(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(name), ZSTR_LEN(name), is_persistent_class(ce));
|
||||
} else {
|
||||
ZEND_ASSERT(access_type & ZEND_ACC_PROTECTED);
|
||||
property_info->name = zend_mangle_property_name("*", 1, ZSTR_VAL(name), ZSTR_LEN(name), ce->type & ZEND_INTERNAL_CLASS);
|
||||
property_info->name = zend_mangle_property_name("*", 1, ZSTR_VAL(name), ZSTR_LEN(name), is_persistent_class(ce));
|
||||
}
|
||||
|
||||
property_info->name = zend_new_interned_string(property_info->name);
|
||||
@@ -3779,7 +3789,7 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
|
||||
|
||||
ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type) /* {{{ */
|
||||
{
|
||||
zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
|
||||
zend_string *key = zend_string_init(name, name_length, is_persistent_class(ce));
|
||||
int ret = zend_declare_property_ex(ce, key, property, access_type, NULL);
|
||||
zend_string_release(key);
|
||||
return ret;
|
||||
|
||||
+30
-8
@@ -4528,7 +4528,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
|
||||
zend_ast *depth_ast = ast->child[0];
|
||||
|
||||
zend_op *opline;
|
||||
int depth;
|
||||
zend_long depth;
|
||||
|
||||
ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE);
|
||||
|
||||
@@ -4555,7 +4555,7 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
|
||||
ast->kind == ZEND_AST_BREAK ? "break" : "continue");
|
||||
} else {
|
||||
if (!zend_handle_loops_and_finally_ex(depth, NULL)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s",
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' " ZEND_LONG_FMT " level%s",
|
||||
ast->kind == ZEND_AST_BREAK ? "break" : "continue",
|
||||
depth, depth == 1 ? "" : "s");
|
||||
}
|
||||
@@ -4572,12 +4572,12 @@ void zend_compile_break_continue(zend_ast *ast) /* {{{ */
|
||||
if (depth == 1) {
|
||||
zend_error(E_WARNING,
|
||||
"\"continue\" targeting switch is equivalent to \"break\". " \
|
||||
"Did you mean to use \"continue %d\"?",
|
||||
"Did you mean to use \"continue " ZEND_LONG_FMT "\"?",
|
||||
depth + 1);
|
||||
} else {
|
||||
zend_error(E_WARNING,
|
||||
"\"continue %d\" targeting switch is equivalent to \"break %d\". " \
|
||||
"Did you mean to use \"continue %d\"?",
|
||||
"\"continue " ZEND_LONG_FMT "\" targeting switch is equivalent to \"break " ZEND_LONG_FMT "\". " \
|
||||
"Did you mean to use \"continue " ZEND_LONG_FMT "\"?",
|
||||
depth, depth, depth + 1);
|
||||
}
|
||||
}
|
||||
@@ -6440,10 +6440,32 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
|
||||
if (!zend_hash_exists(CG(class_table), lcname)) {
|
||||
zend_hash_add_ptr(CG(class_table), lcname, ce);
|
||||
} else {
|
||||
/* this anonymous class has been included */
|
||||
/* This anonymous class has been included, reuse the existing definition.
|
||||
* NB: This behavior is buggy, and this should always result in a separate
|
||||
* class declaration. However, until the problem of RTD key collisions is
|
||||
* solved, this gives a behavior close to what is expected. */
|
||||
zval zv;
|
||||
ZVAL_PTR(&zv, ce);
|
||||
destroy_zend_class(&zv);
|
||||
ce = zend_hash_find_ptr(CG(class_table), lcname);
|
||||
|
||||
/* Manually replicate emission of necessary inheritance opcodes here. We cannot
|
||||
* reuse the general code, as we only want to emit the opcodes, without modifying
|
||||
* the reused class definition. */
|
||||
if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
|
||||
zend_emit_op(NULL, ZEND_BIND_TRAITS, &declare_node, NULL);
|
||||
}
|
||||
if (implements_ast) {
|
||||
zend_ast_list *iface_list = zend_ast_get_list(implements_ast);
|
||||
uint32_t i;
|
||||
for (i = 0; i < iface_list->children; i++) {
|
||||
opline = zend_emit_op(NULL, ZEND_ADD_INTERFACE, &declare_node, NULL);
|
||||
opline->op2_type = IS_CONST;
|
||||
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
|
||||
zend_resolve_class_name_ast(iface_list->child[i]));
|
||||
}
|
||||
zend_emit_op(NULL, ZEND_VERIFY_ABSTRACT_CLASS, &declare_node, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -7739,11 +7761,11 @@ void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
|
||||
if (zend_string_equals_literal(resolved_name, "__COMPILER_HALT_OFFSET__") || (name_ast->attr != ZEND_NAME_RELATIVE && zend_string_equals_literal(orig_name, "__COMPILER_HALT_OFFSET__"))) {
|
||||
zend_ast *last = CG(ast);
|
||||
|
||||
while (last->kind == ZEND_AST_STMT_LIST) {
|
||||
while (last && last->kind == ZEND_AST_STMT_LIST) {
|
||||
zend_ast_list *list = zend_ast_get_list(last);
|
||||
last = list->child[list->children-1];
|
||||
}
|
||||
if (last->kind == ZEND_AST_HALT_COMPILER) {
|
||||
if (last && last->kind == ZEND_AST_HALT_COMPILER) {
|
||||
result->op_type = IS_CONST;
|
||||
ZVAL_LONG(&result->u.constant, Z_LVAL_P(zend_ast_get_zval(last->child[0])));
|
||||
zend_string_release_ex(resolved_name, 0);
|
||||
|
||||
+24
-12
@@ -400,11 +400,13 @@ ZEND_METHOD(error_exception, __construct)
|
||||
Get the file in which the exception occurred */
|
||||
ZEND_METHOD(exception, getFile)
|
||||
{
|
||||
zval rv;
|
||||
zval *prop, rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_FILE));
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_FILE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -412,11 +414,13 @@ ZEND_METHOD(exception, getFile)
|
||||
Get the line in which the exception occurred */
|
||||
ZEND_METHOD(exception, getLine)
|
||||
{
|
||||
zval rv;
|
||||
zval *prop, rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_LINE));
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_LINE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -424,11 +428,13 @@ ZEND_METHOD(exception, getLine)
|
||||
Get the exception message */
|
||||
ZEND_METHOD(exception, getMessage)
|
||||
{
|
||||
zval rv;
|
||||
zval *prop, rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_MESSAGE));
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_MESSAGE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -436,11 +442,13 @@ ZEND_METHOD(exception, getMessage)
|
||||
Get the exception code */
|
||||
ZEND_METHOD(exception, getCode)
|
||||
{
|
||||
zval rv;
|
||||
zval *prop, rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_CODE));
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_CODE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -448,11 +456,13 @@ ZEND_METHOD(exception, getCode)
|
||||
Get the stack trace for the location in which the exception occurred */
|
||||
ZEND_METHOD(exception, getTrace)
|
||||
{
|
||||
zval rv;
|
||||
zval *prop, rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_TRACE));
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_TRACE);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -460,11 +470,13 @@ ZEND_METHOD(exception, getTrace)
|
||||
Get the exception severity */
|
||||
ZEND_METHOD(error_exception, getSeverity)
|
||||
{
|
||||
zval rv;
|
||||
zval *prop, rv;
|
||||
|
||||
DEFAULT_0_PARAMS;
|
||||
|
||||
ZVAL_COPY(return_value, GET_PROPERTY(getThis(), ZEND_STR_SEVERITY));
|
||||
prop = GET_PROPERTY(getThis(), ZEND_STR_SEVERITY);
|
||||
ZVAL_DEREF(prop);
|
||||
ZVAL_COPY(return_value, prop);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
+241
-89
@@ -48,7 +48,7 @@
|
||||
* gc_scan_roots will be called, and each root will be called with
|
||||
* gc_scan(root->ref)
|
||||
*
|
||||
* gc_scan checkes the colors of possible members.
|
||||
* gc_scan checks the colors of possible members.
|
||||
*
|
||||
* If the node is marked as grey and the refcount > 0
|
||||
* gc_scan_black will be called on that node to scan it's subgraph.
|
||||
@@ -245,6 +245,73 @@ static zend_gc_globals gc_globals;
|
||||
# define GC_TRACE(str)
|
||||
#endif
|
||||
|
||||
|
||||
#define GC_STACK_SEGMENT_SIZE (((4096 - ZEND_MM_OVERHEAD) / sizeof(void*)) - 2)
|
||||
|
||||
typedef struct _gc_stack gc_stack;
|
||||
|
||||
struct _gc_stack {
|
||||
gc_stack *prev;
|
||||
gc_stack *next;
|
||||
zend_refcounted *data[GC_STACK_SEGMENT_SIZE];
|
||||
};
|
||||
|
||||
#define GC_STACK_DCL(init) \
|
||||
gc_stack *_stack = init; \
|
||||
size_t _top = 0;
|
||||
|
||||
#define GC_STACK_PUSH(ref) \
|
||||
gc_stack_push(&_stack, &_top, ref);
|
||||
|
||||
#define GC_STACK_POP() \
|
||||
gc_stack_pop(&_stack, &_top)
|
||||
|
||||
static zend_never_inline gc_stack* gc_stack_next(gc_stack *stack)
|
||||
{
|
||||
if (UNEXPECTED(!stack->next)) {
|
||||
gc_stack *segment = emalloc(sizeof(gc_stack));
|
||||
segment->prev = stack;
|
||||
segment->next = NULL;
|
||||
stack->next = segment;
|
||||
}
|
||||
return stack->next;
|
||||
}
|
||||
|
||||
static zend_always_inline void gc_stack_push(gc_stack **stack, size_t *top, zend_refcounted *ref)
|
||||
{
|
||||
if (UNEXPECTED(*top == GC_STACK_SEGMENT_SIZE)) {
|
||||
(*stack) = gc_stack_next(*stack);
|
||||
(*top) = 0;
|
||||
}
|
||||
(*stack)->data[(*top)++] = ref;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_refcounted* gc_stack_pop(gc_stack **stack, size_t *top)
|
||||
{
|
||||
if (UNEXPECTED((*top) == 0)) {
|
||||
if (!(*stack)->prev) {
|
||||
return NULL;
|
||||
} else {
|
||||
(*stack) = (*stack)->prev;
|
||||
(*top) = GC_STACK_SEGMENT_SIZE - 1;
|
||||
return (*stack)->data[GC_STACK_SEGMENT_SIZE - 1];
|
||||
}
|
||||
} else {
|
||||
return (*stack)->data[--(*top)];
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_stack_free(gc_stack *stack)
|
||||
{
|
||||
gc_stack *p = stack->next;
|
||||
|
||||
while (p) {
|
||||
stack = p->next;
|
||||
efree(p);
|
||||
p = stack;
|
||||
}
|
||||
}
|
||||
|
||||
static zend_always_inline uint32_t gc_compress(uint32_t idx)
|
||||
{
|
||||
return idx % GC_MAX_UNCOMPRESSED;
|
||||
@@ -606,16 +673,14 @@ ZEND_API void ZEND_FASTCALL gc_remove_from_buffer(zend_refcounted *ref)
|
||||
gc_remove_from_roots(root);
|
||||
}
|
||||
|
||||
static void gc_scan_black(zend_refcounted *ref)
|
||||
static void gc_scan_black(zend_refcounted *ref, gc_stack *stack)
|
||||
{
|
||||
HashTable *ht;
|
||||
HashTable *ht = NULL;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
tail_call:
|
||||
ht = NULL;
|
||||
GC_REF_SET_BLACK(ref);
|
||||
|
||||
if (GC_TYPE(ref) == IS_OBJECT) {
|
||||
zend_object_get_gc_t get_gc;
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
@@ -630,9 +695,9 @@ tail_call:
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) return;
|
||||
if (!n) goto next;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
if (zv == end) return;
|
||||
if (zv == end) goto next;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
@@ -640,7 +705,8 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
gc_scan_black(ref);
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
}
|
||||
zv++;
|
||||
@@ -649,33 +715,35 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
if ((zend_array*)ref != &EG(symbol_table)) {
|
||||
ht = (zend_array*)ref;
|
||||
} else {
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
return;
|
||||
goto next;
|
||||
} else {
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) return;
|
||||
if (!ht->nNumUsed) goto next;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -687,7 +755,7 @@ tail_call:
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
break;
|
||||
}
|
||||
if (p == end) return;
|
||||
if (p == end) goto next;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -698,7 +766,8 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
gc_scan_black(ref);
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
@@ -710,28 +779,33 @@ tail_call:
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
if (ref) {
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark_grey(zend_refcounted *ref)
|
||||
static void gc_mark_grey(zend_refcounted *ref, gc_stack *stack)
|
||||
{
|
||||
HashTable *ht;
|
||||
HashTable *ht = NULL;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
tail_call:
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
ht = NULL;
|
||||
do {
|
||||
GC_BENCH_INC(zval_marked_grey);
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
|
||||
if (GC_TYPE(ref) == IS_OBJECT) {
|
||||
zend_object_get_gc_t get_gc;
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
|
||||
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) &&
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
int n;
|
||||
zval *zv, *end;
|
||||
zval tmp;
|
||||
@@ -740,31 +814,38 @@ tail_call:
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) return;
|
||||
if (!n) goto next;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
if (zv == end) return;
|
||||
if (zv == end) goto next;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
gc_mark_grey(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
}
|
||||
zv++;
|
||||
}
|
||||
if (EXPECTED(!ht)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
goto tail_call;
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
continue;
|
||||
}
|
||||
goto next;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
if (((zend_array*)ref) == &EG(symbol_table)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
return;
|
||||
goto next;
|
||||
} else {
|
||||
ht = (zend_array*)ref;
|
||||
}
|
||||
@@ -772,14 +853,17 @@ tail_call:
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_DELREF(ref);
|
||||
goto tail_call;
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return;
|
||||
goto next;
|
||||
} else {
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) return;
|
||||
if (!ht->nNumUsed) goto next;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -791,7 +875,7 @@ tail_call:
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
break;
|
||||
}
|
||||
if (p == end) return;
|
||||
if (p == end) goto next;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -801,7 +885,10 @@ tail_call:
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
gc_mark_grey(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
@@ -811,8 +898,14 @@ tail_call:
|
||||
}
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_DELREF(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_GREY);
|
||||
continue;
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
} while (ref);
|
||||
}
|
||||
|
||||
/* Two-Finger compaction algorithm */
|
||||
@@ -852,7 +945,7 @@ static void gc_compact(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_mark_roots(void)
|
||||
static void gc_mark_roots(gc_stack *stack)
|
||||
{
|
||||
gc_root_buffer *current, *last;
|
||||
|
||||
@@ -863,31 +956,41 @@ static void gc_mark_roots(void)
|
||||
while (current != last) {
|
||||
if (GC_IS_ROOT(current->ref)) {
|
||||
if (GC_REF_CHECK_COLOR(current->ref, GC_PURPLE)) {
|
||||
gc_mark_grey(current->ref);
|
||||
GC_REF_SET_COLOR(current->ref, GC_GREY);
|
||||
gc_mark_grey(current->ref, stack);
|
||||
}
|
||||
}
|
||||
current++;
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_scan(zend_refcounted *ref)
|
||||
static void gc_scan(zend_refcounted *ref, gc_stack *stack)
|
||||
{
|
||||
HashTable *ht;
|
||||
HashTable *ht = NULL;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
tail_call:
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
if (GC_REFCOUNT(ref) > 0) {
|
||||
gc_scan_black(ref);
|
||||
if (!GC_REF_CHECK_COLOR(ref, GC_BLACK)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
if (UNEXPECTED(!_stack->next)) {
|
||||
gc_stack_next(_stack);
|
||||
}
|
||||
/* Split stack and reuse the tail */
|
||||
_stack->next->prev = NULL;
|
||||
gc_scan_black(ref, _stack->next);
|
||||
_stack->next->prev = _stack;
|
||||
}
|
||||
} else {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
if (GC_TYPE(ref) == IS_OBJECT) {
|
||||
zend_object_get_gc_t get_gc;
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
|
||||
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) &&
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
int n;
|
||||
zval *zv, *end;
|
||||
zval tmp;
|
||||
@@ -896,43 +999,53 @@ tail_call:
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) return;
|
||||
if (!n) goto next;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
if (zv == end) return;
|
||||
if (zv == end) goto next;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
gc_scan(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
}
|
||||
zv++;
|
||||
}
|
||||
if (EXPECTED(!ht)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
goto tail_call;
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
goto tail_call;
|
||||
}
|
||||
goto next;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
if ((zend_array*)ref == &EG(symbol_table)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
return;
|
||||
goto next;
|
||||
} else {
|
||||
ht = (zend_array*)ref;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_REFERENCE) {
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
goto tail_call;
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
return;
|
||||
goto next;
|
||||
} else {
|
||||
return;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) return;
|
||||
if (!ht->nNumUsed) goto next;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -944,7 +1057,7 @@ tail_call:
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
break;
|
||||
}
|
||||
if (p == end) return;
|
||||
if (p == end) goto next;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -953,7 +1066,10 @@ tail_call:
|
||||
}
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
gc_scan(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
@@ -962,19 +1078,31 @@ tail_call:
|
||||
zv = Z_INDIRECT_P(zv);
|
||||
}
|
||||
ref = Z_COUNTED_P(zv);
|
||||
goto tail_call;
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(ref, GC_WHITE);
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
if (ref) {
|
||||
goto tail_call;
|
||||
}
|
||||
}
|
||||
|
||||
static void gc_scan_roots(void)
|
||||
static void gc_scan_roots(gc_stack *stack)
|
||||
{
|
||||
gc_root_buffer *current = GC_IDX2PTR(GC_FIRST_ROOT);
|
||||
gc_root_buffer *last = GC_IDX2PTR(GC_G(first_unused));
|
||||
|
||||
while (current != last) {
|
||||
if (GC_IS_ROOT(current->ref)) {
|
||||
gc_scan(current->ref);
|
||||
if (GC_REF_CHECK_COLOR(current->ref, GC_GREY)) {
|
||||
GC_REF_SET_COLOR(current->ref, GC_WHITE);
|
||||
gc_scan(current->ref, stack);
|
||||
}
|
||||
}
|
||||
current++;
|
||||
}
|
||||
@@ -1005,18 +1133,15 @@ static void gc_add_garbage(zend_refcounted *ref)
|
||||
GC_G(num_roots)++;
|
||||
}
|
||||
|
||||
static int gc_collect_white(zend_refcounted *ref, uint32_t *flags)
|
||||
static int gc_collect_white(zend_refcounted *ref, uint32_t *flags, gc_stack *stack)
|
||||
{
|
||||
int count = 0;
|
||||
HashTable *ht;
|
||||
HashTable *ht = NULL;
|
||||
Bucket *p, *end;
|
||||
zval *zv;
|
||||
GC_STACK_DCL(stack);
|
||||
|
||||
tail_call:
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
ht = NULL;
|
||||
GC_REF_SET_BLACK(ref);
|
||||
|
||||
do {
|
||||
/* don't count references for compatibility ??? */
|
||||
if (GC_TYPE(ref) != IS_REFERENCE) {
|
||||
count++;
|
||||
@@ -1027,7 +1152,7 @@ tail_call:
|
||||
zend_object *obj = (zend_object*)ref;
|
||||
|
||||
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) &&
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
(get_gc = obj->handlers->get_gc) != NULL)) {
|
||||
int n;
|
||||
zval *zv, *end;
|
||||
zval tmp;
|
||||
@@ -1037,28 +1162,31 @@ tail_call:
|
||||
gc_add_garbage(ref);
|
||||
}
|
||||
if (obj->handlers->dtor_obj &&
|
||||
((obj->handlers->dtor_obj != zend_objects_destroy_object) ||
|
||||
(obj->ce->destructor != NULL))) {
|
||||
((obj->handlers->dtor_obj != zend_objects_destroy_object) ||
|
||||
(obj->ce->destructor != NULL))) {
|
||||
*flags |= GC_HAS_DESTRUCTORS;
|
||||
}
|
||||
ZVAL_OBJ(&tmp, obj);
|
||||
ht = get_gc(&tmp, &zv, &n);
|
||||
end = zv + n;
|
||||
if (EXPECTED(!ht)) {
|
||||
if (!n) return count;
|
||||
if (!n) goto next;
|
||||
while (!Z_REFCOUNTED_P(--end)) {
|
||||
/* count non-refcounted for compatibility ??? */
|
||||
if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
}
|
||||
if (zv == end) return count;
|
||||
if (zv == end) goto next;
|
||||
}
|
||||
}
|
||||
while (zv != end) {
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
count += gc_collect_white(ref, flags);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
/* count non-refcounted for compatibility ??? */
|
||||
} else if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
@@ -1068,10 +1196,14 @@ tail_call:
|
||||
if (EXPECTED(!ht)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
goto tail_call;
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
continue;
|
||||
}
|
||||
goto next;
|
||||
}
|
||||
} else {
|
||||
return count;
|
||||
goto next;
|
||||
}
|
||||
} else if (GC_TYPE(ref) == IS_ARRAY) {
|
||||
/* optimization: color is GC_BLACK (0) */
|
||||
@@ -1083,14 +1215,17 @@ tail_call:
|
||||
if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
|
||||
ref = Z_COUNTED(((zend_reference*)ref)->val);
|
||||
GC_ADDREF(ref);
|
||||
goto tail_call;
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
goto next;
|
||||
} else {
|
||||
return count;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!ht->nNumUsed) return count;
|
||||
if (!ht->nNumUsed) goto next;
|
||||
p = ht->arData;
|
||||
end = p + ht->nNumUsed;
|
||||
while (1) {
|
||||
@@ -1106,7 +1241,7 @@ tail_call:
|
||||
if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
}
|
||||
if (p == end) return count;
|
||||
if (p == end) goto next;
|
||||
}
|
||||
while (p != end) {
|
||||
zv = &p->val;
|
||||
@@ -1116,7 +1251,10 @@ tail_call:
|
||||
if (Z_REFCOUNTED_P(zv)) {
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
count += gc_collect_white(ref, flags);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
GC_STACK_PUSH(ref);
|
||||
}
|
||||
/* count non-refcounted for compatibility ??? */
|
||||
} else if (Z_TYPE_P(zv) != IS_UNDEF) {
|
||||
count++;
|
||||
@@ -1129,12 +1267,19 @@ tail_call:
|
||||
}
|
||||
ref = Z_COUNTED_P(zv);
|
||||
GC_ADDREF(ref);
|
||||
goto tail_call;
|
||||
}
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
GC_REF_SET_BLACK(ref);
|
||||
continue;
|
||||
}
|
||||
|
||||
next:
|
||||
ref = GC_STACK_POP();
|
||||
} while (ref);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int gc_collect_roots(uint32_t *flags)
|
||||
static int gc_collect_roots(uint32_t *flags, gc_stack *stack)
|
||||
{
|
||||
uint32_t idx, end;
|
||||
zend_refcounted *ref;
|
||||
@@ -1165,7 +1310,8 @@ static int gc_collect_roots(uint32_t *flags)
|
||||
ZEND_ASSERT(GC_IS_ROOT(ref));
|
||||
current->ref = GC_MAKE_GARBAGE(ref);
|
||||
if (GC_REF_CHECK_COLOR(ref, GC_WHITE)) {
|
||||
count += gc_collect_white(ref, flags);
|
||||
GC_REF_SET_BLACK(ref);
|
||||
count += gc_collect_white(ref, flags, stack);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
@@ -1280,6 +1426,10 @@ ZEND_API int zend_gc_collect_cycles(void)
|
||||
zend_refcounted *p;
|
||||
uint32_t gc_flags = 0;
|
||||
uint32_t idx, end;
|
||||
gc_stack stack;
|
||||
|
||||
stack.prev = NULL;
|
||||
stack.next = NULL;
|
||||
|
||||
if (GC_G(gc_active)) {
|
||||
return 0;
|
||||
@@ -1290,12 +1440,14 @@ ZEND_API int zend_gc_collect_cycles(void)
|
||||
GC_G(gc_active) = 1;
|
||||
|
||||
GC_TRACE("Marking roots");
|
||||
gc_mark_roots();
|
||||
gc_mark_roots(&stack);
|
||||
GC_TRACE("Scanning roots");
|
||||
gc_scan_roots();
|
||||
gc_scan_roots(&stack);
|
||||
|
||||
GC_TRACE("Collecting roots");
|
||||
count = gc_collect_roots(&gc_flags);
|
||||
count = gc_collect_roots(&gc_flags, &stack);
|
||||
|
||||
gc_stack_free(&stack);
|
||||
|
||||
if (!GC_G(num_roots)) {
|
||||
/* nothing to free */
|
||||
|
||||
@@ -123,8 +123,7 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
/* always free the CV's, in the symtable are only not-free'd IS_INDIRECT's */
|
||||
zend_free_compiled_variables(execute_data);
|
||||
|
||||
if ((EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) &&
|
||||
EXPECTED(GC_TYPE(Z_OBJ(execute_data->This)) == IS_OBJECT)) {
|
||||
if (EX_CALL_INFO() & ZEND_CALL_RELEASE_THIS) {
|
||||
OBJ_RELEASE(Z_OBJ(execute_data->This));
|
||||
}
|
||||
|
||||
@@ -144,8 +143,7 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
}
|
||||
|
||||
/* Free closure object */
|
||||
if ((EX_CALL_INFO() & ZEND_CALL_CLOSURE) &&
|
||||
EXPECTED(GC_TYPE(ZEND_CLOSURE_OBJECT(EX(func))) == IS_OBJECT)) {
|
||||
if (EX_CALL_INFO() & ZEND_CALL_CLOSURE) {
|
||||
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -233,8 +233,9 @@ struct _zend_executor_globals {
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
};
|
||||
|
||||
#define EG_FLAGS_INITIAL 0x00
|
||||
#define EG_FLAGS_IN_SHUTDOWN 0x01
|
||||
#define EG_FLAGS_INITIAL (0)
|
||||
#define EG_FLAGS_IN_SHUTDOWN (1<<0)
|
||||
#define EG_FLAGS_OBJECT_STORE_NO_REUSE (1<<1)
|
||||
|
||||
struct _zend_ini_scanner_globals {
|
||||
zend_file_handle *yy_in;
|
||||
|
||||
+27
-52
@@ -64,7 +64,7 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin
|
||||
zend_output_debug_string(1, "%s(%d) : ht=%p is inconsistent", file, line, ht);
|
||||
break;
|
||||
}
|
||||
zend_bailout();
|
||||
ZEND_ASSERT(0);
|
||||
}
|
||||
#define IS_CONSISTENT(a) _zend_is_inconsistent(a, __FILE__, __LINE__);
|
||||
#define SET_INCONSISTENT(n) do { \
|
||||
@@ -377,10 +377,8 @@ ZEND_API uint32_t zend_array_count(HashTable *ht)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline HashPosition _zend_hash_get_first_pos(const HashTable *ht)
|
||||
static zend_always_inline HashPosition _zend_hash_get_valid_pos(const HashTable *ht, HashPosition pos)
|
||||
{
|
||||
HashPosition pos = 0;
|
||||
|
||||
while (pos < ht->nNumUsed && Z_ISUNDEF(ht->arData[pos].val)) {
|
||||
pos++;
|
||||
}
|
||||
@@ -389,12 +387,7 @@ static zend_always_inline HashPosition _zend_hash_get_first_pos(const HashTable
|
||||
|
||||
static zend_always_inline HashPosition _zend_hash_get_current_pos(const HashTable *ht)
|
||||
{
|
||||
HashPosition pos = ht->nInternalPointer;
|
||||
|
||||
if (pos == 0) {
|
||||
pos = _zend_hash_get_first_pos(ht);
|
||||
}
|
||||
return pos;
|
||||
return _zend_hash_get_valid_pos(ht, ht->nInternalPointer);
|
||||
}
|
||||
|
||||
ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos(const HashTable *ht)
|
||||
@@ -488,6 +481,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
|
||||
|
||||
if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
|
||||
&& EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) {
|
||||
ZEND_ASSERT(HT_ITERATORS_COUNT(iter->ht) != 0);
|
||||
HT_DEC_ITERATORS_COUNT(iter->ht);
|
||||
}
|
||||
iter->ht = NULL;
|
||||
@@ -1077,6 +1071,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
|
||||
p++;
|
||||
} while (++i < ht->nNumUsed);
|
||||
} else {
|
||||
uint32_t old_num_used = ht->nNumUsed;
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) {
|
||||
uint32_t j = i;
|
||||
@@ -1133,6 +1128,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
|
||||
HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(i);
|
||||
p++;
|
||||
} while (++i < ht->nNumUsed);
|
||||
|
||||
/* Migrate pointer to one past the end of the array to the new one past the end, so that
|
||||
* newly inserted elements are picked up correctly. */
|
||||
if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
|
||||
_zend_hash_iterators_update(ht, old_num_used, ht->nNumUsed);
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -1928,7 +1929,8 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
target->pDestructor = ZVAL_PTR_DTOR;
|
||||
|
||||
if (source->nNumOfElements == 0) {
|
||||
HT_FLAGS(target) = (HT_FLAGS(source) & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED)) | HASH_FLAG_STATIC_KEYS;
|
||||
uint32_t mask = HASH_FLAG_MASK & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED);
|
||||
HT_FLAGS(target) = (HT_FLAGS(source) & mask) | HASH_FLAG_STATIC_KEYS;
|
||||
target->nTableMask = HT_MIN_MASK;
|
||||
target->nNumUsed = 0;
|
||||
target->nNumOfElements = 0;
|
||||
@@ -1936,7 +1938,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
target->nInternalPointer = 0;
|
||||
HT_SET_DATA_ADDR(target, &uninitialized_bucket);
|
||||
} else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) {
|
||||
HT_FLAGS(target) = HT_FLAGS(source);
|
||||
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
|
||||
target->nTableMask = source->nTableMask;
|
||||
target->nNumUsed = source->nNumUsed;
|
||||
target->nNumOfElements = source->nNumOfElements;
|
||||
@@ -1945,7 +1947,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
target->nInternalPointer = source->nInternalPointer;
|
||||
memcpy(HT_GET_DATA_ADDR(target), HT_GET_DATA_ADDR(source), HT_USED_SIZE(source));
|
||||
} else if (HT_FLAGS(source) & HASH_FLAG_PACKED) {
|
||||
HT_FLAGS(target) = HT_FLAGS(source);
|
||||
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
|
||||
target->nTableMask = HT_MIN_MASK;
|
||||
target->nNumUsed = source->nNumUsed;
|
||||
target->nNumOfElements = source->nNumOfElements;
|
||||
@@ -1963,7 +1965,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
|
||||
zend_array_dup_packed_elements(source, target, 1);
|
||||
}
|
||||
} else {
|
||||
HT_FLAGS(target) = HT_FLAGS(source);
|
||||
HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
|
||||
target->nTableMask = source->nTableMask;
|
||||
target->nNextFreeElement = source->nNextFreeElement;
|
||||
target->nInternalPointer =
|
||||
@@ -2189,7 +2191,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, H
|
||||
{
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
|
||||
*pos = _zend_hash_get_first_pos(ht);
|
||||
*pos = _zend_hash_get_valid_pos(ht, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2217,19 +2219,13 @@ ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, Has
|
||||
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
|
||||
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
*pos = idx;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
idx++;
|
||||
if (idx >= ht->nNumUsed) {
|
||||
@@ -2272,17 +2268,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPositi
|
||||
/* This function should be made binary safe */
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return HASH_KEY_NON_EXISTENT;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
*str_index = p->key;
|
||||
@@ -2297,20 +2288,14 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zen
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ZVAL_NULL(key);
|
||||
} else {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
ZVAL_NULL(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
ZVAL_STR_COPY(key, p->key);
|
||||
@@ -2322,17 +2307,12 @@ ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *h
|
||||
|
||||
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return HASH_KEY_NON_EXISTENT;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
if (p->key) {
|
||||
return HASH_KEY_IS_STRING;
|
||||
@@ -2346,17 +2326,12 @@ ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, Hash
|
||||
|
||||
ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
|
||||
{
|
||||
uint32_t idx = *pos;
|
||||
uint32_t idx;
|
||||
Bucket *p;
|
||||
|
||||
IS_CONSISTENT(ht);
|
||||
idx = _zend_hash_get_valid_pos(ht, *pos);
|
||||
if (idx < ht->nNumUsed) {
|
||||
if (idx == 0) {
|
||||
idx = _zend_hash_get_first_pos(ht);
|
||||
if (idx >= ht->nNumUsed) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
p = ht->arData + idx;
|
||||
return &p->val;
|
||||
} else {
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
#define HASH_FLAG_HAS_EMPTY_IND (1<<5)
|
||||
#define HASH_FLAG_ALLOW_COW_VIOLATION (1<<6)
|
||||
|
||||
/* Only the low byte are real flags */
|
||||
#define HASH_FLAG_MASK 0xff
|
||||
|
||||
#define HT_FLAGS(ht) (ht)->u.flags
|
||||
|
||||
#define HT_IS_PACKED(ht) \
|
||||
|
||||
@@ -208,8 +208,8 @@ static int zend_do_perform_type_hint_check(const zend_function *fe, zend_arg_inf
|
||||
fe_class_name = ZEND_TYPE_NAME(fe_arg_info->type);
|
||||
class_name = ZSTR_VAL(fe_class_name);
|
||||
class_name_len = ZSTR_LEN(fe_class_name);
|
||||
if (class_name_len == sizeof("parent")-1 && !strcasecmp(class_name, "parent") && proto->common.scope) {
|
||||
fe_class_name = zend_string_copy(proto->common.scope->name);
|
||||
if (class_name_len == sizeof("parent")-1 && !strcasecmp(class_name, "parent") && fe->common.scope && fe->common.scope->parent) {
|
||||
fe_class_name = zend_string_copy(fe->common.scope->parent->name);
|
||||
} else if (class_name_len == sizeof("self")-1 && !strcasecmp(class_name, "self") && fe->common.scope) {
|
||||
fe_class_name = zend_string_copy(fe->common.scope->name);
|
||||
} else {
|
||||
|
||||
+18
-16
@@ -46,6 +46,22 @@ int ini_parse(void);
|
||||
|
||||
#define ZEND_SYSTEM_INI CG(ini_parser_unbuffered_errors)
|
||||
|
||||
static int get_int_val(zval *op) {
|
||||
switch (Z_TYPE_P(op)) {
|
||||
case IS_LONG:
|
||||
return Z_LVAL_P(op);
|
||||
case IS_DOUBLE:
|
||||
return (int)Z_DVAL_P(op);
|
||||
case IS_STRING:
|
||||
{
|
||||
int val = atoi(Z_STRVAL_P(op));
|
||||
zend_string_free(Z_STR_P(op));
|
||||
return val;
|
||||
}
|
||||
EMPTY_SWITCH_DEFAULT_CASE()
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ zend_ini_do_op()
|
||||
*/
|
||||
static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
|
||||
@@ -55,22 +71,8 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
|
||||
int str_len;
|
||||
char str_result[MAX_LENGTH_OF_LONG+1];
|
||||
|
||||
if (IS_LONG == Z_TYPE_P(op1)) {
|
||||
i_op1 = Z_LVAL_P(op1);
|
||||
} else {
|
||||
i_op1 = atoi(Z_STRVAL_P(op1));
|
||||
zend_string_free(Z_STR_P(op1));
|
||||
}
|
||||
if (op2) {
|
||||
if (IS_LONG == Z_TYPE_P(op2)) {
|
||||
i_op2 = Z_LVAL_P(op2);
|
||||
} else {
|
||||
i_op2 = atoi(Z_STRVAL_P(op2));
|
||||
zend_string_free(Z_STR_P(op2));
|
||||
}
|
||||
} else {
|
||||
i_op2 = 0;
|
||||
}
|
||||
i_op1 = get_int_val(op1);
|
||||
i_op2 = op2 ? get_int_val(op2) : 0;
|
||||
|
||||
switch (type) {
|
||||
case '|':
|
||||
|
||||
+221
-220
File diff suppressed because it is too large.
Load diff
@@ -1781,7 +1781,8 @@ NEWLINE ("\r"|"\n"|"\r\n")
|
||||
char *end;
|
||||
if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
|
||||
errno = 0;
|
||||
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, 0));
|
||||
/* base must be passed explicitly for correct parse error on Windows */
|
||||
ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, &end, yytext[0] == '0' ? 8 : 10));
|
||||
/* This isn't an assert, we need to ensure 019 isn't valid octal
|
||||
* Because the lexing itself doesn't do that for us
|
||||
*/
|
||||
|
||||
+12
-6
@@ -41,6 +41,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_destroy(zend_objects_store *objec
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_store *objects)
|
||||
{
|
||||
EG(flags) |= EG_FLAGS_OBJECT_STORE_NO_REUSE;
|
||||
if (objects->top > 1) {
|
||||
uint32_t i;
|
||||
for (i = 1; i < objects->top; i++) {
|
||||
@@ -131,10 +132,10 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
|
||||
{
|
||||
int handle;
|
||||
|
||||
/* When in shutdown sequesnce - do not reuse previously freed handles, to make sure
|
||||
/* When in shutdown sequence - do not reuse previously freed handles, to make sure
|
||||
* the dtors for newly created objects are called in zend_objects_store_call_destructors() loop
|
||||
*/
|
||||
if (!(EG(flags) & EG_FLAGS_IN_SHUTDOWN) && EG(objects_store).free_list_head != -1) {
|
||||
if (EG(objects_store).free_list_head != -1 && EXPECTED(!(EG(flags) & EG_FLAGS_OBJECT_STORE_NO_REUSE))) {
|
||||
handle = EG(objects_store).free_list_head;
|
||||
EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
|
||||
} else {
|
||||
@@ -152,14 +153,17 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_put(zend_object *object)
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ */
|
||||
{
|
||||
ZEND_ASSERT(GC_REFCOUNT(object) == 0);
|
||||
|
||||
/* GC might have released this object already. */
|
||||
if (UNEXPECTED(GC_TYPE(object) == IS_NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure we hold a reference count during the destructor call
|
||||
otherwise, when the destructor ends the storage might be freed
|
||||
when the refcount reaches 0 a second time
|
||||
*/
|
||||
ZEND_ASSERT(EG(objects_store).object_buckets != NULL);
|
||||
ZEND_ASSERT(IS_OBJ_VALID(EG(objects_store).object_buckets[object->handle]));
|
||||
ZEND_ASSERT(GC_REFCOUNT(object) == 0);
|
||||
|
||||
if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) {
|
||||
GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED);
|
||||
|
||||
@@ -176,6 +180,8 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ *
|
||||
uint32_t handle = object->handle;
|
||||
void *ptr;
|
||||
|
||||
ZEND_ASSERT(EG(objects_store).object_buckets != NULL);
|
||||
ZEND_ASSERT(IS_OBJ_VALID(EG(objects_store).object_buckets[object->handle]));
|
||||
EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object);
|
||||
if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) {
|
||||
GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED);
|
||||
|
||||
@@ -440,12 +440,8 @@ char *alloca();
|
||||
#define MAX(a, b) (((a)>(b))?(a):(b))
|
||||
#define MIN(a, b) (((a)<(b))?(a):(b))
|
||||
|
||||
/* x86 instructions BT, SHL, SHR don't require masking */
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) || defined(ZEND_WIN32)
|
||||
# define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) / (sizeof((bits)[0])*8)] >> (bit)) & 1)
|
||||
#else
|
||||
# define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
|
||||
#endif
|
||||
#define ZEND_BIT_TEST(bits, bit) \
|
||||
(((bits)[(bit) / (sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
|
||||
|
||||
/* We always define a function, even if there's a macro or expression we could
|
||||
* alias, so that using it in contexts where we can't make function calls
|
||||
|
||||
+15
-1
@@ -234,7 +234,13 @@ static zend_string* ZEND_FASTCALL zend_new_interned_string_request(zend_string *
|
||||
}
|
||||
|
||||
/* Create a short living interned, freed after the request. */
|
||||
ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT));
|
||||
#if ZEND_RC_DEBUG
|
||||
if (zend_rc_debug) {
|
||||
/* PHP shouldn't create persistent interned string during request,
|
||||
* but at least dl() may do this */
|
||||
ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT));
|
||||
}
|
||||
#endif
|
||||
if (GC_REFCOUNT(str) > 1) {
|
||||
zend_ulong h = ZSTR_H(str);
|
||||
zend_string_delref(str);
|
||||
@@ -257,6 +263,7 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_permanent(const char
|
||||
return ret;
|
||||
}
|
||||
|
||||
ZEND_ASSERT(permanent);
|
||||
ret = zend_string_init(str, size, permanent);
|
||||
ZSTR_H(ret) = h;
|
||||
return zend_add_interned_string(ret, &interned_strings_permanent, IS_STR_PERMANENT);
|
||||
@@ -278,6 +285,13 @@ static zend_string* ZEND_FASTCALL zend_string_init_interned_request(const char *
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if ZEND_RC_DEBUG
|
||||
if (zend_rc_debug) {
|
||||
/* PHP shouldn't create persistent interned string during request,
|
||||
* but at least dl() may do this */
|
||||
ZEND_ASSERT(!permanent);
|
||||
}
|
||||
#endif
|
||||
ret = zend_string_init(str, size, permanent);
|
||||
ZSTR_H(ret) = h;
|
||||
|
||||
|
||||
+11
-9
@@ -1757,7 +1757,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
|
||||
gen_null_handler($f);
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,"default:\n");
|
||||
out($f,"default: ZEND_NULL_LABEL:\n");
|
||||
out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
|
||||
out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
|
||||
break;
|
||||
@@ -2069,7 +2069,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
||||
$prolog = $m[1];
|
||||
out($f,$prolog."if (UNEXPECTED(execute_data == NULL)) {\n");
|
||||
out($f,$prolog."\tstatic const void * const labels[] = {\n");
|
||||
gen_labels($f, $spec, ZEND_VM_KIND_GOTO, $prolog."\t\t", $specs);
|
||||
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
|
||||
out($f,$prolog."\t};\n");
|
||||
out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
|
||||
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
|
||||
@@ -2184,7 +2184,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
||||
out($f,$prolog.$executor_name."_ex(NULL);\n");
|
||||
} else {
|
||||
out($f,$prolog."static const void * const labels[] = {\n");
|
||||
gen_labels($f, $spec, ZEND_VM_KIND_CALL, $prolog."\t", $specs, $switch_labels);
|
||||
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
|
||||
out($f,$prolog."};\n");
|
||||
out($f,$prolog."static const uint32_t specs[] = {\n");
|
||||
gen_specs($f, $prolog."\t", $specs);
|
||||
@@ -2528,13 +2528,15 @@ function gen_vm($def, $skel) {
|
||||
|
||||
// Search for opcode handlers those are used by other opcode handlers
|
||||
foreach ($opcodes as $dsc) {
|
||||
if (preg_match("/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", $dsc["code"], $m)) {
|
||||
$op = $m[1];
|
||||
if (!isset($opnames[$op])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
|
||||
if (preg_match_all("/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m", $dsc["code"], $mm, PREG_SET_ORDER)) {
|
||||
foreach ($mm as $m) {
|
||||
$op = $m[1];
|
||||
if (!isset($opnames[$op])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$op' is not defined.\n");
|
||||
}
|
||||
$code = $opnames[$op];
|
||||
$opcodes[$code]['use'] = 1;
|
||||
}
|
||||
$code = $opnames[$op];
|
||||
$opcodes[$code]['use'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-8
@@ -833,15 +833,11 @@ dnl from object_var in build-dir.
|
||||
dnl
|
||||
AC_DEFUN([PHP_SHARED_MODULE],[
|
||||
install_modules="install-modules"
|
||||
suffix=la
|
||||
|
||||
case $host_alias in
|
||||
*aix*[)]
|
||||
suffix=so
|
||||
link_cmd='$(LIBTOOL) --mode=link ifelse($4,,[$(CC)],[$(CXX)]) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -Wl,-G -o '$3'/$1.la -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $($2) $(translit($1,a-z_-,A-Z__)_SHARED_LIBADD) && mv -f '$3'/.libs/$1.so '$3'/$1.so'
|
||||
;;
|
||||
*[)]
|
||||
suffix=la
|
||||
link_cmd='$(LIBTOOL) --mode=link ifelse($4,,[$(CC)],[$(CXX)]) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) -o [$]@ -export-dynamic -avoid-version -prefer-pic -module -rpath $(phplibdir) $(EXTRA_LDFLAGS) $($2) $(translit($1,a-z_-,A-Z__)_SHARED_LIBADD)'
|
||||
additional_flags="-Wl,-G"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -856,7 +852,7 @@ AC_DEFUN([PHP_SHARED_MODULE],[
|
||||
\$(LIBTOOL) --mode=install cp $3/$1.$suffix \$(phplibdir)
|
||||
|
||||
$3/$1.$suffix: \$($2) \$(translit($1,a-z_-,A-Z__)_SHARED_DEPENDENCIES)
|
||||
$link_cmd
|
||||
\$(LIBTOOL) --mode=link ifelse($4,,[\$(CC)],[\$(CXX)]) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) $additional_flags -o [\$]@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$($2) \$(translit($1,a-z_-,A-Z__)_SHARED_LIBADD)
|
||||
|
||||
EOF
|
||||
])
|
||||
@@ -972,7 +968,7 @@ dnl ---------------------------------------------- Shared module
|
||||
dnl ---------------------------------------------- CLI static module
|
||||
[PHP_]translit($1,a-z_-,A-Z__)[_SHARED]=no
|
||||
case "$PHP_SAPI" in
|
||||
cgi|embed[)]
|
||||
cgi|embed|phpdbg[)]
|
||||
PHP_ADD_SOURCES($ext_dir,$2,$ac_extra,)
|
||||
EXT_STATIC="$EXT_STATIC $1;$ext_dir"
|
||||
;;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
|
||||
set SDK_REMOTE=https://github.com/OSTC/php-sdk-binary-tools.git
|
||||
set SDK_REMOTE=https://github.com/Microsoft/php-sdk-binary-tools.git
|
||||
set SDK_BRANCH=%PHP_BUILD_SDK_BRANCH%
|
||||
set SDK_RUNNER=%PHP_BUILD_CACHE_SDK_DIR%\phpsdk-%PHP_BUILD_CRT%-%PLATFORM%.bat
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ set PDO_MYSQL_TEST_USER=%MYSQL_TEST_USER%
|
||||
set PDO_MYSQL_TEST_PASS=%MYSQL_PWD%
|
||||
set PDO_MYSQL_TEST_HOST=%MYSQL_TEST_HOST%
|
||||
set PDO_MYSQL_TEST_PORT=%MYSQL_TEST_PORT%
|
||||
set PDO_MYSQL_TEST_DSN=mysql:host=%PDO_MYSQL_TEST_HOST% port=%PDO_MYSQL_TEST_PORT% dbname=test user=%PDO_MYSQL_TEST_USER% password=%MYSQL_PW%
|
||||
set PDO_MYSQL_TEST_DSN=mysql:host=%PDO_MYSQL_TEST_HOST%;port=%PDO_MYSQL_TEST_PORT%;dbname=test;user=%PDO_MYSQL_TEST_USER%;password=%MYSQL_PW%
|
||||
"C:\Program Files\MySql\MySQL Server 5.7\bin\mysql.exe" --user=%MYSQL_TEST_USER% -e "CREATE DATABASE IF NOT EXISTS test"
|
||||
if %errorlevel% neq 0 exit /b 3
|
||||
|
||||
@@ -58,7 +58,7 @@ rem set OPENSSL_CONF=
|
||||
rem set SSLEAY_CONF=
|
||||
|
||||
rem prepare for Opcache
|
||||
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enabled=1 -d opcache.enable_cli=1
|
||||
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enable=1 -d opcache.enable_cli=1
|
||||
|
||||
rem prepare for enchant
|
||||
mkdir c:\enchant_plugins
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ int zend_sprintf(char *buffer, const char *format, ...);
|
||||
|
||||
PHP_MAJOR_VERSION=7
|
||||
PHP_MINOR_VERSION=3
|
||||
PHP_RELEASE_VERSION=3
|
||||
PHP_RELEASE_VERSION=6
|
||||
PHP_EXTRA_VERSION=""
|
||||
PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION"
|
||||
PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION`
|
||||
|
||||
@@ -54,12 +54,19 @@ bc_num2long (num)
|
||||
/* Extract the int value, ignore the fraction. */
|
||||
val = 0;
|
||||
nptr = num->n_value;
|
||||
for (index=num->n_len; (index>0) && (val<=(LONG_MAX/BASE)); index--)
|
||||
val = val*BASE + *nptr++;
|
||||
for (index = num->n_len; index > 0; index--) {
|
||||
char n = *nptr++;
|
||||
|
||||
/* Check for overflow. If overflow, return zero. */
|
||||
if (index>0) val = 0;
|
||||
if (val < 0) val = 0;
|
||||
if (val > LONG_MAX/BASE) {
|
||||
return 0;
|
||||
}
|
||||
val *= BASE;
|
||||
|
||||
if (val > LONG_MAX - n) {
|
||||
return 0;
|
||||
}
|
||||
val += n;
|
||||
}
|
||||
|
||||
/* Return the value. */
|
||||
if (num->n_sign == PLUS)
|
||||
|
||||
@@ -222,8 +222,8 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa
|
||||
/* Type-library stuff */
|
||||
void php_com_typelibrary_dtor(zval *pDest)
|
||||
{
|
||||
ITypeLib **Lib = (ITypeLib**)Z_PTR_P(pDest);
|
||||
ITypeLib_Release(*Lib);
|
||||
ITypeLib *Lib = (ITypeLib*)Z_PTR_P(pDest);
|
||||
ITypeLib_Release(Lib);
|
||||
}
|
||||
|
||||
PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #77578 (Crash when php unload)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
// To actually be able to verify the crash during shutdown on Windows, we have
|
||||
// to execute a PHP subprocess, and check its exit status.
|
||||
$php = PHP_BINARY;
|
||||
$ini = php_ini_loaded_file();
|
||||
$iniopt = $ini ? "-c $ini" : '';
|
||||
$command = "$php $iniopt -d com.autoregister_typelib=1 -r \"new COM('WbemScripting.SWbemLocator');\"";
|
||||
exec($command, $output, $status);
|
||||
var_dump($output, $status);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
array(0) {
|
||||
}
|
||||
int(0)
|
||||
===DONE===
|
||||
+12
-2
@@ -1130,6 +1130,7 @@ PHP_MINIT_FUNCTION(curl)
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071306 /* Available since 7.19.6 */
|
||||
REGISTER_CURL_CONSTANT(CURL_VERSION_CURLDEBUG);
|
||||
REGISTER_CURL_CONSTANT(CURLOPT_SSH_KNOWNHOSTS);
|
||||
#endif
|
||||
|
||||
@@ -1334,6 +1335,7 @@ PHP_MINIT_FUNCTION(curl)
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x072f00 /* Available since 7.47.0 */
|
||||
REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_2TLS);
|
||||
REGISTER_CURL_CONSTANT(CURL_VERSION_PSL);
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x073000 /* Available since 7.48.0 */
|
||||
@@ -1452,6 +1454,10 @@ PHP_MINIT_FUNCTION(curl)
|
||||
REGISTER_CURL_CONSTANT(CURLOPT_TLS13_CIPHERS);
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x074001 /* Available since 7.64.1 */
|
||||
REGISTER_CURL_CONSTANT(CURL_VERSION_ALTSVC);
|
||||
#endif
|
||||
|
||||
REGISTER_CURL_CONSTANT(CURLOPT_SAFE_UPLOAD);
|
||||
|
||||
#ifdef PHP_CURL_NEED_OPENSSL_TSL
|
||||
@@ -3429,8 +3435,12 @@ PHP_FUNCTION(curl_error)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
ch->err.str[CURL_ERROR_SIZE] = 0;
|
||||
RETURN_STRING(ch->err.str);
|
||||
if (ch->err.no) {
|
||||
ch->err.str[CURL_ERROR_SIZE] = 0;
|
||||
RETURN_STRING(ch->err.str);
|
||||
} else {
|
||||
RETURN_EMPTY_STRING();
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
+1
-5
@@ -420,6 +420,7 @@ void _php_curl_multi_close(zend_resource *rsrc) /* {{{ */
|
||||
curl_multi_cleanup(mh->multi);
|
||||
zend_llist_clean(&mh->easyh);
|
||||
if (mh->handlers->server_push) {
|
||||
zval_ptr_dtor(&mh->handlers->server_push->func_name);
|
||||
efree(mh->handlers->server_push);
|
||||
}
|
||||
if (mh->handlers) {
|
||||
@@ -577,11 +578,6 @@ static int _php_curl_multi_setopt(php_curlm *mh, zend_long option, zval *zvalue,
|
||||
|
||||
ZVAL_COPY(&mh->handlers->server_push->func_name, zvalue);
|
||||
mh->handlers->server_push->method = PHP_CURL_USER;
|
||||
if (!Z_ISUNDEF(mh->handlers->server_push->func_name)) {
|
||||
zval_ptr_dtor(&mh->handlers->server_push->func_name);
|
||||
mh->handlers->server_push->fci_cache = empty_fcall_info_cache;
|
||||
|
||||
}
|
||||
error = curl_multi_setopt(mh->multi, option, _php_server_push_callback);
|
||||
if (error != CURLM_OK) {
|
||||
return 0;
|
||||
|
||||
@@ -17,6 +17,8 @@ const IGNORED_CONSTANTS = [
|
||||
'CURLOPT_PROGRESSDATA'
|
||||
];
|
||||
|
||||
const CONSTANTS_REGEX_PATTERN = '~^CURL(?:OPT|_VERSION)_[A-Z0-9_]+$~';
|
||||
|
||||
$curlConstants = getCurlConstants();
|
||||
$sourceConstants = getSourceConstants();
|
||||
|
||||
@@ -157,13 +159,8 @@ function getCurlConstants() : array
|
||||
$deprecated = $match[3] ?? null;
|
||||
$removed = $match[4] ?? null;
|
||||
|
||||
if (strpos($name, 'CURLOPT_') !== 0) {
|
||||
// not a CURLOPT_* constant
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($name, IGNORED_CONSTANTS)) {
|
||||
// purposefully ignored constant
|
||||
if (in_array($name, IGNORED_CONSTANTS, true) || !preg_match(CONSTANTS_REGEX_PATTERN, $name)) {
|
||||
// not a wanted constant
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -197,8 +194,8 @@ function getSourceConstants() : array
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strpos($name, 'CURLOPT_') !== 0) {
|
||||
// not a CURLOPT_* constant
|
||||
if (!preg_match(CONSTANTS_REGEX_PATTERN, $name)) {
|
||||
// not a wanted constant
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
--TEST--
|
||||
Request #72189 (Add missing CURL_VERSION_* constants)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
|
||||
include 'skipif.inc';
|
||||
|
||||
$version = curl_version();
|
||||
|
||||
if ($version['version_number'] < 0x071306) {
|
||||
exit('skip: test works only with curl >= 7.19.6');
|
||||
}
|
||||
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$version = curl_version();
|
||||
|
||||
$bitfields = [
|
||||
CURL_VERSION_ASYNCHDNS,
|
||||
CURL_VERSION_CONV,
|
||||
CURL_VERSION_CURLDEBUG,
|
||||
CURL_VERSION_DEBUG,
|
||||
CURL_VERSION_GSSNEGOTIATE,
|
||||
CURL_VERSION_IDN,
|
||||
CURL_VERSION_IPV6,
|
||||
CURL_VERSION_KERBEROS4,
|
||||
CURL_VERSION_LARGEFILE,
|
||||
CURL_VERSION_LIBZ,
|
||||
CURL_VERSION_NTLM,
|
||||
CURL_VERSION_SPNEGO,
|
||||
CURL_VERSION_SSL,
|
||||
CURL_VERSION_SSPI,
|
||||
];
|
||||
|
||||
$matchesCount = 0;
|
||||
|
||||
foreach ($bitfields as $feature) {
|
||||
if ($version['features'] & $feature) {
|
||||
++$matchesCount;
|
||||
}
|
||||
}
|
||||
|
||||
var_dump($matchesCount > 0);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -0,0 +1,77 @@
|
||||
--TEST--
|
||||
Bug #77535 (Invalid callback, h2 server push)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include 'skipif.inc';
|
||||
if (getenv("SKIP_ONLINE_TESTS")) {
|
||||
die("skip online test");
|
||||
}
|
||||
$curl_version = curl_version();
|
||||
if ($curl_version['version_number'] < 0x073d00) {
|
||||
exit("skip: test may crash with curl < 7.61.0");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class MyHttpClient
|
||||
{
|
||||
private $mh;
|
||||
private $curl;
|
||||
|
||||
public function sendRequest()
|
||||
{
|
||||
if (false === $this->mh = curl_multi_init()) {
|
||||
throw new \RuntimeException('Unable to create a new cURL multi handle');
|
||||
}
|
||||
|
||||
$this->addServerPushCallback();
|
||||
|
||||
$this->curl = curl_init();
|
||||
curl_setopt($this->curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
curl_setopt($this->curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
curl_setopt($this->curl, CURLOPT_HEADER, false);
|
||||
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, false);
|
||||
curl_setopt($this->curl, CURLOPT_FAILONERROR, false);
|
||||
curl_setopt($this->curl, CURLOPT_URL, 'https://http2.golang.org/serverpush');
|
||||
curl_setopt($this->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, function ($ch, $data) {
|
||||
return \strlen($data);
|
||||
});
|
||||
curl_setopt($this->curl, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
|
||||
return \strlen($data);
|
||||
});
|
||||
curl_multi_add_handle($this->mh, $this->curl);
|
||||
|
||||
$stillRunning = null;
|
||||
while (true) {
|
||||
do {
|
||||
$mrc = curl_multi_exec($this->mh, $stillRunning);
|
||||
} while (CURLM_CALL_MULTI_PERFORM === $mrc);
|
||||
|
||||
$info = curl_multi_info_read($this->mh);
|
||||
while (false !== $info && $info['msg'] == CURLMSG_DONE) {
|
||||
if (CURLMSG_DONE !== $info['msg']) {
|
||||
continue;
|
||||
}
|
||||
die("Start handle request.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addServerPushCallback(): void
|
||||
{
|
||||
|
||||
$callback = static function () {
|
||||
return CURL_PUSH_OK;
|
||||
};
|
||||
|
||||
curl_multi_setopt($this->mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt($this->mh, CURLMOPT_PUSHFUNCTION, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
$buzz = new MyHttpClient();
|
||||
$buzz->sendRequest();
|
||||
--EXPECT--
|
||||
Start handle request.
|
||||
|
||||
+616
-599
File diff suppressed because it is too large.
Load diff
+37
-2
@@ -551,6 +551,7 @@ static const zend_function_entry date_funcs_period[] = {
|
||||
PHP_ME(DatePeriod, getStartDate, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DatePeriod, getEndDate, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DatePeriod, getDateInterval, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(DatePeriod, getRecurrences, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
@@ -4430,12 +4431,21 @@ PHP_FUNCTION(date_interval_create_from_date_string)
|
||||
Z_PARAM_STR(time_str)
|
||||
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
|
||||
|
||||
php_date_instantiate(date_ce_interval, return_value);
|
||||
|
||||
time = timelib_strtotime(ZSTR_VAL(time_str), ZSTR_LEN(time_str), &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
|
||||
|
||||
if (err->error_count > 0) {
|
||||
php_error_docref(NULL, E_WARNING, "Unknown or bad format (%s) at position %d (%c): %s", ZSTR_VAL(time_str),
|
||||
err->error_messages[0].position, err->error_messages[0].character ? err->error_messages[0].character : ' ', err->error_messages[0].message);
|
||||
RETVAL_FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
php_date_instantiate(date_ce_interval, return_value);
|
||||
diobj = Z_PHPINTERVAL_P(return_value);
|
||||
diobj->diff = timelib_rel_time_clone(&time->relative);
|
||||
diobj->initialized = 1;
|
||||
|
||||
cleanup:
|
||||
timelib_time_dtor(time);
|
||||
timelib_error_container_dtor(err);
|
||||
}
|
||||
@@ -4629,6 +4639,10 @@ PHP_METHOD(DatePeriod, __construct)
|
||||
dpobj->end = clone;
|
||||
}
|
||||
}
|
||||
|
||||
if (dpobj->end == NULL && recurrences < 1) {
|
||||
php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences);
|
||||
}
|
||||
|
||||
/* options */
|
||||
dpobj->include_start_date = !(options & PHP_DATE_PERIOD_EXCLUDE_START_DATE);
|
||||
@@ -4721,6 +4735,27 @@ PHP_METHOD(DatePeriod, getDateInterval)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int DatePeriod::getRecurrences()
|
||||
Get recurrences.
|
||||
*/
|
||||
PHP_METHOD(DatePeriod, getRecurrences)
|
||||
{
|
||||
php_period_obj *dpobj;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
dpobj = Z_PHPPERIOD_P(getThis());
|
||||
|
||||
if (0 == dpobj->recurrences - dpobj->include_start_date) {
|
||||
return;
|
||||
}
|
||||
|
||||
RETURN_LONG(dpobj->recurrences - dpobj->include_start_date);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int check_id_allowed(char *id, zend_long what) /* {{{ */
|
||||
{
|
||||
if (what & PHP_DATE_TIMEZONE_GROUP_AFRICA && strncasecmp(id, "Africa/", 7) == 0) return 1;
|
||||
|
||||
@@ -111,6 +111,7 @@ PHP_METHOD(DatePeriod, __set_state);
|
||||
PHP_METHOD(DatePeriod, getStartDate);
|
||||
PHP_METHOD(DatePeriod, getEndDate);
|
||||
PHP_METHOD(DatePeriod, getDateInterval);
|
||||
PHP_METHOD(DatePeriod, getRecurrences);
|
||||
|
||||
/* Options and Configuration */
|
||||
PHP_FUNCTION(date_default_timezone_set);
|
||||
|
||||
@@ -8,6 +8,7 @@ $start = new DateTime('2000-01-01 00:00:00', new DateTimeZone('Europe/Berlin'));
|
||||
$end = new DateTime('2000-01-31 00:00:00', new DateTimeZone('UTC'));
|
||||
$interval = new DateInterval('P1D');
|
||||
$period = new DatePeriod($start, $interval, $end);
|
||||
$recurrences = 4;
|
||||
|
||||
var_dump($period->getStartDate()->format('Y-m-d H:i:s'));
|
||||
var_dump($period->getStartDate()->getTimeZone()->getName());
|
||||
@@ -16,6 +17,17 @@ var_dump($period->getEndDate()->format('Y-m-d H:i:s'));
|
||||
var_dump($period->getEndDate()->getTimeZone()->getName());
|
||||
|
||||
var_dump($period->getDateInterval()->format('%R%y-%m-%d-%h-%i-%s'));
|
||||
var_dump($period->getRecurrences());
|
||||
|
||||
$periodWithRecurrences = new DatePeriod($start, $interval, $recurrences);
|
||||
|
||||
var_dump($periodWithRecurrences->getRecurrences());
|
||||
var_dump($periodWithRecurrences->getEndDate());
|
||||
|
||||
$periodWithRecurrencesWithoutStart = new DatePeriod($start, $interval, $recurrences, DatePeriod::EXCLUDE_START_DATE);
|
||||
|
||||
var_dump($periodWithRecurrences->getRecurrences());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(19) "2000-01-01 00:00:00"
|
||||
@@ -23,3 +35,7 @@ string(13) "Europe/Berlin"
|
||||
string(19) "2000-01-31 00:00:00"
|
||||
string(3) "UTC"
|
||||
string(12) "+0-0-1-0-0-0"
|
||||
NULL
|
||||
int(4)
|
||||
NULL
|
||||
int(4)
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
DatePeriod: Test wrong recurrence parameter on __construct
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'), 0);
|
||||
} catch (Exception $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'),-1);
|
||||
} catch (Exception $exception) {
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
DatePeriod::__construct(): The recurrence count '0' is invalid. Needs to be > 0
|
||||
DatePeriod::__construct(): The recurrence count '-1' is invalid. Needs to be > 0
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Test date_interval_create_from_date_string() function : nonsense data
|
||||
--FILE--
|
||||
<?php
|
||||
$i = date_interval_create_from_date_string("foobar");
|
||||
var_dump($i);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: date_interval_create_from_date_string(): Unknown or bad format (foobar) at position 0 (f): The timezone could not be found in the database in %sdate_interval_create_from_date_string_broken.php on line 2
|
||||
bool(false)
|
||||
@@ -4,41 +4,9 @@ Test date_interval_create_from_date_string() function : null parameter
|
||||
Rodrigo Prado de Jesus <royopa [at] gmail [dot] com>
|
||||
--FILE--
|
||||
<?php
|
||||
$i = date_interval_create_from_date_string(null); //returns a empty object
|
||||
$i = date_interval_create_from_date_string(null);
|
||||
var_dump($i);
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(DateInterval)#%d (16) {
|
||||
["y"]=>
|
||||
int(0)
|
||||
["m"]=>
|
||||
int(0)
|
||||
["d"]=>
|
||||
int(0)
|
||||
["h"]=>
|
||||
int(0)
|
||||
["i"]=>
|
||||
int(0)
|
||||
["s"]=>
|
||||
int(0)
|
||||
["f"]=>
|
||||
float(0)
|
||||
["weekday"]=>
|
||||
int(0)
|
||||
["weekday_behavior"]=>
|
||||
int(0)
|
||||
["first_last_day_of"]=>
|
||||
int(0)
|
||||
["invert"]=>
|
||||
int(0)
|
||||
["days"]=>
|
||||
int(0)
|
||||
["special_type"]=>
|
||||
int(0)
|
||||
["special_amount"]=>
|
||||
int(0)
|
||||
["have_weekday_relative"]=>
|
||||
int(0)
|
||||
["have_special_relative"]=>
|
||||
int(0)
|
||||
}
|
||||
Warning: date_interval_create_from_date_string(): Unknown or bad format () at position 0 ( ): Empty string in %sdate_interval_create_from_date_string_nullparam.php on line 2
|
||||
bool(false)
|
||||
+35
-16
@@ -2037,10 +2037,10 @@ static int exif_file_sections_free(image_info_type *ImageInfo)
|
||||
/* {{{ exif_iif_add_value
|
||||
Add a value to image_info
|
||||
*/
|
||||
static void exif_iif_add_value(image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value, int motorola_intel)
|
||||
static void exif_iif_add_value(image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value, size_t value_len, int motorola_intel)
|
||||
{
|
||||
size_t idex;
|
||||
void *vptr;
|
||||
void *vptr, *vptr_end;
|
||||
image_info_value *info_value;
|
||||
image_info_data *info_data;
|
||||
image_info_data *list;
|
||||
@@ -2062,8 +2062,12 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
||||
|
||||
switch (format) {
|
||||
case TAG_FMT_STRING:
|
||||
if (length > value_len) {
|
||||
exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len);
|
||||
value = NULL;
|
||||
}
|
||||
if (value) {
|
||||
length = php_strnlen(value, length);
|
||||
length = (int)php_strnlen(value, length);
|
||||
info_value->s = estrndup(value, length);
|
||||
info_data->length = length;
|
||||
} else {
|
||||
@@ -2085,6 +2089,10 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
||||
if (!length)
|
||||
break;
|
||||
case TAG_FMT_UNDEFINED:
|
||||
if (length > value_len) {
|
||||
exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len);
|
||||
value = NULL;
|
||||
}
|
||||
if (value) {
|
||||
if (tag == TAG_MAKER_NOTE) {
|
||||
length = (int) php_strnlen(value, length);
|
||||
@@ -2115,7 +2123,12 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
||||
} else {
|
||||
info_value = &info_data->value;
|
||||
}
|
||||
vptr_end = (char *) value + value_len;
|
||||
for (idex=0,vptr=value; idex<(size_t)length; idex++,vptr=(char *) vptr + php_tiff_bytes_per_format[format]) {
|
||||
if ((char *) vptr_end - (char *) vptr < php_tiff_bytes_per_format[format]) {
|
||||
exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "Value too short");
|
||||
break;
|
||||
}
|
||||
if (length>1) {
|
||||
info_value = &info_data->value.list[idex];
|
||||
}
|
||||
@@ -2151,7 +2164,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
||||
php_error_docref(NULL, E_WARNING, "Found value of type single");
|
||||
#endif
|
||||
info_value->f = *(float *)value;
|
||||
|
||||
break;
|
||||
case TAG_FMT_DOUBLE:
|
||||
#ifdef EXIF_DEBUG
|
||||
php_error_docref(NULL, E_WARNING, "Found value of type double");
|
||||
@@ -2169,9 +2182,9 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
||||
/* {{{ exif_iif_add_tag
|
||||
Add a tag from IFD to image_info
|
||||
*/
|
||||
static void exif_iif_add_tag(image_info_type *image_info, int section_index, char *name, int tag, int format, size_t length, void* value)
|
||||
static void exif_iif_add_tag(image_info_type *image_info, int section_index, char *name, int tag, int format, size_t length, void* value, size_t value_len)
|
||||
{
|
||||
exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, image_info->motorola_intel);
|
||||
exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, value_len, image_info->motorola_intel);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -2592,7 +2605,7 @@ static void add_assoc_image_info(zval *value, int sub_array, image_info_type *im
|
||||
*/
|
||||
static void exif_process_COM (image_info_type *image_info, char *value, size_t length)
|
||||
{
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2);
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2, length-2);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -2607,17 +2620,17 @@ static void exif_process_CME (image_info_type *image_info, char *value, size_t l
|
||||
if (length>3) {
|
||||
switch(value[2]) {
|
||||
case 0:
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value);
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value, length);
|
||||
break;
|
||||
case 1:
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value);
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value, length);
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL, E_NOTICE, "Undefined JPEG2000 comment encoding");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, 0, NULL);
|
||||
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, 0, NULL, 0);
|
||||
php_error_docref(NULL, E_NOTICE, "JPEG2000 comment section too small");
|
||||
}
|
||||
}
|
||||
@@ -3188,6 +3201,10 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
|
||||
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
|
||||
return FALSE;
|
||||
}
|
||||
if ((dir_start - value_ptr) > value_len - (2+NumDirEntries*12)) {
|
||||
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 0x%04X > 0x%04X", (dir_start - value_ptr) + (2+NumDirEntries*12), value_len);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (de=0;de<NumDirEntries;de++) {
|
||||
if (!exif_process_IFD_TAG(ImageInfo, dir_start + 2 + 12 * de,
|
||||
@@ -3209,7 +3226,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
|
||||
static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
||||
{
|
||||
size_t length;
|
||||
int tag, format, components;
|
||||
unsigned int tag, format, components;
|
||||
char *value_ptr, tagname[64], cbuf[32], *outside=NULL;
|
||||
size_t byte_count, offset_val, fpos, fgot;
|
||||
int64_t byte_count_signed;
|
||||
@@ -3260,7 +3277,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
||||
offset_base is ImageInfo->file.list[sn].data-dir_offset
|
||||
dir_entry - offset_base is dir_offset+2+i*12
|
||||
*/
|
||||
if (byte_count > IFDlength || offset_val > IFDlength-byte_count || value_ptr < dir_entry || offset_val < (size_t)(dir_entry-offset_base)) {
|
||||
if (byte_count > IFDlength || offset_val > IFDlength-byte_count || value_ptr < dir_entry || offset_val < (size_t)(dir_entry-offset_base) || dir_entry <= offset_base) {
|
||||
/* It is important to check for IMAGE_FILETYPE_TIFF
|
||||
* JPEG does not use absolute pointers instead its pointers are
|
||||
* relative to the start of the TIFF header in APP1 section. */
|
||||
@@ -3524,7 +3541,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
||||
}
|
||||
}
|
||||
}
|
||||
exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table), tag, format, components, value_ptr);
|
||||
exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table), tag, format, components, value_ptr, byte_count);
|
||||
EFREE_IF(outside);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -3686,10 +3703,10 @@ static void exif_process_APP12(image_info_type *ImageInfo, char *buffer, size_t
|
||||
size_t l1, l2=0;
|
||||
|
||||
if ((l1 = php_strnlen(buffer+2, length-2)) > 0) {
|
||||
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2);
|
||||
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2, l1);
|
||||
if (length > 2+l1+1) {
|
||||
l2 = php_strnlen(buffer+2+l1+1, length-2-l1-1);
|
||||
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1);
|
||||
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1, l2);
|
||||
}
|
||||
}
|
||||
#ifdef EXIF_DEBUG
|
||||
@@ -3903,6 +3920,8 @@ static int exif_scan_thumbnail(image_info_type *ImageInfo)
|
||||
if (c == 0xFF)
|
||||
return FALSE;
|
||||
marker = c;
|
||||
if (pos>=ImageInfo->Thumbnail.size)
|
||||
return FALSE;
|
||||
length = php_jpg_get16(data+pos);
|
||||
if (length > ImageInfo->Thumbnail.size || pos >= ImageInfo->Thumbnail.size - length) {
|
||||
return FALSE;
|
||||
@@ -4557,7 +4576,7 @@ PHP_FUNCTION(exif_read_data)
|
||||
if (ImageInfo.Thumbnail.size) {
|
||||
if (read_thumbnail) {
|
||||
/* not exif_iif_add_str : this is a buffer */
|
||||
exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data);
|
||||
exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data, ImageInfo.Thumbnail.size);
|
||||
}
|
||||
if (!ImageInfo.Thumbnail.width || !ImageInfo.Thumbnail.height) {
|
||||
/* try to evaluate if thumbnail data is present */
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #77753 (Heap-buffer-overflow in php_ifd_get32s)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(exif_read_data(__DIR__."/bug77753.tiff"));
|
||||
?>
|
||||
DONE
|
||||
--EXPECTF--
|
||||
%A
|
||||
Warning: exif_read_data(bug77753.tiff): Illegal IFD size: 0x006A > 0x0065 in %sbug77753.php on line %d
|
||||
|
||||
Warning: exif_read_data(bug77753.tiff): Invalid TIFF file in %sbug77753.php on line %d
|
||||
bool(false)
|
||||
DONE
|
||||
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Bug #77831 (Heap-buffer-overflow in exif_iif_add_value in EXIF)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(exif_read_data(__DIR__."/bug77831.tiff"));
|
||||
?>
|
||||
DONE
|
||||
--EXPECTF--
|
||||
%A
|
||||
bool(false)
|
||||
DONE
|
||||
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #77950 (Heap-buffer-overflow in _estrndup via exif_process_IFD_TAG)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
|
||||
--FILE--
|
||||
<?php
|
||||
exif_read_data(__DIR__."/bug77950.tiff");
|
||||
?>
|
||||
DONE
|
||||
--EXPECTF--
|
||||
%A
|
||||
DONE
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Bug #77988 (heap-buffer-overflow on php_jpg_get16)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
|
||||
--FILE--
|
||||
<?php
|
||||
exif_read_data(__DIR__."/bug77988.jpg", 'COMMENT', FALSE, TRUE);
|
||||
?>
|
||||
DONE
|
||||
--EXPECTF--
|
||||
DONE
|
||||
+60
-72
@@ -1,6 +1,6 @@
|
||||
diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
--- libmagic.orig/apprentice.c 2018-03-11 01:46:42.000000000 +0100
|
||||
+++ libmagic/apprentice.c 2018-11-05 21:33:14.919371593 +0100
|
||||
+++ libmagic/apprentice.c 2018-11-05 00:16:58.812821826 +0100
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
@@ -1245,7 +1245,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
switch (m->str_flags & PSTRING_LEN) {
|
||||
diff -u libmagic.orig/apptype.c libmagic/apptype.c
|
||||
--- libmagic.orig/apptype.c 2011-09-07 23:57:15.000000000 +0200
|
||||
+++ libmagic/apptype.c 2018-08-10 11:51:05.107276763 +0200
|
||||
+++ libmagic/apptype.c 2018-08-10 11:46:29.210671445 +0200
|
||||
@@ -1,15 +1,15 @@
|
||||
/*
|
||||
* Adapted from: apptype.c, Written by Eberhard Mattes and put into the
|
||||
@@ -1280,7 +1280,7 @@ diff -u libmagic.orig/apptype.c libmagic/apptype.c
|
||||
#include "file.h"
|
||||
diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
|
||||
--- libmagic.orig/ascmagic.c 2017-11-02 21:25:39.000000000 +0100
|
||||
+++ libmagic/ascmagic.c 2018-08-10 11:51:05.107276763 +0200
|
||||
+++ libmagic/ascmagic.c 2018-08-10 11:46:29.210671445 +0200
|
||||
@@ -90,7 +90,7 @@
|
||||
rv = file_ascmagic_with_encoding(ms, &bb,
|
||||
ubuf, ulen, code, type, text);
|
||||
@@ -1311,7 +1311,7 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
|
||||
}
|
||||
diff -u libmagic.orig/buffer.c libmagic/buffer.c
|
||||
--- libmagic.orig/buffer.c 2018-03-11 01:46:42.000000000 +0100
|
||||
+++ libmagic/buffer.c 2018-08-10 11:51:05.107276763 +0200
|
||||
+++ libmagic/buffer.c 2018-08-10 11:46:29.210671445 +0200
|
||||
@@ -31,7 +31,11 @@
|
||||
#endif /* lint */
|
||||
|
||||
@@ -1362,7 +1362,7 @@ diff -u libmagic.orig/buffer.c libmagic/buffer.c
|
||||
|
||||
diff -u libmagic.orig/cdf.c libmagic/cdf.c
|
||||
--- libmagic.orig/cdf.c 2018-03-11 01:46:42.000000000 +0100
|
||||
+++ libmagic/cdf.c 2018-08-10 11:51:05.107276763 +0200
|
||||
+++ libmagic/cdf.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -43,7 +43,17 @@
|
||||
#include <err.h>
|
||||
#endif
|
||||
@@ -1620,7 +1620,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
|
||||
#endif
|
||||
diff -u libmagic.orig/cdf.h libmagic/cdf.h
|
||||
--- libmagic.orig/cdf.h 2017-03-09 17:57:17.000000000 +0100
|
||||
+++ libmagic/cdf.h 2018-08-10 11:51:05.107276763 +0200
|
||||
+++ libmagic/cdf.h 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -35,10 +35,10 @@
|
||||
#ifndef _H_CDF_
|
||||
#define _H_CDF_
|
||||
@@ -1646,8 +1646,16 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h
|
||||
|
||||
diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
|
||||
--- libmagic.orig/cdf_time.c 2017-03-29 17:57:48.000000000 +0200
|
||||
+++ libmagic/cdf_time.c 2018-08-10 11:51:05.107276763 +0200
|
||||
@@ -56,7 +56,7 @@
|
||||
+++ libmagic/cdf_time.c 2019-03-08 21:00:46.636733574 +0100
|
||||
@@ -23,6 +23,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
+#include "php.h"
|
||||
|
||||
#include "file.h"
|
||||
|
||||
@@ -56,7 +57,7 @@
|
||||
|
||||
for (y = CDF_BASE_YEAR; y < year; y++)
|
||||
days += isleap(y) + 365;
|
||||
@@ -1656,7 +1664,7 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
|
||||
return days;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
@@ -77,7 +78,7 @@
|
||||
return days;
|
||||
}
|
||||
|
||||
@@ -1665,9 +1673,27 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
|
||||
* Return the 0...11 month number.
|
||||
*/
|
||||
static int
|
||||
@@ -152,7 +153,7 @@
|
||||
#endif
|
||||
#ifdef notyet
|
||||
struct tm tm;
|
||||
- if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
|
||||
+ if (php_gmtime_r(&ts->ts_sec, &tm) == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@@ -168,7 +169,7 @@
|
||||
char *
|
||||
cdf_ctime(const time_t *sec, char *buf)
|
||||
{
|
||||
- char *ptr = ctime_r(sec, buf);
|
||||
+ char *ptr = php_ctime_r(sec, buf);
|
||||
if (ptr != NULL)
|
||||
return buf;
|
||||
(void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
|
||||
diff -u libmagic.orig/compress.c libmagic/compress.c
|
||||
--- libmagic.orig/compress.c 2017-11-02 21:25:39.000000000 +0100
|
||||
+++ libmagic/compress.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/compress.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
@@ -1968,7 +1994,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
|
||||
+#endif /* if PHP_FILEINFO_UNCOMPRESS */
|
||||
diff -u libmagic.orig/der.c libmagic/der.c
|
||||
--- libmagic.orig/der.c 2017-02-10 19:14:01.000000000 +0100
|
||||
+++ libmagic/der.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/der.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -51,7 +51,9 @@
|
||||
#include "magic.h"
|
||||
#include "der.h"
|
||||
@@ -2025,7 +2051,7 @@ diff -u libmagic.orig/der.c libmagic/der.c
|
||||
der_tag(buf, sizeof(buf), tag), len);
|
||||
diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
|
||||
--- libmagic.orig/elfclass.h 2014-12-17 00:18:40.000000000 +0100
|
||||
+++ libmagic/elfclass.h 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/elfclass.h 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) Christos Zoulas 2008.
|
||||
@@ -2073,7 +2099,7 @@ diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
|
||||
(int)elf_getu16(swap, elfhdr.e_shstrndx),
|
||||
diff -u libmagic.orig/encoding.c libmagic/encoding.c
|
||||
--- libmagic.orig/encoding.c 2017-11-02 21:25:39.000000000 +0100
|
||||
+++ libmagic/encoding.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/encoding.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -88,12 +88,12 @@
|
||||
*code_mime = "binary";
|
||||
|
||||
@@ -2103,7 +2129,7 @@ diff -u libmagic.orig/encoding.c libmagic/encoding.c
|
||||
}
|
||||
diff -u libmagic.orig/file.h libmagic/file.h
|
||||
--- libmagic.orig/file.h 2018-03-11 01:46:42.000000000 +0100
|
||||
+++ libmagic/file.h 2018-11-05 21:33:14.919371593 +0100
|
||||
+++ libmagic/file.h 2018-11-05 21:31:59.339653700 +0100
|
||||
@@ -27,21 +27,15 @@
|
||||
*/
|
||||
/*
|
||||
@@ -2390,7 +2416,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
|
||||
#endif
|
||||
diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
|
||||
--- libmagic.orig/fsmagic.c 2017-05-24 21:17:50.000000000 +0200
|
||||
+++ libmagic/fsmagic.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/fsmagic.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
@@ -2751,7 +2777,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
|
||||
case S_IFSOCK:
|
||||
diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
--- libmagic.orig/funcs.c 2017-11-02 21:25:39.000000000 +0100
|
||||
+++ libmagic/funcs.c 2018-11-05 21:33:14.919371593 +0100
|
||||
+++ libmagic/funcs.c 2018-11-05 21:31:59.339653700 +0100
|
||||
@@ -31,7 +31,6 @@
|
||||
#endif /* lint */
|
||||
|
||||
@@ -3136,7 +3162,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
|
||||
diff -u libmagic.orig/magic.c libmagic/magic.c
|
||||
--- libmagic.orig/magic.c 2017-08-28 15:39:18.000000000 +0200
|
||||
+++ libmagic/magic.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/magic.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -25,11 +25,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
@@ -3612,8 +3638,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
|
||||
public const char *
|
||||
magic_error(struct magic_set *ms)
|
||||
diff -u libmagic.orig/magic.h libmagic/magic.h
|
||||
--- libmagic.orig/magic.h 2018-04-23 20:45:58.824428000 +0200
|
||||
+++ libmagic/magic.h 2018-08-10 11:51:05.111276714 +0200
|
||||
--- libmagic.orig/magic.h 2018-11-13 21:40:06.272616270 +0100
|
||||
+++ libmagic/magic.h 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -122,6 +122,7 @@
|
||||
|
||||
const char *magic_getpath(const char *, int);
|
||||
@@ -3624,7 +3650,7 @@ diff -u libmagic.orig/magic.h libmagic/magic.h
|
||||
|
||||
diff -u libmagic.orig/print.c libmagic/print.c
|
||||
--- libmagic.orig/print.c 2017-02-10 19:14:01.000000000 +0100
|
||||
+++ libmagic/print.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/print.c 2019-03-08 21:00:46.636733574 +0100
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) Ian F. Darwin 1986-1995.
|
||||
* Software written by Ian F. Darwin and others;
|
||||
@@ -3643,28 +3669,15 @@ diff -u libmagic.orig/print.c libmagic/print.c
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@@ -28,6 +28,8 @@
|
||||
@@ -28,6 +28,7 @@
|
||||
/*
|
||||
* print.c - debugging printout routines
|
||||
*/
|
||||
+#define _GNU_SOURCE
|
||||
+#include "php.h"
|
||||
|
||||
#include "file.h"
|
||||
|
||||
@@ -43,6 +45,11 @@
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
+#ifdef PHP_WIN32
|
||||
+# define asctime_r php_asctime_r
|
||||
+# define ctime_r php_ctime_r
|
||||
+#endif
|
||||
+
|
||||
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
#include "cdf.h"
|
||||
@@ -75,7 +82,7 @@
|
||||
@@ -75,7 +76,7 @@
|
||||
if (m->mask_op & FILE_OPINVERSE)
|
||||
(void) fputc('~', stderr);
|
||||
|
||||
@@ -3673,7 +3686,7 @@ diff -u libmagic.orig/print.c libmagic/print.c
|
||||
if (m->str_flags) {
|
||||
(void) fputc('/', stderr);
|
||||
if (m->str_flags & STRING_COMPACT_WHITESPACE)
|
||||
@@ -215,26 +222,26 @@
|
||||
@@ -215,18 +216,18 @@
|
||||
file_magwarn(struct magic_set *ms, const char *f, ...)
|
||||
{
|
||||
va_list va;
|
||||
@@ -3701,51 +3714,26 @@ diff -u libmagic.orig/print.c libmagic/print.c
|
||||
}
|
||||
|
||||
protected const char *
|
||||
file_fmttime(uint64_t v, int flags, char *buf)
|
||||
{
|
||||
char *pp;
|
||||
- time_t t;
|
||||
- struct tm *tm, tmz;
|
||||
+ time_t t = (time_t)v;
|
||||
+ struct tm *tm = NULL;
|
||||
|
||||
if (flags & FILE_T_WINDOWS) {
|
||||
struct timespec ts;
|
||||
@@ -247,9 +254,29 @@
|
||||
@@ -247,13 +248,13 @@
|
||||
}
|
||||
|
||||
if (flags & FILE_T_LOCAL) {
|
||||
- tm = localtime_r(&t, &tmz);
|
||||
+ pp = ctime_r(&t, buf);
|
||||
+ tm = php_localtime_r(&t, &tmz);
|
||||
} else {
|
||||
- tm = gmtime_r(&t, &tmz);
|
||||
+#ifndef HAVE_DAYLIGHT
|
||||
+ private int daylight = 0;
|
||||
+#ifdef HAVE_TM_ISDST
|
||||
+ private time_t now = (time_t)0;
|
||||
+
|
||||
+ if (now == (time_t)0) {
|
||||
+ struct tm *tm1;
|
||||
+ (void)time(&now);
|
||||
+ tm1 = localtime(&now);
|
||||
+ if (tm1 == NULL)
|
||||
+ goto out;
|
||||
+ daylight = tm1->tm_isdst;
|
||||
+ }
|
||||
+#endif /* HAVE_TM_ISDST */
|
||||
+#endif /* HAVE_DAYLIGHT */
|
||||
+ if (daylight)
|
||||
+ t += 3600;
|
||||
+ tm = gmtime(&t);
|
||||
+ if (tm == NULL)
|
||||
+ goto out;
|
||||
+ pp = asctime_r(tm, buf);
|
||||
+ tm = php_gmtime_r(&t, &tmz);
|
||||
}
|
||||
if (tm == NULL)
|
||||
goto out;
|
||||
- pp = asctime_r(tm, buf);
|
||||
+ pp = php_asctime_r(tm, buf);
|
||||
|
||||
if (pp == NULL)
|
||||
goto out;
|
||||
diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
|
||||
--- libmagic.orig/readcdf.c 2017-11-02 21:25:39.000000000 +0100
|
||||
+++ libmagic/readcdf.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/readcdf.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -31,7 +31,11 @@
|
||||
|
||||
#include <assert.h>
|
||||
@@ -3882,7 +3870,7 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
|
||||
if (NOTMIME(ms)) {
|
||||
diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
--- libmagic.orig/softmagic.c 2018-04-15 20:49:15.000000000 +0200
|
||||
+++ libmagic/softmagic.c 2018-11-10 12:18:21.864916065 +0100
|
||||
+++ libmagic/softmagic.c 2018-11-11 21:42:27.860274508 +0100
|
||||
@@ -43,6 +43,10 @@
|
||||
#include <time.h>
|
||||
#include "der.h"
|
||||
@@ -4241,7 +4229,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
case FILE_INDIRECT:
|
||||
diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c
|
||||
--- libmagic.orig/strcasestr.c 2014-05-13 18:48:12.000000000 +0200
|
||||
+++ libmagic/strcasestr.c 2018-08-10 11:51:05.111276714 +0200
|
||||
+++ libmagic/strcasestr.c 2018-08-10 11:46:29.214671395 +0200
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
#include "file.h"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "php.h"
|
||||
|
||||
#include "file.h"
|
||||
|
||||
@@ -152,7 +153,7 @@ cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
|
||||
#endif
|
||||
#ifdef notyet
|
||||
struct tm tm;
|
||||
if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
|
||||
if (php_gmtime_r(&ts->ts_sec, &tm) == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@@ -168,7 +169,7 @@ cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timespec *ts)
|
||||
char *
|
||||
cdf_ctime(const time_t *sec, char *buf)
|
||||
{
|
||||
char *ptr = ctime_r(sec, buf);
|
||||
char *ptr = php_ctime_r(sec, buf);
|
||||
if (ptr != NULL)
|
||||
return buf;
|
||||
(void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* $Log$
|
||||
* Revision 2.1 2018/04/26 22:27:12 ab
|
||||
* Update libmagic to 5.31
|
||||
* Update libmagic to 5.33
|
||||
*
|
||||
* $Log$
|
||||
* Revision 2.0 2017/10/11 22:27:12 ab
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
/*
|
||||
* print.c - debugging printout routines
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include "php.h"
|
||||
|
||||
#include "file.h"
|
||||
@@ -45,11 +44,6 @@ FILE_RCSID("@(#)$File: print.c,v 1.82 2017/02/10 18:14:01 christos Exp $")
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# define asctime_r php_asctime_r
|
||||
# define ctime_r php_ctime_r
|
||||
#endif
|
||||
|
||||
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
#include "cdf.h"
|
||||
@@ -240,8 +234,8 @@ protected const char *
|
||||
file_fmttime(uint64_t v, int flags, char *buf)
|
||||
{
|
||||
char *pp;
|
||||
time_t t = (time_t)v;
|
||||
struct tm *tm = NULL;
|
||||
time_t t;
|
||||
struct tm *tm, tmz;
|
||||
|
||||
if (flags & FILE_T_WINDOWS) {
|
||||
struct timespec ts;
|
||||
@@ -254,33 +248,13 @@ file_fmttime(uint64_t v, int flags, char *buf)
|
||||
}
|
||||
|
||||
if (flags & FILE_T_LOCAL) {
|
||||
pp = ctime_r(&t, buf);
|
||||
tm = php_localtime_r(&t, &tmz);
|
||||
} else {
|
||||
#ifndef HAVE_DAYLIGHT
|
||||
private int daylight = 0;
|
||||
#ifdef HAVE_TM_ISDST
|
||||
private time_t now = (time_t)0;
|
||||
|
||||
if (now == (time_t)0) {
|
||||
struct tm *tm1;
|
||||
(void)time(&now);
|
||||
tm1 = localtime(&now);
|
||||
if (tm1 == NULL)
|
||||
goto out;
|
||||
daylight = tm1->tm_isdst;
|
||||
}
|
||||
#endif /* HAVE_TM_ISDST */
|
||||
#endif /* HAVE_DAYLIGHT */
|
||||
if (daylight)
|
||||
t += 3600;
|
||||
tm = gmtime(&t);
|
||||
if (tm == NULL)
|
||||
goto out;
|
||||
pp = asctime_r(tm, buf);
|
||||
tm = php_gmtime_r(&t, &tmz);
|
||||
}
|
||||
if (tm == NULL)
|
||||
goto out;
|
||||
pp = asctime_r(tm, buf);
|
||||
pp = php_asctime_r(tm, buf);
|
||||
|
||||
if (pp == NULL)
|
||||
goto out;
|
||||
|
||||
@@ -282,8 +282,13 @@ if ($pid) {
|
||||
}
|
||||
|
||||
}elseif (preg_match("~^CWD ([A-Za-z./]+)\r\n$~", $buf, $m)) {
|
||||
change_dir($m[1]);
|
||||
fputs($s, "250 CWD command successful.\r\n");
|
||||
if (isset($bug77680)) {
|
||||
fputs($s, "550 Directory change to $m[1] failed: file does not exist\r\n");
|
||||
var_dump($buf);
|
||||
} else {
|
||||
change_dir($m[1]);
|
||||
fputs($s, "250 CWD command successful.\r\n");
|
||||
}
|
||||
|
||||
} elseif (preg_match("~^NLST(?: ([A-Za-z./]+))?\r\n$~", $buf, $m)) {
|
||||
|
||||
@@ -325,6 +330,9 @@ if ($pid) {
|
||||
if (isset($bug7216)) {
|
||||
fputs($s, "257 OK.\r\n");
|
||||
} else {
|
||||
if (isset($bug77680)) {
|
||||
var_dump($buf);
|
||||
}
|
||||
fputs($s, "257 \"/path/to/ftproot$cwd$m[1]\" created.\r\n");
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -4623,7 +4623,11 @@ PHP_FUNCTION(imageantialias)
|
||||
if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
gdImageSetAntiAliased(im, 0);
|
||||
|
||||
if (im->trueColor) {
|
||||
im->AA = alias;
|
||||
}
|
||||
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -132,7 +132,7 @@ void gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
|
||||
BitsPerPixel = colorstobpp(tim->colorsTotal);
|
||||
/* All set, let's do it. */
|
||||
GIFEncode(
|
||||
out, tim->sx, tim->sy, tim->interlace, 0, tim->transparent, BitsPerPixel,
|
||||
out, tim->sx, tim->sy, interlace, 0, tim->transparent, BitsPerPixel,
|
||||
tim->red, tim->green, tim->blue, tim);
|
||||
if (pim) {
|
||||
/* Destroy palette based temporary image. */
|
||||
|
||||
@@ -136,7 +136,11 @@ gdImagePtr gdImageCreateFromXbm(FILE * fd)
|
||||
}
|
||||
h[3] = ch;
|
||||
}
|
||||
sscanf(h, "%x", &b);
|
||||
if (sscanf(h, "%x", &b) != 1) {
|
||||
gd_error("invalid XBM");
|
||||
gdImageDestroy(im);
|
||||
return 0;
|
||||
}
|
||||
for (bit = 1; bit <= max_bit; bit = bit << 1) {
|
||||
gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);
|
||||
if (x == im->sx) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
Bug #77700 (Writing truecolor images as GIF ignores interlace flag)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip gd extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$im = imagecreatetruecolor(10, 10);
|
||||
imagefilledrectangle($im, 0, 0, 9, 9, imagecolorallocate($im, 255, 255, 255));
|
||||
imageinterlace($im, 1);
|
||||
imagegif($im, __DIR__ . 'bug77700.gif');
|
||||
|
||||
$im = imagecreatefromgif(__DIR__ . 'bug77700.gif');
|
||||
var_dump(imageinterlace($im));
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
int(1)
|
||||
===DONE===
|
||||
--CLEAN--
|
||||
<?php
|
||||
unlink(__DIR__ . 'bug77700.gif');
|
||||
?>
|
||||
@@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Bug #77943 (imageantialias($image, false); does not work)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip gd extension not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once __DIR__ . '/func.inc';
|
||||
|
||||
$width = 400;
|
||||
$height = 300;
|
||||
$im = imagecreatetruecolor($width, $height);
|
||||
$white = imagecolorallocate($im, 255, 255, 255);
|
||||
$blue = imagecolorallocate($im, 0, 0, 255);
|
||||
|
||||
imageantialias($im, false);
|
||||
imagefilledrectangle($im, 0, 0, $width-1, $height-1, $white);
|
||||
|
||||
imageline($im, 0, 0, $width, $height, $blue);
|
||||
imagesetthickness($im, 3);
|
||||
imageline($im, 10, 0, $width, $height-10, $blue);
|
||||
|
||||
test_image_equals_file(__DIR__ . '/bug77943.png', $im);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
The images are equal.
|
||||
===DONE===
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
Bug #77973 (Uninitialized read in gdImageCreateFromXbm)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die("skip gd extension not available");
|
||||
if (!function_exists('imagecreatefromxbm')) die("skip imagecreatefromxbm not available");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$contents = hex2bin("23646566696e6520776964746820320a23646566696e652068656967687420320a737461746963206368617220626974735b5d203d7b0a7a7a787a7a");
|
||||
$filepath = __DIR__ . '/bug77973.xbm';
|
||||
file_put_contents($filepath, $contents);
|
||||
$im = imagecreatefromxbm($filepath);
|
||||
var_dump($im);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Warning: imagecreatefromxbm(): invalid XBM in %s on line %d
|
||||
|
||||
Warning: imagecreatefromxbm(): '%s' is not a valid XBM file in %s on line %d
|
||||
bool(false)
|
||||
===DONE===
|
||||
--CLEAN--
|
||||
<?php
|
||||
unlink(__DIR__ . '/bug77973.xbm');
|
||||
?>
|
||||
@@ -194,7 +194,7 @@ static void PHP_SHA3_Final(unsigned char* digest,
|
||||
}
|
||||
|
||||
// Zero out context
|
||||
memset(ctx, 0, sizeof(PHP_SHA3_CTX));
|
||||
ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX));
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
||||
@@ -127,7 +127,7 @@ static inline void SnefruTransform(PHP_SNEFRU_CTX *context, const unsigned char
|
||||
((input[i+2] & 0xff) << 8) | (input[i+3] & 0xff);
|
||||
}
|
||||
Snefru(context->state);
|
||||
memset(&context->state[8], 0, sizeof(uint32_t) * 8);
|
||||
ZEND_SECURE_ZERO(&context->state[8], sizeof(uint32_t) * 8);
|
||||
}
|
||||
|
||||
PHP_HASH_API void PHP_SNEFRUInit(PHP_SNEFRU_CTX *context)
|
||||
|
||||
+3
-1
@@ -1663,7 +1663,9 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st
|
||||
* we can do at this point. */
|
||||
if (*(p1 + 1) == '=') {
|
||||
++p1;
|
||||
--str_left;
|
||||
if (str_left > 1) {
|
||||
--str_left;
|
||||
}
|
||||
}
|
||||
|
||||
err = _php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), cd_pl);
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Bug #78069 (Out-of-bounds read in iconv.c:_php_iconv_mime_decode() due to integer overflow)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('iconv')) die('skip ext/iconv required');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$hdr = iconv_mime_decode_headers(file_get_contents(__DIR__ . "/bug78069.data"),2);
|
||||
var_dump(count($hdr));
|
||||
?>
|
||||
DONE
|
||||
--EXPECT--
|
||||
int(1)
|
||||
DONE
|
||||
@@ -939,13 +939,15 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
|
||||
|
||||
xlink = (zend_resource*) le->ptr;
|
||||
if ((!persistent && xlink->type == le_link) || xlink->type == le_plink) {
|
||||
if (IBG(default_link)) {
|
||||
zend_list_close(IBG(default_link));
|
||||
if (IBG(default_link) != xlink) {
|
||||
GC_ADDREF(xlink);
|
||||
if (IBG(default_link)) {
|
||||
zend_list_delete(IBG(default_link));
|
||||
}
|
||||
IBG(default_link) = xlink;
|
||||
}
|
||||
GC_ADDREF(xlink);
|
||||
GC_ADDREF(xlink);
|
||||
IBG(default_link) = xlink;
|
||||
RETVAL_RES(xlink);
|
||||
RETURN_RES(xlink);
|
||||
} else {
|
||||
zend_hash_str_del(&EG(regular_list), hash, sizeof(hash)-1);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_constructor)
|
||||
intl_error_reset(NULL);
|
||||
object = return_value;
|
||||
/* Parse parameters. */
|
||||
if (zend_parse_parameters_ex(zpp_flags, ZEND_NUM_ARGS(), "sll|zzs",
|
||||
if (zend_parse_parameters_ex(zpp_flags, ZEND_NUM_ARGS(), "s!ll|zzs",
|
||||
&locale_str, &locale_len, &date_type, &time_type, &timezone_zv,
|
||||
&calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) {
|
||||
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
|
||||
|
||||
@@ -175,7 +175,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object)
|
||||
goto cleanup;
|
||||
}
|
||||
cal = obj_cal->clone();
|
||||
} else if (instanceof_function(instance_ce, php_date_get_date_ce())) {
|
||||
} else if (instanceof_function(instance_ce, php_date_get_interface_ce())) {
|
||||
if (intl_datetime_decompose(object, &date, &timeZone, NULL,
|
||||
"datefmt_format_object") == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Bug #77895: IntlDateFormatter::create fails in strict mode if $locale = null
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
var_dump(IntlDateFormatter::create(null, IntlDateFormatter::NONE, IntlDateFormatter::NONE));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
object(IntlDateFormatter)#1 (0) {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Bug #65683: Intl does not support DateTimeImmutable (using datefmt_format_object)
|
||||
--FILE--
|
||||
<?php
|
||||
$date = date_create('1970-01-01');
|
||||
$date_imm = date_create_immutable('1970-01-01');
|
||||
var_dump(datefmt_format_object($date, null, 'fr_FR'));
|
||||
var_dump(datefmt_format_object($date_imm, null, 'fr_FR'));
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(%d) "%s"
|
||||
string(%d) "%s"
|
||||
+10
-2
@@ -567,8 +567,16 @@ again:
|
||||
return php_json_encode_serializable_object(buf, val, options, encoder);
|
||||
}
|
||||
/* fallthrough -- Non-serializable object */
|
||||
case IS_ARRAY:
|
||||
return php_json_encode_array(buf, val, options, encoder);
|
||||
case IS_ARRAY: {
|
||||
/* Avoid modifications (and potential freeing) of the array through a reference when a
|
||||
* jsonSerialize() method is invoked. */
|
||||
zval zv;
|
||||
int res;
|
||||
ZVAL_COPY(&zv, val);
|
||||
res = php_json_encode_array(buf, &zv, options, encoder);
|
||||
zval_ptr_dtor_nogc(&zv);
|
||||
return res;
|
||||
}
|
||||
|
||||
case IS_REFERENCE:
|
||||
val = Z_REFVAL_P(val);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
Bug #77843: Use after free with json serializer
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class X implements JsonSerializable {
|
||||
public $prop = "value";
|
||||
public function jsonSerialize() {
|
||||
global $arr;
|
||||
unset($arr[0]);
|
||||
var_dump($this);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
$arr = [new X()];
|
||||
var_dump(json_encode([&$arr]));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
object(X)#1 (1) {
|
||||
["prop"]=>
|
||||
string(5) "value"
|
||||
}
|
||||
string(20) "[[{"prop":"value"}]]"
|
||||
+3
-1
@@ -259,7 +259,9 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array,
|
||||
add_assoc_long(&value, "target", target);
|
||||
add_assoc_long(&value, "count", count);
|
||||
add_assoc_long(&value, "errcode", errcode);
|
||||
add_assoc_stringl(&value, "context", context->bv_val, context->bv_len);
|
||||
if ( context && (context->bv_len >= 0) ) {
|
||||
add_assoc_stringl(&value, "context", context->bv_val, context->bv_len);
|
||||
}
|
||||
add_assoc_zval(array, "value", &value);
|
||||
} else {
|
||||
add_assoc_null(array, "value");
|
||||
|
||||
+32
-7
@@ -65,6 +65,17 @@
|
||||
#include "php_onig_compat.h"
|
||||
#include <oniguruma.h>
|
||||
#undef UChar
|
||||
#if ONIGURUMA_VERSION_INT < 60800
|
||||
typedef void OnigMatchParam;
|
||||
#define onig_new_match_param() (NULL)
|
||||
#define onig_initialize_match_param(x) (void)(x)
|
||||
#define onig_set_match_stack_limit_size_of_match_param(x, y)
|
||||
#define onig_free_match_param(x)
|
||||
#define onig_search_with_param(reg, str, end, start, range, region, option, mp) \
|
||||
onig_search(reg, str, end, start, range, region, option)
|
||||
#define onig_match_with_param(re, str, end, at, region, option, mp) \
|
||||
onig_match(re, str, end, at, region, option)
|
||||
#endif
|
||||
#elif HAVE_PCRE || HAVE_BUNDLED_PCRE
|
||||
#include "ext/pcre/php_pcre.h"
|
||||
#endif
|
||||
@@ -1027,9 +1038,18 @@ static void *_php_mb_compile_regex(const char *pattern)
|
||||
/* {{{ _php_mb_match_regex */
|
||||
static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len)
|
||||
{
|
||||
return onig_search((php_mb_regex_t *)opaque, (const OnigUChar *)str,
|
||||
(const OnigUChar*)str + str_len, (const OnigUChar *)str,
|
||||
(const OnigUChar*)str + str_len, NULL, ONIG_OPTION_NONE) >= 0;
|
||||
OnigMatchParam *mp = onig_new_match_param();
|
||||
int err;
|
||||
onig_initialize_match_param(mp);
|
||||
if (!ZEND_LONG_UINT_OVFL(MBSTRG(regex_stack_limit))) {
|
||||
onig_set_match_stack_limit_size_of_match_param(mp, (unsigned int)MBSTRG(regex_stack_limit));
|
||||
}
|
||||
/* search */
|
||||
err = onig_search_with_param((php_mb_regex_t *)opaque, (const OnigUChar *)str,
|
||||
(const OnigUChar*)str + str_len, (const OnigUChar *)str,
|
||||
(const OnigUChar*)str + str_len, NULL, ONIG_OPTION_NONE, mp);
|
||||
onig_free_match_param(mp);
|
||||
return err >= 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1502,6 +1522,9 @@ PHP_INI_BEGIN()
|
||||
PHP_INI_ALL,
|
||||
OnUpdateBool,
|
||||
strict_detection, zend_mbstring_globals, mbstring_globals)
|
||||
#if HAVE_MBREGEX
|
||||
STD_PHP_INI_ENTRY("mbstring.regex_stack_limit", "100000",PHP_INI_ALL, OnUpdateLong, regex_stack_limit, zend_mbstring_globals, mbstring_globals)
|
||||
#endif
|
||||
PHP_INI_END()
|
||||
/* }}} */
|
||||
|
||||
@@ -3111,7 +3134,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
|
||||
{
|
||||
HashTable *output, *chash;
|
||||
zend_long idx;
|
||||
zend_string *key, *key_tmp;
|
||||
zend_string *key;
|
||||
zval *entry, entry_tmp;
|
||||
size_t ckey_len, cval_len;
|
||||
char *ckey, *cval;
|
||||
@@ -3131,7 +3154,8 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
|
||||
/* convert key */
|
||||
if (key) {
|
||||
ckey = php_mb_convert_encoding(ZSTR_VAL(key), ZSTR_LEN(key), _to_encoding, _from_encodings, &ckey_len);
|
||||
key_tmp = zend_string_init(ckey, ckey_len, 0);
|
||||
key = zend_string_init(ckey, ckey_len, 0);
|
||||
efree(ckey);
|
||||
}
|
||||
/* convert value */
|
||||
ZEND_ASSERT(entry);
|
||||
@@ -3159,13 +3183,14 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
|
||||
case IS_OBJECT:
|
||||
default:
|
||||
if (key) {
|
||||
efree(key_tmp);
|
||||
zend_string_release(key);
|
||||
}
|
||||
php_error_docref(NULL, E_WARNING, "Object is not supported");
|
||||
continue;
|
||||
}
|
||||
if (key) {
|
||||
zend_hash_add(output, key_tmp, &entry_tmp);
|
||||
zend_hash_add(output, key, &entry_tmp);
|
||||
zend_string_release(key);
|
||||
} else {
|
||||
zend_hash_index_add(output, idx, &entry_tmp);
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mbstring)
|
||||
void *http_output_conv_mimetypes;
|
||||
#if HAVE_MBREGEX
|
||||
struct _zend_mb_regex_globals *mb_regex_globals;
|
||||
zend_long regex_stack_limit;
|
||||
#endif
|
||||
char *last_used_encoding_name;
|
||||
const mbfl_encoding *last_used_encoding;
|
||||
|
||||
@@ -34,6 +34,18 @@
|
||||
#include <oniguruma.h>
|
||||
#undef UChar
|
||||
|
||||
#if ONIGURUMA_VERSION_INT < 60800
|
||||
typedef void OnigMatchParam;
|
||||
#define onig_new_match_param() (NULL)
|
||||
#define onig_initialize_match_param(x) (void)(x)
|
||||
#define onig_set_match_stack_limit_size_of_match_param(x, y)
|
||||
#define onig_free_match_param(x)
|
||||
#define onig_search_with_param(reg, str, end, start, range, region, option, mp) \
|
||||
onig_search(reg, str, end, start, range, region, option)
|
||||
#define onig_match_with_param(re, str, end, at, region, option, mp) \
|
||||
onig_match(re, str, end, at, region, option)
|
||||
#endif
|
||||
|
||||
ZEND_EXTERN_MODULE_GLOBALS(mbstring)
|
||||
|
||||
struct _zend_mb_regex_globals {
|
||||
@@ -445,13 +457,18 @@ static php_mb_regex_t *php_mbregex_compile_pattern(const char *pattern, size_t p
|
||||
OnigErrorInfo err_info;
|
||||
OnigUChar err_str[ONIG_MAX_ERROR_MESSAGE_LEN];
|
||||
|
||||
if (!php_mb_check_encoding(pattern, patlen, _php_mb_regex_mbctype2name(enc))) {
|
||||
php_error_docref(NULL, E_WARNING,
|
||||
"Pattern is not valid under %s encoding", _php_mb_regex_mbctype2name(enc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = zend_hash_str_find_ptr(&MBREX(ht_rc), (char *)pattern, patlen);
|
||||
if (!rc || onig_get_options(rc) != options || onig_get_encoding(rc) != enc || onig_get_syntax(rc) != syntax) {
|
||||
if ((err_code = onig_new(&retval, (OnigUChar *)pattern, (OnigUChar *)(pattern + patlen), options, enc, syntax, &err_info)) != ONIG_NORMAL) {
|
||||
onig_error_code_to_str(err_str, err_code, &err_info);
|
||||
php_error_docref(NULL, E_WARNING, "mbregex compile err: %s", err_str);
|
||||
retval = NULL;
|
||||
goto out;
|
||||
return NULL;
|
||||
}
|
||||
if (rc == MBREX(search_re)) {
|
||||
/* reuse the new rc? see bug #72399 */
|
||||
@@ -461,7 +478,6 @@ static php_mb_regex_t *php_mbregex_compile_pattern(const char *pattern, size_t p
|
||||
} else {
|
||||
retval = rc;
|
||||
}
|
||||
out:
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -850,6 +866,23 @@ PHP_FUNCTION(mb_regex_encoding)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ _php_mb_onig_search */
|
||||
static int _php_mb_onig_search(regex_t* reg, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start,
|
||||
const OnigUChar* range, OnigRegion* region, OnigOptionType option) {
|
||||
OnigMatchParam *mp = onig_new_match_param();
|
||||
int err;
|
||||
onig_initialize_match_param(mp);
|
||||
if (!ZEND_LONG_UINT_OVFL(MBSTRG(regex_stack_limit))) {
|
||||
onig_set_match_stack_limit_size_of_match_param(mp, (unsigned int)MBSTRG(regex_stack_limit));
|
||||
}
|
||||
/* search */
|
||||
err = onig_search_with_param(reg, str, end, start, range, region, option, mp);
|
||||
onig_free_match_param(mp);
|
||||
return err;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ _php_mb_regex_ereg_exec */
|
||||
static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
|
||||
{
|
||||
@@ -909,7 +942,7 @@ static void _php_mb_regex_ereg_exec(INTERNAL_FUNCTION_PARAMETERS, int icase)
|
||||
regs = onig_region_new();
|
||||
|
||||
/* actually execute the regular expression */
|
||||
if (onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, (OnigUChar *)(string + string_len), regs, 0) < 0) {
|
||||
if (_php_mb_onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, (OnigUChar *)(string + string_len), regs, 0) < 0) {
|
||||
RETVAL_FALSE;
|
||||
goto out;
|
||||
}
|
||||
@@ -1086,7 +1119,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
|
||||
string_lim = (OnigUChar*)(string + string_len);
|
||||
regs = onig_region_new();
|
||||
while (err >= 0) {
|
||||
err = onig_search(re, (OnigUChar *)string, (OnigUChar *)string_lim, pos, (OnigUChar *)string_lim, regs, 0);
|
||||
err = _php_mb_onig_search(re, (OnigUChar *)string, (OnigUChar *)string_lim, pos, (OnigUChar *)string_lim, regs, 0);
|
||||
if (err <= -2) {
|
||||
OnigUChar err_str[ONIG_MAX_ERROR_MESSAGE_LEN];
|
||||
onig_error_code_to_str(err_str, err);
|
||||
@@ -1249,6 +1282,11 @@ PHP_FUNCTION(mb_split)
|
||||
count--;
|
||||
}
|
||||
|
||||
if (!php_mb_check_encoding(string, string_len,
|
||||
_php_mb_regex_mbctype2name(MBREX(current_mbctype)))) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* create regex pattern buffer */
|
||||
if ((re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, MBREX(regex_default_options), MBREX(current_mbctype), MBREX(regex_default_syntax))) == NULL) {
|
||||
RETURN_FALSE;
|
||||
@@ -1262,7 +1300,7 @@ PHP_FUNCTION(mb_split)
|
||||
/* churn through str, generating array entries as we go */
|
||||
while (count != 0 && (size_t)(pos - (OnigUChar *)string) < string_len) {
|
||||
size_t beg, end;
|
||||
err = onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), pos, (OnigUChar *)(string + string_len), regs, 0);
|
||||
err = _php_mb_onig_search(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), pos, (OnigUChar *)(string + string_len), regs, 0);
|
||||
if (err < 0) {
|
||||
break;
|
||||
}
|
||||
@@ -1319,6 +1357,7 @@ PHP_FUNCTION(mb_ereg_match)
|
||||
OnigSyntaxType *syntax;
|
||||
OnigOptionType option = 0;
|
||||
int err;
|
||||
OnigMatchParam *mp;
|
||||
|
||||
{
|
||||
char *option_str = NULL;
|
||||
@@ -1338,12 +1377,23 @@ PHP_FUNCTION(mb_ereg_match)
|
||||
}
|
||||
}
|
||||
|
||||
if (!php_mb_check_encoding(string, string_len,
|
||||
_php_mb_regex_mbctype2name(MBREX(current_mbctype)))) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if ((re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, option, MBREX(current_mbctype), syntax)) == NULL) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
mp = onig_new_match_param();
|
||||
onig_initialize_match_param(mp);
|
||||
if(MBSTRG(regex_stack_limit) > 0 && MBSTRG(regex_stack_limit) < UINT_MAX) {
|
||||
onig_set_match_stack_limit_size_of_match_param(mp, (unsigned int)MBSTRG(regex_stack_limit));
|
||||
}
|
||||
/* match */
|
||||
err = onig_match(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, NULL, 0);
|
||||
err = onig_match_with_param(re, (OnigUChar *)string, (OnigUChar *)(string + string_len), (OnigUChar *)string, NULL, 0, mp);
|
||||
onig_free_match_param(mp);
|
||||
if (err >= 0) {
|
||||
RETVAL_TRUE;
|
||||
} else {
|
||||
@@ -1406,7 +1456,7 @@ _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode)
|
||||
}
|
||||
MBREX(search_regs) = onig_region_new();
|
||||
|
||||
err = onig_search(MBREX(search_re), str, str + len, str + pos, str + len, MBREX(search_regs), 0);
|
||||
err = _php_mb_onig_search(MBREX(search_re), str, str + len, str + pos, str + len, MBREX(search_regs), 0);
|
||||
if (err == ONIG_MISMATCH) {
|
||||
MBREX(search_pos) = len;
|
||||
RETVAL_FALSE;
|
||||
|
||||
@@ -14,6 +14,6 @@ var_dump($var1);
|
||||
--EXPECTF--
|
||||
Notice: Undefined variable: var in %s on line %d
|
||||
|
||||
Warning: mb_ereg_replace(): mbregex compile err: invalid code point value in %sbug72994.php on line %d
|
||||
Warning: mb_ereg_replace(): Pattern is not valid under UTF-8 encoding in %sbug72994.php on line %d
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -2,8 +2,8 @@
|
||||
Bug #77367 (Negative size parameter in mb_split)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('mbstring extension not available');
|
||||
if (!function_exists('mb_split')) die('mb_split() not available');
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (!function_exists('mb_split')) die('skip mb_split() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
@@ -12,10 +12,5 @@ var_dump(mb_split("\\w", "\xfc"));
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(0) ""
|
||||
[1]=>
|
||||
string(0) ""
|
||||
}
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -1,11 +1,14 @@
|
||||
--TEST--
|
||||
Bug #77370 (Buffer overflow on mb regex functions - fetch_token)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (!function_exists('mb_split')) die('skip mb_split() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(mb_split(" \xfd",""));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mb_split(): mbregex compile err: invalid code point value in %sbug77370.php on line %d
|
||||
Warning: mb_split(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
@@ -1,11 +1,14 @@
|
||||
--TEST--
|
||||
Bug #77371 (heap buffer overflow in mb regex functions - compile_string_node)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (!function_exists('mb_ereg')) die('skip mb_ereg() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(mb_ereg("()0\xfc00000\xfc00000\xfc00000\xfc",""));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mb_ereg(): mbregex compile err: invalid code point value in %sbug77371.php on line %d
|
||||
Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
@@ -1,7 +1,10 @@
|
||||
--TEST--
|
||||
Bug #77381 (heap buffer overflow in multibyte match_at)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (!function_exists('mb_ereg')) die('skip mb_ereg() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(mb_ereg("000||0\xfa","0"));
|
||||
@@ -10,14 +13,14 @@ var_dump(mb_ereg("0000\\"."\xf5","0"));
|
||||
var_dump(mb_ereg("(?i)FFF00000000000000000\xfd",""));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: mb_ereg(): mbregex compile err: invalid code point value in %sbug77381.php on line %d
|
||||
Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: mb_ereg(): mbregex compile err: invalid code point value in %sbug77381.php on line %d
|
||||
Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: mb_ereg(): mbregex compile err: invalid code point value in %sbug77381.php on line %d
|
||||
Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: mb_ereg(): mbregex compile err: invalid code point value in %sbug77381.php on line %d
|
||||
Warning: mb_ereg(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
@@ -1,14 +1,14 @@
|
||||
--TEST--
|
||||
Bug #77371 (Heap overflow in utf32be_mbc_to_code)
|
||||
Bug #77418 (Heap overflow in utf32be_mbc_to_code)
|
||||
--SKIPIF--
|
||||
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (!function_exists('mb_split')) die('skip mb_split() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
mb_regex_encoding("UTF-32");
|
||||
var_dump(mb_split("\x00\x00\x00\x5c\x00\x00\x00B","000000000000000000000000000000"));
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(30) "000000000000000000000000000000"
|
||||
}
|
||||
bool(false)
|
||||
@@ -1,5 +1,10 @@
|
||||
--TEST--
|
||||
Bug #77428: mb_ereg_replace() doesn't replace a substitution variable
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (!function_exists('mb_ereg_replace')) die('skip mb_ereg_replace() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
--TEST--
|
||||
Bug #77514: mb_ereg_replace() with trailing backslash adds null byte
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('mbstring')) die('skip mbstring extension not available');
|
||||
if (!function_exists('mb_ereg_replace')) die('skip mb_ereg_replace() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
mb_convert_encoding() shouldn't leak keys
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$x = "x";
|
||||
$array = ["foo" . $x => "bar"];
|
||||
mb_convert_encoding($array, 'UTF-8', 'UTF-8');
|
||||
var_dump($array);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
["foox"]=>
|
||||
string(3) "bar"
|
||||
}
|
||||
@@ -110,7 +110,7 @@ string(10) "string_val"
|
||||
|
||||
-- Iteration 4 --
|
||||
|
||||
Warning: mb_ereg_replace(): mbregex compile err: invalid code point value in %smb_ereg_replace_variation1.php on line %d
|
||||
Warning: mb_ereg_replace(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
|
||||
-- Iteration 5 --
|
||||
@@ -118,7 +118,7 @@ string(10) "string_val"
|
||||
|
||||
-- Iteration 6 --
|
||||
|
||||
Warning: mb_ereg_replace(): mbregex compile err: invalid code point value in %smb_ereg_replace_variation1.php on line %d
|
||||
Warning: mb_ereg_replace(): Pattern is not valid under UTF-8 encoding in %s on line %d
|
||||
bool(false)
|
||||
|
||||
-- Iteration 7 --
|
||||
|
||||
Loaded 100 of 273 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user