diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index b274dc4..5df6647 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -62,7 +62,7 @@ * */ #ifdef PHP_CAN_SUPPORT_PROC_OPEN -#if 0 && HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H +#if HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H # include # include # define PHP_CAN_DO_PTS 1 diff --git a/php.ini-development b/php.ini-development index 7765cfe..bc53aed 100644 --- a/php.ini-development +++ b/php.ini-development @@ -291,6 +291,12 @@ ; and below. This directive makes most sense if used in a per-directory ; or per-virtualhost web server configuration file. ; http://php.net/open-basedir + +; NOTE: this is considered a "broken" security measure. +; Applications relying on this feature will not receive full +; support by the security team. For more information please +; see /usr/share/doc/php-common/README.Debian.security +; ;open_basedir = ; This directive allows you to disable certain functions for security reasons. diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 index 740cf14..1e8d51b 100644 diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 4335a86..a7b1bb5 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -52,6 +52,10 @@ #include "php_qdbm.h" #include "php_tcadb.h" +#ifdef DB4_INCLUDE_FILE +#include DB4_INCLUDE_FILE +#endif + /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_popen, 0, 0, 2) ZEND_ARG_INFO(0, path) @@ -552,6 +556,10 @@ php_info_print_table_start(); php_info_print_table_row(2, "DBA support", "enabled"); +#ifdef DB_VERSION_STRING + php_info_print_table_row(2, "libdb header version", DB_VERSION_STRING); + php_info_print_table_row(2, "libdb library version", db_version(NULL, NULL, NULL)); +#endif if (handlers.s) { smart_str_0(&handlers); php_info_print_table_row(2, "Supported handlers", ZSTR_VAL(handlers.s)); diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 index c700dac..8932005 100644 --- a/ext/mysqli/config.m4 +++ b/ext/mysqli/config.m4 @@ -59,7 +59,7 @@ MYSQL_LIB_CFG='--libmysqld-libs' dnl mysqlnd doesn't support embedded, so we have to add some extra stuff mysqli_extra_sources="mysqli_embedded.c" - elif test "$enable_maintainer_zts" = "yes"; then + elif true || test "$enable_maintainer_zts" = "yes"; then MYSQL_LIB_CFG='--libs_r' MYSQL_LIB_NAME='mysqlclient_r' else diff --git a/ext/pdo_mysql/config.m4 b/ext/pdo_mysql/config.m4 index c165fb6..2e391eb 100755 --- a/ext/pdo_mysql/config.m4 +++ b/ext/pdo_mysql/config.m4 @@ -67,7 +67,7 @@ if test "x$SED" = "x"; then AC_PATH_PROG(SED, sed) fi - if test "$enable_maintainer_zts" = "yes"; then + if true || test "$enable_maintainer_zts" = "yes"; then PDO_MYSQL_LIBNAME=mysqlclient_r PDO_MYSQL_LIBS=`$PDO_MYSQL_CONFIG --libs_r | $SED -e "s/'//g"` else --- /dev/null +++ b/tests/func/null-new_val.phpt @@ -0,0 +1,10 @@ +--TEST-- +ini_restore strcmp NULL new_val +--FILE-- + +--EXPECT-- diff --git a/build/build.mk b/build/build.mk index ff2fafd..a044916 100644 --- a/build/build.mk +++ b/build/build.mk @@ -63,6 +63,5 @@ @if (test ! -f '.git/info/exclude' || grep -s "git-ls-files" .git/info/exclude); then \ (echo "Rebuild .git/info/exclude" && echo '*.o' > .git/info/exclude && git svn propget svn:ignore | grep -v config.nice >> .git/info/exclude); \ fi; \ - git clean -X -f -d; .PHONY: $(ALWAYS) snapshot diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 index 1e8d51b..d2e6fd9 100644 diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in index cdee4c6..ed733c5 100644 --- a/sapi/fpm/php-fpm.8.in +++ b/sapi/fpm/php-fpm.8.in @@ -139,22 +139,8 @@ .TP .B php.ini The standard php configuration file. -.SH EXAMPLES -For any unix systems which use init.d for their main process manager, you should use the init script provided to start and stop the php-fpm daemon. -.P -.PD 1 -.RS -sudo /etc/init.d/php-fpm start -.RE -.TP -For any unix systems which use systemd for their main process manager, you should use the unit file provided to start and stop the php-fpm daemon. -.P -.PD 1 -.RS -sudo systemctl start php-fpm.service -.RE -.TP -If your installation has no appropriate init script, launch php-fpm with no arguments. It will launch as a daemon (background process) by default. The file @php_fpm_localstatedir@/run/php-fpm.pid determines whether php-fpm is already up and running. Once started, php-fpm then responds to several POSIX signals: +.SH SIGNAL +Once started, php-fpm then responds to several POSIX signals: .P .PD 0 .RS @@ -168,10 +154,6 @@ .RE .PD 1 .P -.SH TIPS -The PHP-FPM CGI daemon will work well with most popular webservers, including Apache2, lighttpd and nginx. -.PD 1 -.P .SH SEE ALSO The PHP-FPM website: .PD 0 diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 9643617..8133d7d 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -687,7 +687,13 @@ switch (value) { case PHP_STREAM_MMAP_SUPPORTED: - return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; + if (fd == -1) + return PHP_STREAM_OPTION_RETURN_ERR; + /* Don't mmap large files */ + do_fstat(data, 1); + if (data->sb.st_size > 4 * 1024 * 1024) + return PHP_STREAM_OPTION_RETURN_ERR; + return PHP_STREAM_OPTION_RETURN_OK; case PHP_STREAM_MMAP_MAP_RANGE: if(do_fstat(data, 1) != 0) { diff --git a/ext/dba/dba.c b/ext/dba/dba.c index a7b1bb5..fee8e98 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -940,7 +940,7 @@ } } - if (error || hptr->open(info, &error) != SUCCESS) { + if (error || (hptr->open)(info, &error) != SUCCESS) { dba_close(info); php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:""); FREENOW; diff --git a/ext/dba/dba_db3.c b/ext/dba/dba_db3.c index 90db5a0..ff80c75 100644 --- a/ext/dba/dba_db3.c +++ b/ext/dba/dba_db3.c @@ -96,9 +96,9 @@ dbp->set_errcall(dbp, php_dba_db3_errcall_fcn); if( #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) - (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { #else - (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { #endif dba_db3_data *data; diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c index 344515d..34b7b68 100644 --- a/ext/dba/dba_db4.c +++ b/ext/dba/dba_db4.c @@ -125,9 +125,9 @@ dbp->set_errcall(dbp, php_dba_db4_errcall_fcn); if ( #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) - (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { #else - (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { #endif dba_db4_data *data; diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 6f2519d..900e763 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -49,6 +49,18 @@ int le_deflate; int le_inflate; +/* + * zlib include files can define the following preprocessor defines which rename + * the corresponding PHP functions to gzopen64, gzseek64 and gztell64 and thereby + * breaking some software, most notably PEAR's Archive_Tar, which halts execution + * without error message on gzip compressed archivesa. + * + * This only seems to happen on 32bit systems with large file support. + */ +#undef gzopen +#undef gzseek +#undef gztell + ZEND_DECLARE_MODULE_GLOBALS(zlib); /* {{{ Memory management wrappers */ diff --git a/ext/standard/tests/strings/setlocale_variation2.phpt b/ext/standard/tests/strings/setlocale_variation2.phpt index 5ebdfe8..cadf7a3 100644 --- a/ext/standard/tests/strings/setlocale_variation2.phpt +++ b/ext/standard/tests/strings/setlocale_variation2.phpt @@ -55,6 +55,7 @@ //try different locale names $failure_locale = array(); $success_count = 0; +$expected = 0; echo "-- Test setlocale() with all available locale in the system --\n"; // gather all locales installed in the system(stored $all_system_locales), @@ -64,6 +65,10 @@ if(setlocale(LC_ALL,$value )){ $success_count++; } + else if ($value == 'no_NO.ISO-8859-1') { + // ignore this one, see rhbz #971416 + $expected++; + } else{ //failure values are put in to an array $failure_locale $failure_locale[] = $value; @@ -72,11 +77,11 @@ echo "No of locales found on the machine = ".count($all_system_locales)."\n"; echo "No of setlocale() success = ".$success_count."\n"; -echo "Expected no of failures = 0\n"; +echo "Expected no of failures = $expected\n"; echo "Test "; // check if there were any failure of setlocale() function earlier, if any // failure then dump the list of failing locales -if($success_count != count($all_system_locales)){ +if(($success_count + $expected) != count($all_system_locales)){ echo "FAILED\n"; echo "Names of locale() for which setlocale() failed ...\n"; var_dump($failure_locale); @@ -92,6 +97,6 @@ -- Test setlocale() with all available locale in the system -- No of locales found on the machine = %d No of setlocale() success = %d -Expected no of failures = 0 +Expected no of failures = %d Test PASSED Done diff --git a/ext/pcre/tests/bug37911.phpt b/ext/pcre/tests/bug37911.phpt index 2b7481a..0d2859d 100644 --- a/ext/pcre/tests/bug37911.phpt +++ b/ext/pcre/tests/bug37911.phpt @@ -37,5 +37,5 @@ string(4) "blub" } -Warning: preg_replace_callback(): Compilation failed: group name must start with a non-digit at offset %d in %sbug37911.php on line %d +Warning: preg_replace_callback(): Numeric named subpatterns are not allowed in %sbug37911.php on line %d NULL diff --git a/ext/pcre/tests/grep2.phpt b/ext/pcre/tests/grep2.phpt index 1a8476c..0cf8d4a 100644 --- a/ext/pcre/tests/grep2.phpt +++ b/ext/pcre/tests/grep2.phpt @@ -40,12 +40,6 @@ string(1) "1" } bool(true) -array(3) { - [5]=> - string(1) "a" - ["xyz"]=> - string(2) "q6" - [6]=> - string(3) "h20" +array(0) { } -bool(false) +bool(true) diff --git a/ext/pcre/tests/match_flags3.phpt b/ext/pcre/tests/match_flags3.phpt index 84deb0b..c1c9d56 100644 --- a/ext/pcre/tests/match_flags3.phpt +++ b/ext/pcre/tests/match_flags3.phpt @@ -42,5 +42,5 @@ } } -Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset %d in %smatch_flags3.php on line %d +Warning: preg_match(): Numeric named subpatterns are not allowed in %smatch_flags3.php on line %d bool(false) diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index 4e307ee..8cecf17 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -31,7 +31,7 @@ #include "ext/standard/info.h" #include "tidy.h" -#include "buffio.h" +#include "tidybuffio.h" /* compatibility with older versions of libtidy */ #ifndef TIDY_CALL diff --git a/ext/xmlrpc/libxmlrpc/xml_element.c b/ext/xmlrpc/libxmlrpc/xml_element.c index 6fc6bd3..a30b500 100644 --- a/ext/xmlrpc/libxmlrpc/xml_element.c +++ b/ext/xmlrpc/libxmlrpc/xml_element.c @@ -723,6 +723,9 @@ long byte_idx = XML_GetCurrentByteIndex(parser); /* int byte_total = XML_GetCurrentByteCount(parser); */ const char * error_str = XML_ErrorString(err_code); + if(byte_idx > len) { + byte_idx = len; + } if(byte_idx >= 0) { snprintf(buf, sizeof(buf), --- /dev/null +++ b/ext/xmlrpc/tests/bug77242.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #77242 (heap out of bounds read in xmlrpc_decode()) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +NULL \ No newline at end of file diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 308c1e9..1921fa1 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2021,7 +2021,7 @@ } while (pos != filename && (*(pos - 1) == '/' || *(pos - 1) == '\0')) { - pos = memchr(pos + 1, '.', filename_len - (pos - filename) + 1); + pos = memchr(pos + 1, '.', filename_len - (pos - filename) - 1); if (!pos) { return FAILURE; } --- /dev/null +++ b/ext/phar/tests/bug77247.phpt @@ -0,0 +1,14 @@ +--TEST-- +PHP bug #77247 (heap buffer overflow in phar_detect_phar_fname_ext) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +OK \ No newline at end of file diff --git a/ext/standard/dns.c b/ext/standard/dns.c index d7513e0..84eddd2 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -549,7 +549,10 @@ CHECKCP(n); add_assoc_stringl(subarray, "tag", (char*)cp, n); cp += n; - add_assoc_string(subarray, "value", (char*)cp); + n = dlen - n - 2; + CHECKCP(n); + add_assoc_stringl(subarray, "value", (char*)cp, n); + cp += n; break; case DNS_T_TXT: { diff --git a/ext/standard/tests/network/dns_get_record_caa.phpt b/ext/standard/tests/network/dns_get_record_caa.phpt index 121bb92..2128692 100644 --- a/ext/standard/tests/network/dns_get_record_caa.phpt +++ b/ext/standard/tests/network/dns_get_record_caa.phpt @@ -7,25 +7,32 @@ ?> --FILE-- 0) { - if (array_key_exists('type', $dns[0]) - and $dns[0]['type'] == 'CAA' - and array_key_exists('flags', $dns[0]) - and array_key_exists('tag', $dns[0]) - and array_key_exists('value', $dns[0]) - ) { - $match = true; +/* This must be domains which publish an RFC6844 CAA-type DNS record */ +$domains = ["big.basic.caatestsuite.com", "google.com"]; +foreach ($domains as $domain) { + $match = false; + $dns = dns_get_record($domain, DNS_CAA); + if (count($dns) > 0) { + if (array_key_exists("type", $dns[0]) + and $dns[0]["type"] == "CAA" + and array_key_exists("flags", $dns[0]) + and array_key_exists("tag", $dns[0]) + and array_key_exists("value", $dns[0]) + ) { + $chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-."; + if (strlen($dns[0]["value"]) == strspn($dns[0]["value"], $chars)) { + $match = true; + } + } + } + if ($match) { + echo "CAA record found\n"; + } else { + echo "CAA lookup failed\n"; + var_dump($dns); } -} -if ($match) { - echo "CAA record found\n"; -} else { - echo "CAA Lookup failed\n"; } ?> --EXPECT-- CAA record found +CAA record found diff --git a/ext/mbstring/oniguruma/regparse.c b/ext/mbstring/oniguruma/regparse.c index d2925f1..252ca18 100644 --- a/ext/mbstring/oniguruma/regparse.c +++ b/ext/mbstring/oniguruma/regparse.c @@ -246,6 +246,12 @@ } #endif +#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) +# define UNEXPECTED(condition) __builtin_expect(condition, 0) +#else +# define UNEXPECTED(condition) (condition) +#endif + /* scan pattern methods */ #define PEND_VALUE 0 @@ -260,14 +266,17 @@ c = ONIGENC_MBC_TO_CODE(enc, p, end); \ pfetch_prev = p; \ p += ONIGENC_MBC_ENC_LEN(enc, p); \ + if(UNEXPECTED(p > end)) p = end; \ } while (0) #define PINC_S do { \ p += ONIGENC_MBC_ENC_LEN(enc, p); \ + if(UNEXPECTED(p > end)) p = end; \ } while (0) #define PFETCH_S(c) do { \ c = ONIGENC_MBC_TO_CODE(enc, p, end); \ p += ONIGENC_MBC_ENC_LEN(enc, p); \ + if(UNEXPECTED(p > end)) p = end; \ } while (0) #define PPEEK (p < end ? ONIGENC_MBC_TO_CODE(enc, p, end) : PEND_VALUE) --- /dev/null +++ b/ext/mbstring/tests/bug77370.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #77370 (Buffer overflow on mb regex functions - fetch_token) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(0) "" +} diff --git a/ext/mbstring/oniguruma/regcomp.c b/ext/mbstring/oniguruma/regcomp.c index b93ca94..c72d65d 100644 --- a/ext/mbstring/oniguruma/regcomp.c +++ b/ext/mbstring/oniguruma/regcomp.c @@ -524,6 +524,7 @@ for (; p < end; ) { len = enclen(enc, p); + if (p + len > end) len = end - p; if (len == prev_len) { slen++; } --- /dev/null +++ b/ext/mbstring/tests/bug77371.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #77371 (heap buffer overflow in mb regex functions - compile_string_node) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) \ No newline at end of file diff --git a/ext/mbstring/oniguruma/enc/utf16_be.c b/ext/mbstring/oniguruma/enc/utf16_be.c index 1e909eb..9e2f73b 100644 --- a/ext/mbstring/oniguruma/enc/utf16_be.c +++ b/ext/mbstring/oniguruma/enc/utf16_be.c @@ -75,16 +75,18 @@ } static OnigCodePoint -utf16be_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED) +utf16be_mbc_to_code(const UChar* p, const UChar* end) { OnigCodePoint code; if (UTF16_IS_SURROGATE_FIRST(*p)) { + if (end - p < 4) return 0; code = ((((p[0] - 0xd8) << 2) + ((p[1] & 0xc0) >> 6) + 1) << 16) + ((((p[1] & 0x3f) << 2) + (p[2] - 0xdc)) << 8) + p[3]; } else { + if (end - p < 2) return 0; code = p[0] * 256 + p[1]; } return code; diff --git a/ext/mbstring/oniguruma/enc/utf16_le.c b/ext/mbstring/oniguruma/enc/utf16_le.c index 5cc0759..580f8df 100644 --- a/ext/mbstring/oniguruma/enc/utf16_le.c +++ b/ext/mbstring/oniguruma/enc/utf16_le.c @@ -81,13 +81,14 @@ } static OnigCodePoint -utf16le_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED) +utf16le_mbc_to_code(const UChar* p, const UChar* end) { OnigCodePoint code; UChar c0 = *p; UChar c1 = *(p+1); if (UTF16_IS_SURROGATE_FIRST(c1)) { + if (end - p < 4) return 0; code = ((((c1 - 0xd8) << 2) + ((c0 & 0xc0) >> 6) + 1) << 16) + ((((c0 & 0x3f) << 2) + (p[3] - 0xdc)) << 8) + p[2]; diff --git a/ext/mbstring/oniguruma/enc/utf32_be.c b/ext/mbstring/oniguruma/enc/utf32_be.c index b4f8226..5295f26 100644 --- a/ext/mbstring/oniguruma/enc/utf32_be.c +++ b/ext/mbstring/oniguruma/enc/utf32_be.c @@ -60,6 +60,7 @@ static OnigCodePoint utf32be_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED) { + if (end - p < 4) return 0; return (OnigCodePoint )(((p[0] * 256 + p[1]) * 256 + p[2]) * 256 + p[3]); } diff --git a/ext/mbstring/oniguruma/enc/utf32_le.c b/ext/mbstring/oniguruma/enc/utf32_le.c index 8f413bf..a78c4d0 100644 --- a/ext/mbstring/oniguruma/enc/utf32_le.c +++ b/ext/mbstring/oniguruma/enc/utf32_le.c @@ -60,6 +60,7 @@ static OnigCodePoint utf32le_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED) { + if (end - p < 4) return 0; return (OnigCodePoint )(((p[3] * 256 + p[2]) * 256 + p[1]) * 256 + p[0]); } --- /dev/null +++ b/ext/mbstring/tests/bug77418.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #77371 (Heap overflow in utf32be_mbc_to_code) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(30) "000000000000000000000000000000" +} diff --git a/ext/xmlrpc/libxmlrpc/base64.c b/ext/xmlrpc/libxmlrpc/base64.c index 5ebdf31..a4fa193 100644 --- a/ext/xmlrpc/libxmlrpc/base64.c +++ b/ext/xmlrpc/libxmlrpc/base64.c @@ -77,7 +77,7 @@ while (!hiteof) { unsigned char igroup[3], ogroup[4]; - int c, n; + int c, n; igroup[0] = igroup[1] = igroup[2] = 0; for (n = 0; n < 3; n++) { @@ -169,7 +169,7 @@ return; } - if (dtable[c] & 0x80) { + if (dtable[(unsigned char)c] & 0x80) { /* fprintf(stderr, "Offset %i length %i\n", offset, length); fprintf(stderr, "character '%c:%x:%c' in input file.\n", c, c, dtable[c]); --- /dev/null +++ b/ext/xmlrpc/tests/bug77380.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #77380 (Global out of bounds read in xmlrpc base64 code) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +object(stdClass)#1 (2) { + ["scalar"]=> + string(0) "" + ["xmlrpc_type"]=> + string(6) "base64" +} diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 1921fa1..583ed45 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1390,6 +1390,9 @@ /* set up our manifest */ mydata = ecalloc(1, sizeof(phar_archive_data)); mydata->fname = expand_filepath(fname, NULL); + if (mydata->fname == NULL) { + return FAILURE; + } fname_len = strlen(mydata->fname); #ifdef PHP_WIN32 phar_unixify_path_separators(mydata->fname, fname_len); --- /dev/null +++ b/ext/phar/tests/bug77396.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #77396 Relative filename exceeding maximum path length causes null pointer dereference. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught UnexpectedValueException: Phar creation or opening failed in %s/bug77396.php:%d +Stack trace: +#0 %s/bug77396.php(%d): PharData->__construct(%s) +#1 {main} + thrown in %s/bug77396.php on line %d diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 41df661..300cf01 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1109,7 +1109,7 @@ char *path; size_t len; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &path, &len) == FAILURE) { + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "p", &path, &len) == FAILURE) { return; } --- /dev/null +++ b/ext/spl/tests/bug77431.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bug #77431 (SplFileInfo::__construct() accepts NUL bytes) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught TypeError: SplFileInfo::__construct() expects parameter 1 to be a valid path, string given in %s:%d +Stack trace:%A \ No newline at end of file diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 6fa60f7..e9aeaef 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3566,10 +3566,10 @@ tag_table_type tag_table = exif_get_tag_table(section_index); if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) { - return FALSE; - } + return FALSE; + } - if (ImageInfo->FileSize >= dir_offset+2) { + if (ImageInfo->FileSize >= 2 && ImageInfo->FileSize - 2 >= dir_offset) { sn = exif_file_sections_add(ImageInfo, M_PSEUDO, 2, NULL); #ifdef EXIF_DEBUG exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read from TIFF: filesize(x%04X), IFD dir(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, 2); @@ -3577,8 +3577,8 @@ php_stream_seek(ImageInfo->infile, dir_offset, SEEK_SET); /* we do not know the order of sections */ php_stream_read(ImageInfo->infile, (char*)ImageInfo->file.list[sn].data, 2); num_entries = php_ifd_get16u(ImageInfo->file.list[sn].data, ImageInfo->motorola_intel); - dir_size = 2/*num dir entries*/ +12/*length of entry*/*num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/; - if (ImageInfo->FileSize >= dir_offset+dir_size) { + dir_size = 2/*num dir entries*/ +12/*length of entry*/*(size_t)num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/; + if (ImageInfo->FileSize >= dir_size && ImageInfo->FileSize - dir_size >= dir_offset) { #ifdef EXIF_DEBUG exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read from TIFF: filesize(x%04X), IFD dir(x%04X + x%04X), IFD entries(%d)", ImageInfo->FileSize, dir_offset+2, dir_size-2, num_entries); #endif @@ -3661,9 +3661,9 @@ } } } - if (ImageInfo->FileSize >= dir_offset + ImageInfo->file.list[sn].size) { + if (ImageInfo->FileSize >= ImageInfo->file.list[sn].size && ImageInfo->FileSize - ImageInfo->file.list[sn].size >= dir_offset) { if (ifd_size > dir_size) { - if (dir_offset + ifd_size > ImageInfo->FileSize) { + if (ImageInfo->FileSize < ifd_size || dir_offset > ImageInfo->FileSize - ifd_size) { exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, ifd_size); return FALSE; } diff --git a/ext/exif/exif.c b/ext/exif/exif.c index e9aeaef..b2de1a9 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3508,7 +3508,7 @@ return FALSE; marker = c; length = php_jpg_get16(data+pos); - if (pos+length>=ImageInfo->Thumbnail.size) { + if (length > ImageInfo->Thumbnail.size || pos >= ImageInfo->Thumbnail.size - length) { return FALSE; } #ifdef EXIF_DEBUG @@ -3529,6 +3529,10 @@ case M_SOF14: case M_SOF15: /* handle SOFn block */ + if (length < 8 || ImageInfo->Thumbnail.size - 8 < pos) { + /* exif_process_SOFn needs 8 bytes */ + return FALSE; + } exif_process_SOFn(data+pos, marker, &sof_info); ImageInfo->Thumbnail.height = sof_info.height; ImageInfo->Thumbnail.width = sof_info.width; @@ -4176,7 +4180,9 @@ ZVAL_STRINGL(return_value, ImageInfo.Thumbnail.data, ImageInfo.Thumbnail.size); if (arg_c >= 3) { if (!ImageInfo.Thumbnail.width || !ImageInfo.Thumbnail.height) { - exif_scan_thumbnail(&ImageInfo); + if (!exif_scan_thumbnail(&ImageInfo)) { + ImageInfo.Thumbnail.width = ImageInfo.Thumbnail.height = 0; + } } zval_dtor(p_width); zval_dtor(p_height); --- /dev/null +++ b/ext/exif/tests/bug77540.jpg @@ -0,0 +1 @@ +ÿØáUExifMM* =ÚÿØÿÏÚ \ No newline at end of file --- /dev/null +++ b/ext/exif/tests/bug77540.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug 77540 (Invalid Read on exif_process_SOFn) +--SKIPIF-- + +--FILE-- + +DONE +--EXPECTF-- +Width 0 +Height 0 +DONE \ No newline at end of file diff --git a/ext/exif/exif.c b/ext/exif/exif.c index b2de1a9..57567fb 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2740,7 +2740,7 @@ break; } - if (maker_note->offset >= value_len) { + if (value_len < 2 || maker_note->offset >= value_len - 1) { /* Do not go past the value end */ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->offset); return FALSE; @@ -2793,6 +2793,7 @@ break; default: case MN_OFFSET_NORMAL: + data_len = value_len; break; } --- /dev/null +++ b/ext/exif/tests/bug77563.jpg @@ -0,0 +1 @@ +ÿØá +--FILE-- + +DONE +--EXPECTF-- +Warning: exif_thumbnail(bug77563.jpg): Illegal IFD offset in %s/bug77563.php on line %d + +Warning: exif_thumbnail(bug77563.jpg): File structure corrupted in %s/bug77563.php on line %d + +Warning: exif_thumbnail(bug77563.jpg): Invalid JPEG file in %s/bug77563.php on line %d +DONE \ No newline at end of file diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 37663ca..cacee8e 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -762,7 +762,12 @@ header.typeflag = entry->tar_type; if (entry->link) { - strncpy(header.linkname, entry->link, strlen(entry->link)); + if (strlcpy(header.linkname, entry->link, sizeof(header.linkname)) >= sizeof(header.linkname)) { + if (fp->error) { + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, link \"%s\" is too long for format", entry->phar->fname, entry->link); + } + return ZEND_HASH_APPLY_STOP; + } } strncpy(header.magic, "ustar", sizeof("ustar")-1); diff --git a/ext/phar/tests/bug71488.phpt b/ext/phar/tests/bug71488.phpt index 22d2bf0..65bd7b2 100644 --- a/ext/phar/tests/bug71488.phpt +++ b/ext/phar/tests/bug71488.phpt @@ -13,5 +13,6 @@ ---EXPECT-- -DONE \ No newline at end of file +--EXPECTF-- +Fatal error: Uncaught BadMethodCallException: tar-based phar "%s/bug71488.test" cannot be created, link "%s" is too long for format in %sbug71488.php:%d +Stack trace:%A --- /dev/null +++ b/ext/phar/tests/bug77586.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #77586 Symbolic link names in tar-formatted phar must be less than 100 bytes. +--SKIPIF-- + +--FILE-- +buildFromDirectory($dir . "/files"); +?> +--CLEAN-- + +--EXPECTF-- +Fatal error: Uncaught PharException: tar-based phar "%s/bug77586.tar" cannot be created, link "%s" is too long for format %s +Stack trace: +#0 %s/bug77586.php(%d): PharData->buildFromDirectory('%s') +#1 {main} + thrown in %s/bug77586.php %s on line %d --- /dev/null +++ b/ext/phar/tests/bug77586/files/link-nktarAMLdJBv7BGYnpzg-ZDycSpWN3Ne3kacltOSE-EqfhStJ1EoBpGuoua6VE-dne29hvpNWXiVbepwIf8-NRHWM9LITLo3nXZnKVNC @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 8133d7d..8c6c65b 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -1166,34 +1166,51 @@ # ifdef EXDEV if (errno == EXDEV) { zend_stat_t sb; +# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(NETWARE) + /* not sure what to do in ZTS case, umask is not thread-safe */ + int oldmask = umask(077); +# endif + int success = 0; if (php_copy_file(url_from, url_to) == SUCCESS) { if (VCWD_STAT(url_from, &sb) == 0) { + success = 1; # if !defined(TSRM_WIN32) && !defined(NETWARE) - if (VCWD_CHMOD(url_to, sb.st_mode)) { - if (errno == EPERM) { - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - VCWD_UNLINK(url_from); - return 1; - } + /* + * Try to set user and permission info on the target. + * If we're not root, then some of these may fail. + * We try chown first, to set proper group info, relying + * on the system environment to have proper umask to not allow + * access to the file in the meantime. + */ + if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) { php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - return 0; + if (errno != EPERM) { + success = 0; + } } - if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) { - if (errno == EPERM) { + + if (success) { + if (VCWD_CHMOD(url_to, sb.st_mode)) { php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - VCWD_UNLINK(url_from); - return 1; + if (errno != EPERM) { + success = 0; + } } - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - return 0; } # endif - VCWD_UNLINK(url_from); - return 1; + if (success) { + VCWD_UNLINK(url_from); + } + } else { + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); } + } else { + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); } - php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); - return 0; +# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(NETWARE) + umask(oldmask); +# endif + return success; } # endif #endif diff --git a/Zend/configure.in b/Zend/configure.in index 6d4d450..212a96b 100644 --- a/Zend/configure.in +++ b/Zend/configure.in @@ -70,7 +70,7 @@ #endif #ifndef zend_isnan -#if HAVE_DECL_ISNAN +#if HAVE_DECL_ISNAN && (!defined(__cplusplus) || __cplusplus < 201103L) #define zend_isnan(a) isnan(a) #elif defined(HAVE_FPCLASS) #define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN)) @@ -79,7 +79,7 @@ #endif #endif -#if HAVE_DECL_ISINF +#if HAVE_DECL_ISINF && (!defined(__cplusplus) || __cplusplus < 201103L) #define zend_isinf(a) isinf(a) #elif defined(INFINITY) /* Might not work, but is required by ISO C99 */ @@ -90,7 +90,7 @@ #define zend_isinf(a) 0 #endif -#if HAVE_DECL_ISFINITE +#if HAVE_DECL_ISFINITE && (!defined(__cplusplus) || __cplusplus < 201103L) #define zend_finite(a) isfinite(a) #elif defined(HAVE_FINITE) #define zend_finite(a) finite(a) diff --git a/configure.in b/configure.in index a45fe71..51bb70e 100644 --- a/configure.in +++ b/configure.in @@ -75,7 +75,7 @@ #endif #ifndef zend_isnan -#if HAVE_DECL_ISNAN +#if HAVE_DECL_ISNAN && (!defined(__cplusplus) || __cplusplus < 201103L) #define zend_isnan(a) isnan(a) #elif defined(HAVE_FPCLASS) #define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN)) @@ -84,7 +84,7 @@ #endif #endif -#if HAVE_DECL_ISINF +#if HAVE_DECL_ISINF && (!defined(__cplusplus) || __cplusplus < 201103L) #define zend_isinf(a) isinf(a) #elif defined(INFINITY) /* Might not work, but is required by ISO C99 */ @@ -95,7 +95,7 @@ #define zend_isinf(a) 0 #endif -#if HAVE_DECL_ISFINITE +#if HAVE_DECL_ISFINITE && (!defined(__cplusplus) || __cplusplus < 201103L) #define zend_finite(a) isfinite(a) #elif defined(HAVE_FINITE) #define zend_finite(a) finite(a) diff --git a/ext/readline/config.m4 b/ext/readline/config.m4 index 0a00370..b0cefcc 100644 --- a/ext/readline/config.m4 +++ b/ext/readline/config.m4 @@ -67,6 +67,13 @@ -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS ]) + PHP_CHECK_LIBRARY(readline, rl_completion_matches, + [ + AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, [ ]) + ],[],[ + -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS + ]) + AC_DEFINE(HAVE_LIBREADLINE, 1, [ ]) elif test "$PHP_LIBEDIT" != "no"; then @@ -114,11 +121,17 @@ -L$READLINE_DIR/$PHP_LIBDIR ]) + PHP_CHECK_LIBRARY(edit, rl_completion_matches, + [ + AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, [ ]) + ],[],[ + -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS + ]) + AC_DEFINE(HAVE_LIBEDIT, 1, [ ]) fi if test "$PHP_READLINE" != "no" || test "$PHP_LIBEDIT" != "no"; then - AC_CHECK_FUNCS([rl_completion_matches]) PHP_NEW_EXTENSION(readline, readline.c readline_cli.c, $ext_shared, cli) PHP_SUBST(READLINE_SHARED_LIBADD) fi diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 57567fb..cd6b824 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2801,6 +2801,10 @@ 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 +--FILE-- + +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 \ No newline at end of file --- /dev/null +++ b/ext/exif/tests/bug77753.tiff @@ -0,0 +1 @@ +II*  ² |’ e ÿ OLYMPUS OPTICAL CO.,LTD ÿÿÿÿ ÿ OLYMP  \ No newline at end of file diff --git a/NEWS b/NEWS index 31c91ce..2ab2845 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,10 @@ Backported from 7.1.28 +- EXIF: + . Fixed bug #77753 (Heap-buffer-overflow in php_ifd_get32s). (Stas) + . Fixed bug #77831 (Heap-buffer-overflow in exif_iif_add_value). (Stas) + - SQLite3: . Added sqlite3.defensive INI directive. (BohwaZ) diff --git a/ext/exif/exif.c b/ext/exif/exif.c index cd6b824..a1c49e9 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -1654,10 +1654,10 @@ /* {{{ 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; @@ -1679,8 +1679,12 @@ 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 { @@ -1702,6 +1706,10 @@ 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); @@ -1732,7 +1740,12 @@ } else { info_value = &info_data->value; } + vptr_end = value+value_len; for (idex=0,vptr=value; idex<(size_t)length; idex++,vptr=(char *) vptr + php_tiff_bytes_per_format[format]) { + if (vptr_end - 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]; } @@ -1768,7 +1781,7 @@ 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"); @@ -1786,9 +1799,9 @@ /* {{{ 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); } /* }}} */ @@ -2209,7 +2222,7 @@ */ 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); } /* }}} */ @@ -2224,17 +2237,17 @@ 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"); } } @@ -2826,7 +2839,7 @@ 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; @@ -3137,7 +3150,7 @@ } } } - 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; } @@ -3295,10 +3308,10 @@ 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 @@ -4099,7 +4112,7 @@ 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 */ --- /dev/null +++ b/ext/exif/tests/bug77831.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #77831 (Heap-buffer-overflow in exif_iif_add_value in EXIF) +--SKIPIF-- + +--FILE-- + +DONE +--EXPECTF-- +%A +bool(false) +DONE \ No newline at end of file --- /dev/null +++ b/ext/exif/tests/bug77831.tiff @@ -0,0 +1 @@ +ÿØá.ExifMM*    \ No newline at end of file --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2890,7 +2890,7 @@ 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. */ diff --git a/ext/gd/libgd/xbm.c b/ext/gd/libgd/xbm.c index 044159d..16978a1 100644 --- a/ext/gd/libgd/xbm.c +++ b/ext/gd/libgd/xbm.c @@ -135,7 +135,11 @@ } h[3] = ch; } - sscanf(h, "%x", &b); + if (sscanf(h, "%x", &b) != 1) { + php_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) { --- /dev/null +++ b/ext/gd/tests/bug77973.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #77973 (Uninitialized read in gdImageCreateFromXbm) +--SKIPIF-- + +--FILE-- + +===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-- + diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index ea619aa..0614534 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -1645,7 +1645,9 @@ * 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); --- /dev/null +++ b/ext/iconv/tests/bug78069.data @@ -0,0 +1 @@ +SuLt; 0Jpaa ect: =?is ect: =?isuLt; 0Jpaa ect: =?o-8859-1?q?<3F3F=3F?=¢ \ No newline at end of file --- /dev/null +++ b/ext/iconv/tests/bug78069.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #78069 (Out-of-bounds read in iconv.c:_php_iconv_mime_decode() due to integer overflow) +--SKIPIF-- + +--FILE-- + +DONE +--EXPECT-- +int(1) +DONE \ No newline at end of file --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3525,6 +3525,8 @@ 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; --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -2054,6 +2054,15 @@ } #endif + if (strncmp(arg3, "file:", 5) == 0) { + /* starts with "file:" */ + if (!arg3[5]) { + return SQLITE_DENY; + } + if (php_check_open_basedir(arg3 + 5)) { + return SQLITE_DENY; + } + } if (php_check_open_basedir(arg3)) { return SQLITE_DENY; } diff --git a/ext/curl/tests/check_win_config.phpt b/ext/curl/tests/check_win_config.phpt index 98f3e92..9e1ad98 100644 --- a/ext/curl/tests/check_win_config.phpt +++ b/ext/curl/tests/check_win_config.phpt @@ -45,7 +45,7 @@ KERBEROS5 => Yes UNIX_SOCKETS => No PSL => No -Protocols => dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp +Protocols => dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp Host => %s-pc-win32 SSL Version => OpenSSL/%s ZLib Version => %s diff --git a/ext/curl/tests/curl_basic_009.phpt b/ext/curl/tests/curl_basic_009.phpt index 529e590..3b36a78 100644 --- a/ext/curl/tests/curl_basic_009.phpt +++ b/ext/curl/tests/curl_basic_009.phpt @@ -18,6 +18,6 @@ ?> ---EXPECTF-- -%unicode|string%(%d) "%Srotocol%s" -int(1) +--EXPECTREGEX-- +string\(\d+\) "([^\r\n]*rotocol[^\r\n]+|Could not resolve host: .+)" +int\(\d\) diff --git a/ext/pdo_mysql/tests/pdo_mysql_exec.phpt b/ext/pdo_mysql/tests/pdo_mysql_exec.phpt index acd9090..9830737 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_exec.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_exec.phpt @@ -75,7 +75,7 @@ exec_and_count(19, $db, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(255)) BEGIN SELECT VERSION() INTO ver_param; END;', 0); // we got this far without problems. If there's an issue from now on, its a failure $ignore_exception = false; - exec_and_count(20, $db, 'CALL p(@version)', 0); + exec_and_count(20, $db, 'CALL p(@version)', 1); $stmt = $db->query('SELECT @version AS p_version'); $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC); if (count($tmp) > 1 || !isset($tmp[0]['p_version'])) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt index 72b5315..82806ce 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt @@ -38,7 +38,7 @@ if (false !== ($tmp = @$stmt->getColumnMeta(-1))) printf("[004] Expecting false got %s\n", var_export($tmp, true)); - // Warning: PDOStatement::getColumnMeta() expects parameter 1 to be integer, array given in + // Warning: PDOStatement::getColumnMeta() expects parameter 1 to be int, array given in if (false !== ($tmp = @$stmt->getColumnMeta(array()))) printf("[005] Expecting false got %s\n", var_export($tmp, true)); @@ -162,37 +162,37 @@ test_meta($db, 100, 'INT', -2147483648, 'LONG', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR); test_meta($db, 110, 'INT UNSIGNED', 4294967295, 'LONG', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR); - test_meta($db, 120, 'BIGINT', -9223372036854775808, 'LONGLONG', ($is_mysqlnd) ? ((PHP_INT_SIZE == 4) ? PDO::PARAM_STR : PDO::PARAM_INT) : PDO::PARAM_STR); - test_meta($db, 130, 'BIGINT UNSIGNED', 18446744073709551615, 'LONGLONG', ($is_mysqlnd) ? ((PHP_INT_SIZE == 4) ? PDO::PARAM_STR : PDO::PARAM_INT) : PDO::PARAM_STR); + test_meta($db, 120, 'BIGINT', '-9223372036854775808', 'LONGLONG', ($is_mysqlnd) ? ((PHP_INT_SIZE == 4) ? PDO::PARAM_STR : PDO::PARAM_INT) : PDO::PARAM_STR); + test_meta($db, 130, 'BIGINT UNSIGNED', '18446744073709551615', 'LONGLONG', ($is_mysqlnd) ? ((PHP_INT_SIZE == 4) ? PDO::PARAM_STR : PDO::PARAM_INT) : PDO::PARAM_STR); test_meta($db, 130, 'REAL', -1.01, ($real_as_float) ? 'FLOAT' : 'DOUBLE', PDO::PARAM_STR); test_meta($db, 140, 'REAL UNSIGNED', 1.01, ($real_as_float) ? 'FLOAT' : 'DOUBLE', PDO::PARAM_STR); - test_meta($db, 150, 'REAL ZEROFILL', -1.01, ($real_as_float) ? 'FLOAT' : 'DOUBLE', PDO::PARAM_STR); + test_meta($db, 150, 'REAL ZEROFILL', 1.01, ($real_as_float) ? 'FLOAT' : 'DOUBLE', PDO::PARAM_STR); test_meta($db, 160, 'REAL UNSIGNED ZEROFILL', 1.01, ($real_as_float) ? 'FLOAT' : 'DOUBLE', PDO::PARAM_STR); test_meta($db, 170, 'DOUBLE', -1.01, 'DOUBLE', PDO::PARAM_STR); test_meta($db, 180, 'DOUBLE UNSIGNED', 1.01, 'DOUBLE', PDO::PARAM_STR); - test_meta($db, 190, 'DOUBLE ZEROFILL', -1.01, 'DOUBLE', PDO::PARAM_STR); + test_meta($db, 190, 'DOUBLE ZEROFILL', 1.01, 'DOUBLE', PDO::PARAM_STR); test_meta($db, 200, 'DOUBLE UNSIGNED ZEROFILL', 1.01, 'DOUBLE', PDO::PARAM_STR); test_meta($db, 210, 'FLOAT', -1.01, 'FLOAT', PDO::PARAM_STR); test_meta($db, 220, 'FLOAT UNSIGNED', 1.01, 'FLOAT', PDO::PARAM_STR); - test_meta($db, 230, 'FLOAT ZEROFILL', -1.01, 'FLOAT', PDO::PARAM_STR); + test_meta($db, 230, 'FLOAT ZEROFILL', 1.01, 'FLOAT', PDO::PARAM_STR); test_meta($db, 240, 'FLOAT UNSIGNED ZEROFILL', 1.01, 'FLOAT', PDO::PARAM_STR); test_meta($db, 250, 'DECIMAL', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); test_meta($db, 260, 'DECIMAL UNSIGNED', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); - test_meta($db, 270, 'DECIMAL ZEROFILL', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); + test_meta($db, 270, 'DECIMAL ZEROFILL', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); test_meta($db, 280, 'DECIMAL UNSIGNED ZEROFILL', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); test_meta($db, 290, 'NUMERIC', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); test_meta($db, 300, 'NUMERIC UNSIGNED', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); - test_meta($db, 310, 'NUMERIC ZEROFILL', -1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); + test_meta($db, 310, 'NUMERIC ZEROFILL', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); test_meta($db, 320, 'NUMERIC UNSIGNED ZEROFILL', 1.01, array('DECIMAL', 'NEWDECIMAL'), PDO::PARAM_STR); test_meta($db, 330, 'DATE', '2008-04-23', array('DATE', 'NEWDATE'), PDO::PARAM_STR); test_meta($db, 340, 'TIME', '14:37:00', 'TIME', PDO::PARAM_STR); - test_meta($db, 350, 'TIMESTAMP', time(), 'TIMESTAMP', PDO::PARAM_STR); + test_meta($db, 350, 'TIMESTAMP', '2008-03-23 14:38:00', 'TIMESTAMP', PDO::PARAM_STR); test_meta($db, 360, 'DATETIME', '2008-03-23 14:38:00', 'DATETIME', PDO::PARAM_STR); test_meta($db, 370, 'YEAR', '2008', 'YEAR', ($is_mysqlnd) ? PDO::PARAM_INT : PDO::PARAM_STR); @@ -309,6 +309,6 @@ $db->exec('DROP TABLE IF EXISTS test'); print "done!"; ?> ---EXPECTF-- +--EXPECT-- Testing native PS... done! diff --git a/ext/standard/tests/streams/stream_socket_sendto.phpt b/ext/standard/tests/streams/stream_socket_sendto.phpt deleted file mode 100644 index 62d9f6e..0000000 --- a/ext/standard/tests/streams/stream_socket_sendto.phpt +++ /dev/null @@ -1,58 +0,0 @@ ---TEST-- -int stream_socket_sendto ( resource $socket , string $data [, int $flags = 0 [, string $address ]] ); ---CREDITS-- -marcosptf - - @phpsp - sao paulo - br ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Notice: fwrite(): send of %i bytes failed with errno=%i Broken pipe in %s on line %i - -Warning: stream_socket_sendto() expects at least %i parameters, %i given in %s on line %i -bool(%s) - -Warning: stream_socket_sendto() expects at least %i parameters, %i given in %s on line %i -bool(%s) - -Warning: stream_socket_sendto(): Broken pipe - in %s on line %i -int(%i) - -Warning: stream_socket_sendto(): Broken pipe - in %s on line %i -int(%i) - -Warning: stream_socket_sendto(): php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %i - -Warning: stream_socket_sendto(): Failed to resolve %s: php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %i - -Warning: stream_socket_sendto(): Failed to parse %s into a valid network address in %s on line %i -bool(%s) - -Warning: stream_socket_sendto(): php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %i - -Warning: stream_socket_sendto(): Failed to resolve %s: php_network_getaddresses: getaddrinfo failed: Name or service not known in %s on line %i - -Warning: stream_socket_sendto(): Failed to parse %s into a valid network address in %s on line %i -bool(%s) diff --git a/ext/standard/tests/strings/bug65769.phpt b/ext/standard/tests/strings/bug65769.phpt index 1a81d48..efe5788 100644 --- a/ext/standard/tests/strings/bug65769.phpt +++ b/ext/standard/tests/strings/bug65769.phpt @@ -26,6 +26,9 @@ $lconv['mon_decimal_point'], $lconv['mon_thousands_sep'] ); + if ($locale === 'Swedish_Sweden.1252') { + var_dump(in_array($lconv['mon_thousands_sep'], ['.', ' '])); + } echo '++++++++++++++++++++++', "\n"; } @@ -38,7 +41,8 @@ string(3) "SEK" string(2) "kr" string(1) "," -string(1) "." +string(1) "%c" +bool(true) ++++++++++++++++++++++ string(18) "French_France.1252" string(1) "," @@ -64,7 +68,7 @@ string(1) "," string(1) " " ++++++++++++++++++++++ -string(25) "Czech_Czech Republic.1250" +string(%d) "Czech_Czech%s.1250" string(1) "," string(1) " " string(3) "CZK" diff --git a/sapi/cli/tests/php_cli_server.inc b/sapi/cli/tests/php_cli_server.inc index 5ee3887..0ea90da 100644 --- a/sapi/cli/tests/php_cli_server.inc +++ b/sapi/cli/tests/php_cli_server.inc @@ -11,13 +11,14 @@ file_put_contents($doc_root . '/' . ($router ?: 'index.php'), ''); } + if (substr(PHP_OS, 0, 3) == 'WIN') { $descriptorspec = array( 0 => STDIN, 1 => STDOUT, - 2 => STDERR, + 2 => array("pipe","w"), ); - if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = "{$php_executable} -t {$doc_root} -n {$cmd_args} -S " . PHP_CLI_SERVER_ADDRESS; if (!is_null($router)) { $cmd .= " {$router}"; @@ -25,6 +26,11 @@ $handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true, "suppress_errors" => true)); } else { + $descriptorspec = array( + 0 => STDIN, + 1 => STDOUT, + 2 => STDERR, + ); $cmd = "exec {$php_executable} -t {$doc_root} -n {$cmd_args} -S " . PHP_CLI_SERVER_ADDRESS; if (!is_null($router)) { $cmd .= " {$router}"; diff --git a/ext/exif/exif.c b/ext/exif/exif.c index dd7d268..8b379bb 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3497,7 +3497,7 @@ size_t length=2, pos=0; jpeg_sof_info sof_info; - if (!data) { + if (!data || ImageInfo->Thumbnail.size < 4) { return FALSE; /* nothing to do here */ } if (memcmp(data, "\xFF\xD8\xFF", 3)) { --- /dev/null +++ b/ext/exif/tests/bug78222.jpg @@ -0,0 +1 @@ +ÿØáUExifMM* 000000=000000000000ÿØÿ00000%000000Ú \ No newline at end of file --- /dev/null +++ b/ext/exif/tests/bug78222.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #78222 (heap-buffer-overflow on exif_scan_thumbnail) +--SKIPIF-- + +--FILE-- + +DONE +--EXPECTF-- +DONE \ No newline at end of file diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 8b379bb..3f8dd90 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2619,7 +2619,7 @@ { int a; char *decode; - size_t len;; + size_t len; *pszEncoding = NULL; /* Copy the comment */ @@ -2632,11 +2632,11 @@ /* First try to detect BOM: ZERO WIDTH NOBREAK SPACE (FEFF 16) * since we have no encoding support for the BOM yet we skip that. */ - if (!memcmp(szValuePtr, "\xFE\xFF", 2)) { + if (ByteCount >=2 && !memcmp(szValuePtr, "\xFE\xFF", 2)) { decode = "UCS-2BE"; szValuePtr = szValuePtr+2; ByteCount -= 2; - } else if (!memcmp(szValuePtr, "\xFF\xFE", 2)) { + } else if (ByteCount >=2 && !memcmp(szValuePtr, "\xFF\xFE", 2)) { decode = "UCS-2LE"; szValuePtr = szValuePtr+2; ByteCount -= 2; --- /dev/null +++ b/ext/exif/tests/bug78256.jpg @@ -0,0 +1 @@ +ÿØáBExifMM* 000000000’†002000000000000UNICODE \ No newline at end of file --- /dev/null +++ b/ext/exif/tests/bug78256.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #78256 (heap-buffer-overflow on exif_process_user_comment) +--SKIPIF-- + +--FILE-- + +DONE +--EXPECTF-- +DONE \ No newline at end of file diff --git a/ext/mbstring/oniguruma/regext.c b/ext/mbstring/oniguruma/regext.c index b1b957b..b108e63 100644 --- a/ext/mbstring/oniguruma/regext.c +++ b/ext/mbstring/oniguruma/regext.c @@ -29,6 +29,7 @@ #include "regint.h" +#if 0 static void conv_ext0be32(const UChar* s, const UChar* end, UChar* conv) { @@ -158,6 +159,7 @@ return ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION; } +#endif extern int onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end, @@ -169,9 +171,7 @@ if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL; if (ci->pattern_enc != ci->target_enc) { - r = conv_encoding(ci->pattern_enc, ci->target_enc, pattern, pattern_end, - &cpat, &cpat_end); - if (r) return r; + return ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION; } else { cpat = (UChar* )pattern; diff --git a/ext/pcre/pcrelib/pcre_compile.c b/ext/pcre/pcrelib/pcre_compile.c index c782774..402c428 100644 --- a/ext/pcre/pcrelib/pcre_compile.c +++ b/ext/pcre/pcrelib/pcre_compile.c @@ -483,7 +483,7 @@ "lookbehind assertion is not fixed length\0" "malformed number or name after (?(\0" "conditional group contains more than two branches\0" - "assertion expected after (?(\0" + "assertion expected after (?( or (?(?C)\0" "(?R or (?[+-]digits must be followed by )\0" /* 30 */ "unknown POSIX class name\0" @@ -6732,6 +6732,15 @@ for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break; if (ptr[i] == CHAR_RIGHT_PARENTHESIS) tempptr += i + 1; + + /* tempptr should now be pointing to the opening parenthesis of the + assertion condition. */ + + if (*tempptr != CHAR_LEFT_PARENTHESIS) + { + *errorcodeptr = ERR28; + goto FAILED; + } } /* For conditions that are assertions, check the syntax, and then exit --- /dev/null +++ b/ext/pcre/tests/bug75457.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #75457 (heap-use-after-free in php7.0.25) +--FILE-- + +--EXPECTF-- +Warning: preg_match(): Compilation failed: assertion expected after (?( or (?(?C) at offset 4 in %sbug75457.php on line %d +bool(false) diff --git a/ext/opcache/tests/php_cli_server.inc b/ext/opcache/tests/php_cli_server.inc index 456ed66..ca781b7 100644 --- a/ext/opcache/tests/php_cli_server.inc +++ b/ext/opcache/tests/php_cli_server.inc @@ -7,16 +7,22 @@ $php_executable = getenv('TEST_PHP_EXECUTABLE'); $doc_root = __DIR__; - $descriptorspec = array( - 0 => STDIN, - 1 => STDOUT, - 2 => STDERR, - ); - if (substr(PHP_OS, 0, 3) == 'WIN') { + $descriptorspec = array( + 0 => STDIN, + 1 => STDOUT, + 2 => array("pipe", "w"), + ); + $cmd = "{$php_executable} -t {$doc_root} $ini -S " . PHP_CLI_SERVER_ADDRESS; $handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true, "suppress_errors" => true)); } else { + $descriptorspec = array( + 0 => STDIN, + 1 => STDOUT, + 2 => STDERR, + ); + $cmd = "exec {$php_executable} -t {$doc_root} $ini -S " . PHP_CLI_SERVER_ADDRESS . " 2>/dev/null"; $handle = proc_open($cmd, $descriptorspec, $pipes, $doc_root); } diff --git a/ext/opcache/tests/bug66461.phpt b/ext/opcache/tests/bug66461.phpt index 33132ab..2d09fef 100644 --- a/ext/opcache/tests/bug66461.phpt +++ b/ext/opcache/tests/bug66461.phpt @@ -4,6 +4,7 @@ opcache.enable=1 opcache.enable_cli=1 opcache.optimization_level=-1 +opcache.log_verbosity_level=1 opcache.file_update_protection=0 opcache.interned_strings_buffer=0 --SKIPIF-- diff --git a/ext/opcache/tests/issue0115.phpt b/ext/opcache/tests/issue0115.phpt index 26d9908..8794a00 100644 --- a/ext/opcache/tests/issue0115.phpt +++ b/ext/opcache/tests/issue0115.phpt @@ -32,7 +32,7 @@ unset($p); include "php_cli_server.inc"; -php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1 -d extension=phar.'.PHP_SHLIB_SUFFIX); +php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1 -d extension='.(substr(PHP_OS, 0, 3) == 'WIN' ? 'php_' : '').'phar.'.PHP_SHLIB_SUFFIX); echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0115_1.phar.php'); echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0115_2.phar.php'); ?> diff --git a/ext/opcache/tests/issue0149.phpt b/ext/opcache/tests/issue0149.phpt index ba57623..f8ff972 100644 --- a/ext/opcache/tests/issue0149.phpt +++ b/ext/opcache/tests/issue0149.phpt @@ -20,7 +20,7 @@ unset($p); include "php_cli_server.inc"; -php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1 -d extension=phar.'.PHP_SHLIB_SUFFIX); +php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1 -d extension='.(substr(PHP_OS, 0, 3) == 'WIN' ? 'php_' : '').'phar.'.PHP_SHLIB_SUFFIX); echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php'); echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php'); echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php'); diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 695839c..88c7c9f 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1208,8 +1208,8 @@ path_info = script_path_translated + ptlen; tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0)); } else { - path_info = env_path_info ? env_path_info + pilen - slen : NULL; - tflag = (orig_path_info != path_info); + path_info = (env_path_info && pilen > slen) ? env_path_info + pilen - slen : NULL; + tflag = path_info && (orig_path_info != path_info); } if (tflag) { --- a/ext/bcmath/libbcmath/src/str2num.c +++ b/ext/bcmath/libbcmath/src/str2num.c @@ -57,9 +57,9 @@ zero_int = FALSE; if ( (*ptr == '+') || (*ptr == '-')) ptr++; /* Sign */ while (*ptr == '0') ptr++; /* Skip leading zeros. */ - while (isdigit((int)*ptr)) ptr++, digits++; /* digits */ + while (*ptr >= '0' && *ptr <= '9') ptr++, digits++; /* digits */ if (*ptr == '.') ptr++; /* decimal point */ - while (isdigit((int)*ptr)) ptr++, strscale++; /* digits */ + while (*ptr >= '0' && *ptr <= '9') ptr++, strscale++; /* digits */ if ((*ptr != '\0') || (digits+strscale == 0)) { *num = bc_copy_num (BCG(_zero_)); --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -684,10 +684,10 @@ if (SPL_HAS_FLAG(ctor_flags, DIT_CTOR_FLAGS)) { flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO; - parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &path, &len, &flags); + parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &path, &len, &flags); } else { flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF; - parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &path, &len); + parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "p", &path, &len); } if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_SKIPDOTS)) { flags |= SPL_FILE_DIR_SKIPDOTS; diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 3f8dd90..a7da928 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2820,8 +2820,9 @@ } for (de=0;detag_table)) { + size_t offset = 2 + 12 * de; + if (!exif_process_IFD_TAG(ImageInfo, dir_start + offset, + offset_base, data_len - offset, displacement, section_index, 0, maker_note->tag_table)) { return FALSE; } } --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2748,7 +2748,8 @@ continue; if (maker_note->model && (!ImageInfo->model || strcmp(maker_note->model, ImageInfo->model))) continue; - if (maker_note->id_string && strncmp(maker_note->id_string, value_ptr, maker_note->id_string_len)) + if (maker_note->id_string && value_len >= maker_note->id_string_len + && strncmp(maker_note->id_string, value_ptr, maker_note->id_string_len)) continue; break; } diff --git a/ext/standard/string.c b/ext/standard/string.c index a8b39ee..c4b5e03 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4757,7 +4757,7 @@ if (state == 4) { /* Inside */ break; - } else if (state == 2 && *(p-1) != '\\') { + } else if (state == 2 && p >= buf + 1 && *(p-1) != '\\') { if (lc == c) { lc = '\0'; } else if (lc != '\\') { @@ -4784,7 +4784,7 @@ case '!': /* JavaScript & Other HTML scripting languages */ - if (state == 1 && *(p-1) == '<') { + if (state == 1 && p >= buf + 1 && *(p-1) == '<') { state = 3; lc = c; } else { @@ -4811,7 +4811,7 @@ case '?': - if (state == 1 && *(p-1) == '<') { + if (state == 1 && p >= buf + 1 && *(p-1) == '<') { br=0; state=2; break; --- /dev/null +++ b/ext/standard/tests/file/bug79099.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #79099 (OOB read in php_strip_tags_ex) +--FILE-- + +--EXPECT-- +string(0) "" +string(0) "" +string(0) "" +string(0) "" +string(0) "" +string(0) "" diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index 122ff4c..657eb98 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -138,6 +138,17 @@ {0xf70f,0xf848,0xc740,0xc8fe}, }; +static inline int is_in_cp950_pua(int c1, int c) { + if ((c1 >= 0xfa && c1 <= 0xfe) || (c1 >= 0x8e && c1 <= 0xa0) || + (c1 >= 0x81 && c1 <= 0x8d) || (c1 >= 0xc7 && c1 <= 0xc8)) { + return (c >=0x40 && c <= 0x7e) || (c >= 0xa1 && c <= 0xfe); + } + if (c1 == 0xc6) { + return c >= 0xa1 && c <= 0xfe; + } + return 0; +} + /* * Big5 => wchar */ @@ -186,11 +197,7 @@ if (filter->from->no_encoding == mbfl_no_encoding_cp950) { /* PUA for CP950 */ - if (w <= 0 && - (((c1 >= 0xfa && c1 <= 0xfe) || (c1 >= 0x8e && c1 <= 0xa0) || - (c1 >= 0x81 && c1 <= 0x8d) ||(c1 >= 0xc7 && c1 <= 0xc8)) - && ((c > 0x39 && c < 0x7f) || (c > 0xa0 && c < 0xff))) || - ((c1 == 0xc6) && (c > 0xa0 && c < 0xff))) { + if (w <= 0 && is_in_cp950_pua(c1, c)) { c2 = c1 << 8 | c; for (k = 0; k < sizeof(cp950_pua_tbl)/(sizeof(unsigned short)*4); k++) { if (c2 >= cp950_pua_tbl[k][2] && c2 <= cp950_pua_tbl[k][3]) { --- /dev/null +++ b/ext/mbstring/tests/bug79037.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #79037: global buffer-overflow in `mbfl_filt_conv_big5_wchar` +--FILE-- + +--EXPECT-- +string(1) "?" diff --git a/ext/standard/string.c b/ext/standard/string.c index c4b5e03..7c044af 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4707,7 +4707,7 @@ switch (state) { case 1: /* HTML/XML */ lc = '>'; - if (is_xml && *(p -1) == '-') { + if (is_xml && p >= buf + 1 && *(p-1) == '-') { break; } in_q = state = is_xml = 0; @@ -4728,7 +4728,7 @@ break; case 2: /* PHP */ - if (!br && lc != '\"' && *(p-1) == '?') { + if (!br && lc != '\"' && p >= buf + 1 && *(p-1) == '?') { in_q = state = 0; tp = tbuf; } --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -341,7 +341,7 @@ str = zval_get_string(newval); - handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval)); + handler = xmlFindCharEncodingHandler(ZSTR_VAL(str)); if (handler != NULL) { xmlCharEncCloseFunc(handler); --- /dev/null +++ b/ext/dom/tests/bug77569.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #77569 (Write Acess Violation in DomImplementation) +--SKIPIF-- + +--FILE-- +createDocument("", ""); +$dom->encoding = null; +?> +--EXPECTF-- +Warning: main(): Invalid Document Encoding in %s on line %d diff --git a/ext/session/session.c b/ext/session/session.c index bd557b0..48a15b6 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -3108,9 +3108,11 @@ if (PS(rfc1867_cleanup)) { php_session_rfc1867_cleanup(progress); } else { - add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1); - Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; - php_session_rfc1867_update(progress, 1); + if (!Z_ISUNDEF(progress->data)) { + add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1); + Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; + php_session_rfc1867_update(progress, 1); + } } php_rshutdown_session_globals(); } --- /dev/null +++ b/ext/session/tests/bug79221.phpt @@ -0,0 +1,45 @@ +--TEST-- +Null Pointer Dereference in PHP Session Upload Progress +--INI-- +error_reporting=0 +file_uploads=1 +upload_max_filesize=1024 +session.save_path= +session.name=PHPSESSID +session.serialize_handler=php +session.use_strict_mode=0 +session.use_cookies=1 +session.use_only_cookies=0 +session.upload_progress.enabled=1 +session.upload_progress.cleanup=0 +session.upload_progress.prefix=upload_progress_ +session.upload_progress.name=PHP_SESSION_UPLOAD_PROGRESS +session.upload_progress.freq=1% +session.upload_progress.min_freq=0.000000001 +--COOKIE-- +PHPSESSID=session-upload +--POST_RAW-- +Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 +-----------------------------20896060251896012921717172737 +Content-Disposition: form-data; name="PHPSESSID" + +session-upload +-----------------------------20896060251896012921717172737 +Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS" + +ryat +-----------------------------20896060251896012921717172737 +Content-Disposition: form-data; file="file"; ryat="filename" + +1 +-----------------------------20896060251896012921717172737-- +--FILE-- +c; phar_archive_object *phar_obj = p_obj->p; + php_stream_statbuf ssb; value = iter->funcs->get_current_data(iter); @@ -1745,6 +1746,16 @@ php_stream_copy_to_stream_ex(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len); data->internal_file->uncompressed_filesize = data->internal_file->compressed_filesize = php_stream_tell(p_obj->fp) - data->internal_file->offset; + if (php_stream_stat(fp, &ssb) != -1) { + data->internal_file->flags = ssb.sb.st_mode & PHAR_ENT_PERM_MASK ; + } else { +#ifndef _WIN32 + mode_t mask; + mask = umask(0); + umask(mask); + data->internal_file->flags &= ~mask; +#endif + } } if (close_fp) { --- /dev/null +++ b/ext/phar/tests/bug79082.phpt @@ -0,0 +1,52 @@ +--TEST-- +Phar: Bug #79082: Files added to tar with Phar::buildFromIterator have all-access permissions +--SKIPIF-- + +--FILE-- + 'tar', Phar::ZIP => 'zip'] as $mode => $ext) { + clearstatcache(); + $phar = new PharData(__DIR__ . '/test79082.' . $ext, null, null, $mode); + $phar->buildFromIterator(new \RecursiveDirectoryIterator(__DIR__ . '/test79082', \FilesystemIterator::SKIP_DOTS), __DIR__ . '/test79082'); + $phar->extractTo(__DIR__); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile')['mode'])); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile2')['mode'])); + unlink(__DIR__ . '/test79082-testfile'); + unlink(__DIR__ . '/test79082-testfile2'); +} +foreach([Phar::TAR => 'tar', Phar::ZIP => 'zip'] as $mode => $ext) { + clearstatcache(); + $phar = new PharData(__DIR__ . '/test79082-d.' . $ext, null, null, $mode); + $phar->buildFromDirectory(__DIR__ . '/test79082'); + $phar->extractTo(__DIR__); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile')['mode'])); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile2')['mode'])); + unlink(__DIR__ . '/test79082-testfile'); + unlink(__DIR__ . '/test79082-testfile2'); +} +?> +--CLEAN-- + +--EXPECT-- +string(2) "22" +string(6) "100644" +string(6) "100400" +string(6) "100644" +string(6) "100400" +string(6) "100644" +string(6) "100400" +string(6) "100644" +string(6) "100400" --- /dev/null +++ b/ext/phar/tests/test79082/test79082-testfile @@ -0,0 +1 @@ +test --- /dev/null +++ b/ext/phar/tests/test79082/test79082-testfile2 @@ -0,0 +1 @@ +test diff --git a/ext/openssl/tests/bug54992-ca.pem b/ext/openssl/tests/bug54992-ca.pem index ac13917..266f08c 100644 --- a/ext/openssl/tests/bug54992-ca.pem +++ b/ext/openssl/tests/bug54992-ca.pem @@ -1,35 +1,35 @@ -----BEGIN CERTIFICATE----- -MIIGAzCCA+ugAwIBAgIUVL06vQzqQ1uRdJ7NAAZyylsKOpYwDQYJKoZIhvcNAQEL +MIIGAzCCA+ugAwIBAgIUZOucIjT7OfT7rQQu4W5rghLGMYEwDQYJKoZIhvcNAQEL BQAwgZAxCzAJBgNVBAYTAlBUMQ8wDQYDVQQIDAZMaXNib2ExDzANBgNVBAcMBkxp c2JvYTEXMBUGA1UECgwOUEhQIEZvdW5kYXRpb24xHjAcBgNVBAMMFVJvb3QgQ0Eg Zm9yIFBIUCBUZXN0czEmMCQGCSqGSIb3DQEJARYXaW50ZXJuYWxzQGxpc3RzLnBo -cC5uZXQwHhcNMTgxMjAxMjEzNTUwWhcNMTgxMjMxMjEzNTUwWjCBkDELMAkGA1UE +cC5uZXQwHhcNMjAwMjE4MDg1MDM0WhcNMjEwMzI0MDg1MDM0WjCBkDELMAkGA1UE BhMCUFQxDzANBgNVBAgMBkxpc2JvYTEPMA0GA1UEBwwGTGlzYm9hMRcwFQYDVQQK DA5QSFAgRm91bmRhdGlvbjEeMBwGA1UEAwwVUm9vdCBDQSBmb3IgUEhQIFRlc3Rz MSYwJAYJKoZIhvcNAQkBFhdpbnRlcm5hbHNAbGlzdHMucGhwLm5ldDCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBANVgTLlHH3bNkxx+XA1xhr842rf+lP5A -XDhM5N9vRCXs/6FAB6iFAfnR+YVgcHD/ppgrrOlAIf6QF2J9EOA4h9oOtCrbhC9y -3uKT/dnPWpa39NAdHDJMl2GndulhfyNzXoPmHR+UmVl8RIwJa2yzq8kfI28VZOdG -4oW+L8hybO1r+7kewnI/3TQme+yxRMtI/RDAneBPUu4yx+VTy6gP1R7PMwEnMgLC -msdBEJh2FR2rjboejZiBAHRG5cWbmRlYV0ApDZAgaKbKGCgken7FF9mImduv7c9H -pHkSKAFdt5hYaeJJy48lh5wC7gMjBo62WKUnBqnV1gBBniWSfsgfNJKPV5a3EO32 -7KinHzzCH4V1C8tCU26om0CoRI+Bm/dpnwuDZWELzMnnyAeCmGWnPi2s/+QaWwKC -sMXn0+3CFYtlZ+zEZm0KB10RMypRLhn9md9/TfxJNNjDIHCMCLJkxyxFnYOWqtCd -zAA09r117AgM3tbRYY9NYvNzLw5hnPs2W3gB4vrUzqBcgdfIdVaE1QUyy8rWjMNI -fIVJVFeyN2mcg3JQw2WmKINDQJWZxXFJR9BPgISpR93BF5zIfGZSSRPuBXaXQ6j/ -9aw+fnA8asietOL2wGa60zqX1WKopNYvRlt6CCIYkFcfRRkoEjcMRpyVsSn2U9Dd -pFlDHq9iE6SLAgMBAAGjUzBRMB0GA1UdDgQWBBQKZYIWtrUo8Iv5zBWfBn40D7p9 -1DAfBgNVHSMEGDAWgBQKZYIWtrUo8Iv5zBWfBn40D7p91DAPBgNVHRMBAf8EBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAEJhZ6mMgRUJGF4dM5r+SfrwCTbNGDJkFz -DSbeb6WMTtvzL1g2P5zHQ0OvlX+mvmqCRXM40sUFMHDLCQzIgKLpgd44yZM6k4wL -hReX2okQ8tEwB73ahy/H3TaRr3B2l6s16kx4obDpyTsbrBZgiks515ru5EM2pv7x -31Ya2sUlXBWt+Kc+Z/6UI2Eot7G4M11oeRGpWnFBqPFAIByEbnCR4NCPbAKl2t2q -vhsQh0zAo9qB4uUyc/XblKKRtdupDnRceSCLg18ZwnBxrVZBuSK5oUCAwAFtE4BZ -G793gbwIUeR0pFgNMKkfPnXy3Ii8OmPDc9CsxO0Qg4Xh2VXWpVI+N5xL5L/M3O1i -UDDO2PeoaEVfz3htOCYo1U6BSQqMzg5JD2JifzKEscy3rFkpH21EHLg07Fv4ZSFo -HG22zt00dJpNatyAzzaYHlMel4K1fwNrGrUH5M2OeRtvkUMlDKwp8qrKIDpTi6vT -GW0woBoRlR1+qGGG9RHBqm937uhHJsLw8lFJmvO0ObqbdpdfW4nWugL8x1LZC9oz -uaH7hwj5i0SKK/StuLxAPP6cl4RqQhXO5rxEz2iFjl4nwwtRH3KPEDEAvQcnNXpi -2YV5z8C78j1amzbSJBlGpu3aoJNn+WPgjePmeBe7oE9t1/5kvIVIAj8kg6CaKfHz -6hiK1Erl8g== +KoZIhvcNAQEBBQADggIPADCCAgoCggIBANDtiwpbgpWNthaPNRpgjvNagqaq1EjS +19CNFq1+w5jRI8K130RvAWkDwnDcr70RSuNKhbJ2dEool3sUi8puNdvWLa8p95k9 +wg1HtCICixxIdLoYAzprkBJw7QUu/XH9SJeJRkYL7EUFoSDnQF9kbW1qMxZBRlFI +JEacK1crUBGekudu1DjHCM6dumyObrH4FYZtDdKHLu3PVTO299J7ILsHlAJ31qOG +zK96yBkjRomru/+Yr9ZjT915slvg19+PGLRSRLMXoolw+WEk5gc00/AsGqXQpavN +njDu9uw+33Eimrj8KnVsCh9cBQFmrCdqOdJmv8VwD63lcYLruAXkfHIUgdyeVMVT +Q8O+bgGQWaUrxRED4pJ932TicC23BhiZ/78/nyLwry473mHSIw4Y3M6kGSmEOs+3 +fDcsF8waqOeGXbgdOUjBTu92io+lGsCnUZBRe7sOus6aKHYDE1aBDeGtO4oALS+V +kNrbCh/VpRIwO9Ah4PvxweqW0ZdloW3TRIXRgRxmGJ9NFe1Rkvv7FB7i2l8IeAKS +ckuew31vxP6LgGUe5j/qt6xv6GOysefOCAAoHHeNEH+ZSlD1tiglvMVhsUmY9Rit +XEnB+X8FtOAM3SFiX5tsgB6n4hRKue5WkZywnbkPx7sDu4LQCA00i55dzjP/39M0 +yPnsQrJfOnj5AgMBAAGjUzBRMB0GA1UdDgQWBBSHvApjxItCycV/u9J4Z3b6UAP7 +jzAfBgNVHSMEGDAWgBSHvApjxItCycV/u9J4Z3b6UAP7jzAPBgNVHRMBAf8EBTAD +AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQB6ffwQmqI9Rq3qiPspJiFLsAT9Um8A/kd0 +unYdMyBRl9T0llGXBeN3YYrJLVAd01UAOSSDV3Cf8L2J2zvKRT8YbC3/LxB/RLIM +/eHVMGSxpy0S5U8HVChbYGEx/zC9p71HwL31Xj+NfOW1nFbEEPqSbGRmou+X2twZ +Omwz4Vm4MEpIQLRdgV5bLMN1SETH3TGwdMmTE2S8iKrqeDGB8NEl2LcDvbHAvPNw +KjitZRiicU99KzSSiGh7dsG/d9JsZqtCSmD+a2PesoUPSPsCaInLQG3aGkApt8Gl +TtFTxJo9QW7YWxFr9Efb2eU6UIilPSsVj8tvIfS1PRTTJrOlBpJDI6TL5YYtFuw3 +Ij27ILbXSwqUM5MIDYoRDxschNiMRhkRjmnebir2KQdvbt43rW8czwooOzTkd1Bi +RCAbUCAh1TqVu4vLGcoA8/Rf/1n4M8Zdgq19yfInmU4xs7kaiVvnnAxLSF1TmJl6 +8FCN7ONvHNNXciRkzIxw5Yn6GODa/e8Fzvaza/vkSvW4ry4Hu7T6ze10SuHagN3R +wwBGBlEI5FEyEKFsTZeHdDMoYzv7Ls4OXZzAo7B/Lwa4OTql7ApVw7MwHEplN3SS +1Qn4YhhmwJqiGvTGQZSA1gv6Ua/HPHjs1y1fSz+uRukUqlBemDhllmVjWHKJetOv ++FMLf6DmBw== -----END CERTIFICATE----- diff --git a/ext/openssl/tests/bug54992.pem b/ext/openssl/tests/bug54992.pem index 1a64a4e..a04c68c 100644 --- a/ext/openssl/tests/bug54992.pem +++ b/ext/openssl/tests/bug54992.pem @@ -1,26 +1,26 @@ -----BEGIN CERTIFICATE----- -MIID7jCCAdYCFBDKe4ra5M5zJIb81D7zwFRmyHQGMA0GCSqGSIb3DQEBCwUAMIGQ +MIID7jCCAdYCFF2eDgBNSufPjQA1YmkSEu4tWGvTMA0GCSqGSIb3DQEBCwUAMIGQ MQswCQYDVQQGEwJQVDEPMA0GA1UECAwGTGlzYm9hMQ8wDQYDVQQHDAZMaXNib2Ex FzAVBgNVBAoMDlBIUCBGb3VuZGF0aW9uMR4wHAYDVQQDDBVSb290IENBIGZvciBQ SFAgVGVzdHMxJjAkBgkqhkiG9w0BCQEWF2ludGVybmFsc0BsaXN0cy5waHAubmV0 -MB4XDTE4MTIwMTIxNDU0MloXDTE4MTIzMTIxNDU0MlowWjEXMBUGA1UEAxMOYnVn +MB4XDTIwMDIxODA4NTA0N1oXDTIxMDMyNDA4NTA0N1owWjEXMBUGA1UEAxMOYnVn NTQ5OTIubG9jYWwxCzAJBgNVBAYTAlBUMQ8wDQYDVQQHEwZMaXNib2ExDzANBgNV BAgTBkxpc2JvYTEQMA4GA1UEChMHcGhwLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOB jQAwgYkCgYEAtUAVQKTgpUPgtFOJ3w3kDJETS45tWeT96kUg1NeYLKW+jNbFhxPo PJv7XhfemCaqh2tbq1cdYW906Wp1L+eNQvdTYA2IQG4EQBUlmfyIakOIMsN/RizV kF09vlNQwTpaMpqTv7wB8vvwbxb9jbC2ZhQUBEg6PIn18dSstbM9FZ0CAwEAATAN -BgkqhkiG9w0BAQsFAAOCAgEAid90+ulRK+4ifB2tKnt2MyuqXZexv2yQ4u15EYmE -NLOpP5ZWN8vSvRI3IGruNA00dX/F2EOT+u82ApOxzYyxceAx29Ytpt7PSd2nUqkN -TbDAsDTUZdoDLUa6dGPe5Faaai00nfNJ3lqmC9xPbBPKyJ3hjz0Uj6gi51Lfi410 -4GZa4oIL3NEIKVtaK942EAYCjeWx1VT8AnsvK4Nqufo97sbZNHJhgY+ApM168kox -kFA/RNYp/pNS0FCc8b9DwMnu38n2n33iDl3P54chpAcyuWJE5wL/kN2gnS6iMsLP -14NtBg2mm++4XqBpt9glmWr56HZtvyFW0IhpDwQgRe4GSIwPES2g1s7iUs3T4VdJ -aHkF4v8Bdl6DWXSVdbqIq8CpVZLhf7vt6pV/22YpVCjQFmiLtc8a4gWaYvpn6j+L -nAajb9JpdkNeqNiBxmtfQwL7xtY+1goLd9OKtIO1b2517ZRgU9NkUfLKCTl2W2L8 -sMY7FPVs6Z1jfaXw+vIWKCJKe0thf0HMV4q11ptsqpzyIzAAjAfma1b/MM5ATHsa -6h7Poh0yg+WMSdXurjhDWogOWrzPXSe0izUYpREkTVl1oLhzorxlEDh7vBLB2TS3 -TPAEdNxEbsIutMjoz5ql5dYxgZQGW7HARXrXhMbk6cBU8khNcGGqz1uzX1x7Vb2d -hKs= +BgkqhkiG9w0BAQsFAAOCAgEAEhDpl41vWZF9lGSlxz5uwIGguibrbeBYn/1PYpw4 +jF0i/DxNWYmAh/9vM/ClXhL9rVtHev88eO6goIDjiU2W59ksffxxw0Xno6XOgElb +8sdWBF4wLKiCuZrAYJ+N+CWKWkWFgsdBEHGktBk/UIh7Aw2LjVneMMj8lIgpDw9l +PfMZ1SAajBEh5D4TrM6TR3ImT2x0t4Rb1LOrfdn34eHHp/K1wpsZfDwzQKXF1RNb +XqQwzsB5kEMdOBC1ykOXcLqiUPxMakiVAfnt8w1UCdCB3TH63HkxATqoqZLXFYRX +JZRLkAUvoqdDNVP2gOYRewInWJL+EaRNt3P5DR8tEgCOUyw0UYgpI7KDHV5cL3MB +JKeLXmQu0o9ZviPk3saEdmhnSaPCGcVoF5E1vnSudcla7wz65U0w+bEX94DxGad/ +CrsGVS0VbdTV6lPQgcbP/IP4sxBUqZvpDlr20XzgsgdwCBgGwcJ47Y1zDQh17sAe +rZxhtxHG6PJbCwdj7z9FNgsMPmfFXoqcLFyN+N3vbGMpOaO6KCoylmFvNSQCwFrm +y/V+z5fQFe42trqLr04DEVw7rzGN6I8vyGPu7267FNDO5bdwuJ0FVjB88IW2mcRw +S52CzP5H7wavwVsKQ9iZTsBWYwxiU2YCwjhx0v5WWZAnQfjjzA5vvFokWhrWDvca +auw= -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQC1QBVApOClQ+C0U4nfDeQMkRNLjm1Z5P3qRSDU15gspb6M1sWH diff --git a/ext/openssl/tests/bug65538.phar b/ext/openssl/tests/bug65538.phar index 3e10d5e..5eb1bd4 100644 --- a/ext/openssl/tests/bug65538.phar +++ b/ext/openssl/tests/bug65538.phar @@ -289,64 +289,64 @@ } Extract_Phar::go(); -__HALT_COMPILER(); ?>ebug54992-ca.pemcå‘\cø5R¶ bug54992.pem å‘\ ScÕ¶-----BEGIN CERTIFICATE----- -MIIGAzCCA+ugAwIBAgIUVL06vQzqQ1uRdJ7NAAZyylsKOpYwDQYJKoZIhvcNAQEL +__HALT_COMPILER(); ?>ebug54992-ca.pemcq¥K^c9À(0´ bug54992.pem q¥K^ σ´-----BEGIN CERTIFICATE----- +MIIGAzCCA+ugAwIBAgIUZOucIjT7OfT7rQQu4W5rghLGMYEwDQYJKoZIhvcNAQEL BQAwgZAxCzAJBgNVBAYTAlBUMQ8wDQYDVQQIDAZMaXNib2ExDzANBgNVBAcMBkxp c2JvYTEXMBUGA1UECgwOUEhQIEZvdW5kYXRpb24xHjAcBgNVBAMMFVJvb3QgQ0Eg Zm9yIFBIUCBUZXN0czEmMCQGCSqGSIb3DQEJARYXaW50ZXJuYWxzQGxpc3RzLnBo -cC5uZXQwHhcNMTgxMjAxMjEzNTUwWhcNMTgxMjMxMjEzNTUwWjCBkDELMAkGA1UE +cC5uZXQwHhcNMjAwMjE4MDg1MDM0WhcNMjEwMzI0MDg1MDM0WjCBkDELMAkGA1UE BhMCUFQxDzANBgNVBAgMBkxpc2JvYTEPMA0GA1UEBwwGTGlzYm9hMRcwFQYDVQQK DA5QSFAgRm91bmRhdGlvbjEeMBwGA1UEAwwVUm9vdCBDQSBmb3IgUEhQIFRlc3Rz MSYwJAYJKoZIhvcNAQkBFhdpbnRlcm5hbHNAbGlzdHMucGhwLm5ldDCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBANVgTLlHH3bNkxx+XA1xhr842rf+lP5A -XDhM5N9vRCXs/6FAB6iFAfnR+YVgcHD/ppgrrOlAIf6QF2J9EOA4h9oOtCrbhC9y -3uKT/dnPWpa39NAdHDJMl2GndulhfyNzXoPmHR+UmVl8RIwJa2yzq8kfI28VZOdG -4oW+L8hybO1r+7kewnI/3TQme+yxRMtI/RDAneBPUu4yx+VTy6gP1R7PMwEnMgLC -msdBEJh2FR2rjboejZiBAHRG5cWbmRlYV0ApDZAgaKbKGCgken7FF9mImduv7c9H -pHkSKAFdt5hYaeJJy48lh5wC7gMjBo62WKUnBqnV1gBBniWSfsgfNJKPV5a3EO32 -7KinHzzCH4V1C8tCU26om0CoRI+Bm/dpnwuDZWELzMnnyAeCmGWnPi2s/+QaWwKC -sMXn0+3CFYtlZ+zEZm0KB10RMypRLhn9md9/TfxJNNjDIHCMCLJkxyxFnYOWqtCd -zAA09r117AgM3tbRYY9NYvNzLw5hnPs2W3gB4vrUzqBcgdfIdVaE1QUyy8rWjMNI -fIVJVFeyN2mcg3JQw2WmKINDQJWZxXFJR9BPgISpR93BF5zIfGZSSRPuBXaXQ6j/ -9aw+fnA8asietOL2wGa60zqX1WKopNYvRlt6CCIYkFcfRRkoEjcMRpyVsSn2U9Dd -pFlDHq9iE6SLAgMBAAGjUzBRMB0GA1UdDgQWBBQKZYIWtrUo8Iv5zBWfBn40D7p9 -1DAfBgNVHSMEGDAWgBQKZYIWtrUo8Iv5zBWfBn40D7p91DAPBgNVHRMBAf8EBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAEJhZ6mMgRUJGF4dM5r+SfrwCTbNGDJkFz -DSbeb6WMTtvzL1g2P5zHQ0OvlX+mvmqCRXM40sUFMHDLCQzIgKLpgd44yZM6k4wL -hReX2okQ8tEwB73ahy/H3TaRr3B2l6s16kx4obDpyTsbrBZgiks515ru5EM2pv7x -31Ya2sUlXBWt+Kc+Z/6UI2Eot7G4M11oeRGpWnFBqPFAIByEbnCR4NCPbAKl2t2q -vhsQh0zAo9qB4uUyc/XblKKRtdupDnRceSCLg18ZwnBxrVZBuSK5oUCAwAFtE4BZ -G793gbwIUeR0pFgNMKkfPnXy3Ii8OmPDc9CsxO0Qg4Xh2VXWpVI+N5xL5L/M3O1i -UDDO2PeoaEVfz3htOCYo1U6BSQqMzg5JD2JifzKEscy3rFkpH21EHLg07Fv4ZSFo -HG22zt00dJpNatyAzzaYHlMel4K1fwNrGrUH5M2OeRtvkUMlDKwp8qrKIDpTi6vT -GW0woBoRlR1+qGGG9RHBqm937uhHJsLw8lFJmvO0ObqbdpdfW4nWugL8x1LZC9oz -uaH7hwj5i0SKK/StuLxAPP6cl4RqQhXO5rxEz2iFjl4nwwtRH3KPEDEAvQcnNXpi -2YV5z8C78j1amzbSJBlGpu3aoJNn+WPgjePmeBe7oE9t1/5kvIVIAj8kg6CaKfHz -6hiK1Erl8g== +KoZIhvcNAQEBBQADggIPADCCAgoCggIBANDtiwpbgpWNthaPNRpgjvNagqaq1EjS +19CNFq1+w5jRI8K130RvAWkDwnDcr70RSuNKhbJ2dEool3sUi8puNdvWLa8p95k9 +wg1HtCICixxIdLoYAzprkBJw7QUu/XH9SJeJRkYL7EUFoSDnQF9kbW1qMxZBRlFI +JEacK1crUBGekudu1DjHCM6dumyObrH4FYZtDdKHLu3PVTO299J7ILsHlAJ31qOG +zK96yBkjRomru/+Yr9ZjT915slvg19+PGLRSRLMXoolw+WEk5gc00/AsGqXQpavN +njDu9uw+33Eimrj8KnVsCh9cBQFmrCdqOdJmv8VwD63lcYLruAXkfHIUgdyeVMVT +Q8O+bgGQWaUrxRED4pJ932TicC23BhiZ/78/nyLwry473mHSIw4Y3M6kGSmEOs+3 +fDcsF8waqOeGXbgdOUjBTu92io+lGsCnUZBRe7sOus6aKHYDE1aBDeGtO4oALS+V +kNrbCh/VpRIwO9Ah4PvxweqW0ZdloW3TRIXRgRxmGJ9NFe1Rkvv7FB7i2l8IeAKS +ckuew31vxP6LgGUe5j/qt6xv6GOysefOCAAoHHeNEH+ZSlD1tiglvMVhsUmY9Rit +XEnB+X8FtOAM3SFiX5tsgB6n4hRKue5WkZywnbkPx7sDu4LQCA00i55dzjP/39M0 +yPnsQrJfOnj5AgMBAAGjUzBRMB0GA1UdDgQWBBSHvApjxItCycV/u9J4Z3b6UAP7 +jzAfBgNVHSMEGDAWgBSHvApjxItCycV/u9J4Z3b6UAP7jzAPBgNVHRMBAf8EBTAD +AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQB6ffwQmqI9Rq3qiPspJiFLsAT9Um8A/kd0 +unYdMyBRl9T0llGXBeN3YYrJLVAd01UAOSSDV3Cf8L2J2zvKRT8YbC3/LxB/RLIM +/eHVMGSxpy0S5U8HVChbYGEx/zC9p71HwL31Xj+NfOW1nFbEEPqSbGRmou+X2twZ +Omwz4Vm4MEpIQLRdgV5bLMN1SETH3TGwdMmTE2S8iKrqeDGB8NEl2LcDvbHAvPNw +KjitZRiicU99KzSSiGh7dsG/d9JsZqtCSmD+a2PesoUPSPsCaInLQG3aGkApt8Gl +TtFTxJo9QW7YWxFr9Efb2eU6UIilPSsVj8tvIfS1PRTTJrOlBpJDI6TL5YYtFuw3 +Ij27ILbXSwqUM5MIDYoRDxschNiMRhkRjmnebir2KQdvbt43rW8czwooOzTkd1Bi +RCAbUCAh1TqVu4vLGcoA8/Rf/1n4M8Zdgq19yfInmU4xs7kaiVvnnAxLSF1TmJl6 +8FCN7ONvHNNXciRkzIxw5Yn6GODa/e8Fzvaza/vkSvW4ry4Hu7T6ze10SuHagN3R +wwBGBlEI5FEyEKFsTZeHdDMoYzv7Ls4OXZzAo7B/Lwa4OTql7ApVw7MwHEplN3SS +1Qn4YhhmwJqiGvTGQZSA1gv6Ua/HPHjs1y1fSz+uRukUqlBemDhllmVjWHKJetOv ++FMLf6DmBw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIID7jCCAdYCFBDKe4ra5M5zJIb81D7zwFRmyHQGMA0GCSqGSIb3DQEBCwUAMIGQ +MIID7jCCAdYCFF2eDgBNSufPjQA1YmkSEu4tWGvTMA0GCSqGSIb3DQEBCwUAMIGQ MQswCQYDVQQGEwJQVDEPMA0GA1UECAwGTGlzYm9hMQ8wDQYDVQQHDAZMaXNib2Ex FzAVBgNVBAoMDlBIUCBGb3VuZGF0aW9uMR4wHAYDVQQDDBVSb290IENBIGZvciBQ SFAgVGVzdHMxJjAkBgkqhkiG9w0BCQEWF2ludGVybmFsc0BsaXN0cy5waHAubmV0 -MB4XDTE4MTIwMTIxNDU0MloXDTE4MTIzMTIxNDU0MlowWjEXMBUGA1UEAxMOYnVn +MB4XDTIwMDIxODA4NTA0N1oXDTIxMDMyNDA4NTA0N1owWjEXMBUGA1UEAxMOYnVn NTQ5OTIubG9jYWwxCzAJBgNVBAYTAlBUMQ8wDQYDVQQHEwZMaXNib2ExDzANBgNV BAgTBkxpc2JvYTEQMA4GA1UEChMHcGhwLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOB jQAwgYkCgYEAtUAVQKTgpUPgtFOJ3w3kDJETS45tWeT96kUg1NeYLKW+jNbFhxPo PJv7XhfemCaqh2tbq1cdYW906Wp1L+eNQvdTYA2IQG4EQBUlmfyIakOIMsN/RizV kF09vlNQwTpaMpqTv7wB8vvwbxb9jbC2ZhQUBEg6PIn18dSstbM9FZ0CAwEAATAN -BgkqhkiG9w0BAQsFAAOCAgEAid90+ulRK+4ifB2tKnt2MyuqXZexv2yQ4u15EYmE -NLOpP5ZWN8vSvRI3IGruNA00dX/F2EOT+u82ApOxzYyxceAx29Ytpt7PSd2nUqkN -TbDAsDTUZdoDLUa6dGPe5Faaai00nfNJ3lqmC9xPbBPKyJ3hjz0Uj6gi51Lfi410 -4GZa4oIL3NEIKVtaK942EAYCjeWx1VT8AnsvK4Nqufo97sbZNHJhgY+ApM168kox -kFA/RNYp/pNS0FCc8b9DwMnu38n2n33iDl3P54chpAcyuWJE5wL/kN2gnS6iMsLP -14NtBg2mm++4XqBpt9glmWr56HZtvyFW0IhpDwQgRe4GSIwPES2g1s7iUs3T4VdJ -aHkF4v8Bdl6DWXSVdbqIq8CpVZLhf7vt6pV/22YpVCjQFmiLtc8a4gWaYvpn6j+L -nAajb9JpdkNeqNiBxmtfQwL7xtY+1goLd9OKtIO1b2517ZRgU9NkUfLKCTl2W2L8 -sMY7FPVs6Z1jfaXw+vIWKCJKe0thf0HMV4q11ptsqpzyIzAAjAfma1b/MM5ATHsa -6h7Poh0yg+WMSdXurjhDWogOWrzPXSe0izUYpREkTVl1oLhzorxlEDh7vBLB2TS3 -TPAEdNxEbsIutMjoz5ql5dYxgZQGW7HARXrXhMbk6cBU8khNcGGqz1uzX1x7Vb2d -hKs= +BgkqhkiG9w0BAQsFAAOCAgEAEhDpl41vWZF9lGSlxz5uwIGguibrbeBYn/1PYpw4 +jF0i/DxNWYmAh/9vM/ClXhL9rVtHev88eO6goIDjiU2W59ksffxxw0Xno6XOgElb +8sdWBF4wLKiCuZrAYJ+N+CWKWkWFgsdBEHGktBk/UIh7Aw2LjVneMMj8lIgpDw9l +PfMZ1SAajBEh5D4TrM6TR3ImT2x0t4Rb1LOrfdn34eHHp/K1wpsZfDwzQKXF1RNb +XqQwzsB5kEMdOBC1ykOXcLqiUPxMakiVAfnt8w1UCdCB3TH63HkxATqoqZLXFYRX +JZRLkAUvoqdDNVP2gOYRewInWJL+EaRNt3P5DR8tEgCOUyw0UYgpI7KDHV5cL3MB +JKeLXmQu0o9ZviPk3saEdmhnSaPCGcVoF5E1vnSudcla7wz65U0w+bEX94DxGad/ +CrsGVS0VbdTV6lPQgcbP/IP4sxBUqZvpDlr20XzgsgdwCBgGwcJ47Y1zDQh17sAe +rZxhtxHG6PJbCwdj7z9FNgsMPmfFXoqcLFyN+N3vbGMpOaO6KCoylmFvNSQCwFrm +y/V+z5fQFe42trqLr04DEVw7rzGN6I8vyGPu7267FNDO5bdwuJ0FVjB88IW2mcRw +S52CzP5H7wavwVsKQ9iZTsBWYwxiU2YCwjhx0v5WWZAnQfjjzA5vvFokWhrWDvca +auw= -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQC1QBVApOClQ+C0U4nfDeQMkRNLjm1Z5P3qRSDU15gspb6M1sWH @@ -363,4 +363,4 @@ FqU0zPvrnBZ6Zwlgm2cSVQJAPLYA51Z9piajbTuggpioQ5qbUEDkJjmYHbm8eJnK h5NW/EtCk4SBxAc+8ElPrvJjtZyOPWfm4vZF5sDKtC3Fkg== -----END RSA PRIVATE KEY----- -.c{˜ÕTåU‘9oùõÚÝñ—ùSGBMB \ No newline at end of file +¡§¬–? =Æ)9Ö r…ÈËuÂGBMB \ No newline at end of file diff --git a/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt b/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt index 39d62b2..49ecaac 100644 --- a/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt +++ b/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt @@ -32,12 +32,17 @@ phpt_wait(); - // should be: 3610606deda596b3ae3859d33c4ce1d9 - stream_context_set_option($clientCtx, 'ssl', 'peer_fingerprint', '3610606deda596b3ae3859d33c4ce1da'); + // Run the following to get actual md5 (from sources root): + // openssl x509 -noout -fingerprint -md5 -inform pem -in ext/openssl/tests/bug54992.pem | cut -d '=' -f 2 | tr -d ':' | tr 'A-F' 'a-f' + // Currently it's 4edbbaf40a6a4b6af22b6d6d9818378f + // One below is intentionally broken (compare the last character): + stream_context_set_option($clientCtx, 'ssl', 'peer_fingerprint', '9aa2c02d62358f2fa0db575806e37799'); var_dump(stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx)); + // Run the following to get actual sha256 (from sources root): + // openssl x509 -noout -fingerprint -sha256 -inform pem -in ext/openssl/tests/bug54992.pem | cut -d '=' -f 2 | tr -d ':' | tr 'A-F' 'a-f' stream_context_set_option($clientCtx, 'ssl', 'peer_fingerprint', [ - 'sha256' => 'dffa72247ab7e44d94b2858528e3f67015925782148d2cf0b15cd82d1c931215', + 'sha256' => '62e70554daabf366ba9ada30d3af794ec421368e79b68f64dc9ed546d834ae7d', ]); var_dump(stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx)); CODE; diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 9e42a62..4c38f17 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3242,6 +3242,11 @@ { unsigned exif_value_2a, offset_of_ifd; + if (length < 2) { + exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Missing TIFF alignment marker"); + return; + } + /* set the thumbnail stuff to nothing so we can test to see if they get set up */ if (memcmp(CharBuf, "II", 2) == 0) { ImageInfo->motorola_intel = 0; @@ -3394,7 +3399,7 @@ return FALSE; } - sn = exif_file_sections_add(ImageInfo, marker, itemlen+1, NULL); + sn = exif_file_sections_add(ImageInfo, marker, itemlen, NULL); Data = ImageInfo->file.list[sn].data; /* Store first two pre-read bytes. */ --- /dev/null +++ b/ext/exif/tests/bug79282.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #79282: Use-of-uninitialized-value in exif +--FILE-- + +--EXPECTF-- +Warning: exif_read_data(): Invalid TIFF alignment marker in %s on line %d + +Warning: exif_read_data(): File structure corrupted in %s on line %d + +Warning: exif_read_data(): Invalid JPEG file in %s on line %d +bool(false) diff --git a/ext/standard/url.c b/ext/standard/url.c index 9c42afb..2990bd9 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -659,7 +659,7 @@ HashTable *hashT; zend_long format = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &url, &url_len, &format) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &url, &url_len, &format) == FAILURE) { return; } context = FG(default_context) ? FG(default_context) : (FG(default_context) = php_stream_context_alloc()); diff --git a/ext/standard/exec.c b/ext/standard/exec.c index d6f0cbf..e486f52 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -524,6 +524,15 @@ return; } + if (!command_len) { + php_error_docref(NULL, E_WARNING, "Cannot execute a blank command"); + RETURN_FALSE; + } + if (strlen(command) != command_len) { + php_error_docref(NULL, E_WARNING, "NULL byte detected. Possible attack"); + RETURN_FALSE; + } + #ifdef PHP_WIN32 if ((in=VCWD_POPEN(command, "rt"))==NULL) { #else diff --git a/ext/standard/url.c b/ext/standard/url.c index 2990bd9..a9cc06b 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -540,7 +540,7 @@ #ifndef CHARSET_EBCDIC *dest = (char) php_htoi(data + 1); #else - *dest = os_toebcdic[(char) php_htoi(data + 1)]; + *dest = os_toebcdic[(unsigned char) php_htoi(data + 1)]; #endif data += 2; len -= 2; @@ -632,7 +632,7 @@ #ifndef CHARSET_EBCDIC *dest = (char) php_htoi(data + 1); #else - *dest = os_toebcdic[(char) php_htoi(data + 1)]; + *dest = os_toebcdic[(unsigned char) php_htoi(data + 1)]; #endif data += 2; len -= 2; diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c index b12f30d..7fa3a7f 100644 --- a/Zend/zend_signal.c +++ b/Zend/zend_signal.c @@ -304,34 +304,45 @@ SIGG(active) = 1; SIGG(depth) = 0; + SIGG(check) = ZEND_DEBUG; } /* }}} */ /* {{{ zend_signal_deactivate * */ void zend_signal_deactivate(void) { - if (SIGG(check)) { int x; struct sigaction sa = {{0}}; if (SIGG(depth) != 0) { zend_error(E_CORE_WARNING, "zend_signal: shutdown with non-zero blocking depth (%d)", SIGG(depth)); } + /* did anyone steal our installed handler */ for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) { sigaction(zend_sigs[x], NULL, &sa); - if (sa.sa_sigaction != zend_signal_handler_defer) { + if (sa.sa_sigaction != zend_signal_handler_defer && + sa.sa_sigaction != (void *) SIG_IGN) { zend_error(E_CORE_WARNING, "zend_signal: handler was replaced for signal (%d) after startup", zend_sigs[x]); } } } - SIGNAL_BEGIN_CRITICAL(); - SIGG(active) = 0; + /* After active=0 is set, signal handlers will be called directly and other + * state that is reset below will not be accessed. */ + *((volatile int *) &SIGG(active)) = 0; + SIGG(running) = 0; SIGG(blocked) = 0; SIGG(depth) = 0; - SIGNAL_END_CRITICAL(); + + /* If there are any queued signals because of a missed unblock, drop them. */ + if (SIGG(phead) && SIGG(ptail)) { + SIGG(ptail)->next = SIGG(pavail); + SIGG(pavail) = SIGG(phead); + SIGG(phead) = NULL; + SIGG(ptail) = NULL; + } } /* }}} */ diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 5227601..2116726 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1478,7 +1478,9 @@ /* check blacklist right after ensuring that file was opened */ if (file_handle->opened_path && zend_accel_blacklist_is_blacklisted(&accel_blacklist, ZSTR_VAL(file_handle->opened_path))) { + SHM_UNPROTECT(); ZCSG(blacklist_misses)++; + SHM_PROTECT(); *op_array_p = accelerator_orig_compile_file(file_handle, type); return NULL; } @@ -1509,7 +1511,9 @@ } if (ZCG(accel_directives).max_file_size > 0 && size > (size_t)ZCG(accel_directives).max_file_size) { + SHM_UNPROTECT(); ZCSG(blacklist_misses)++; + SHM_PROTECT(); *op_array_p = accelerator_orig_compile_file(file_handle, type); return NULL; } @@ -1860,11 +1864,16 @@ return accelerator_orig_compile_file(file_handle, type); } + SHM_PROTECT(); + HANDLE_UNBLOCK_INTERRUPTIONS(); + persistent_script = opcache_compile_file(file_handle, type, key, key ? key_length : 0, &op_array); + HANDLE_BLOCK_INTERRUPTIONS(); + SHM_UNPROTECT(); + /* Try and cache the script and assume that it is returned from_shared_memory. * If it isn't compile_and_cache_file() changes the flag to 0 */ from_shared_memory = 0; - persistent_script = opcache_compile_file(file_handle, type, key, key ? key_length : 0, &op_array); if (persistent_script) { persistent_script = cache_script_in_shared_memory(persistent_script, key, key ? key_length : 0, &from_shared_memory); } @@ -1983,7 +1992,7 @@ zend_string *resolved_path; int key_length; char *key = NULL; - + if (!ZCG(accel_directives).revalidate_path) { /* lookup by "not-real" path */ key = accel_make_persistent_key(filename, filename_len, &key_length); diff --git a/main/main.c b/main/main.c index 93ac6ca..91f9ead 100644 --- a/main/main.c +++ b/main/main.c @@ -1882,6 +1882,11 @@ zend_unset_timeout(); } zend_end_try(); + /* 17. Deactivate Zend signals */ +#ifdef ZEND_SIGNALS + zend_signal_deactivate(); +#endif + #ifdef PHP_WIN32 if (PG(com_initialized)) { CoUninitialize(); diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index aee355b..8815e8a 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -1451,6 +1451,21 @@ ze_obj->filename = NULL; } +#if LIBZIP_VERSION_MAJOR > 1 || LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR >= 6 + /* reduce BC break introduce in libzip 1.6.0 + "Do not accept empty files as valid zip archives any longer" */ + + /* open for write without option to empty the archive */ + if ((flags & (ZIP_TRUNCATE | ZIP_RDONLY)) == 0) { + zend_stat_t st; + + /* exists and is empty */ + if (VCWD_STAT(resolved_path, &st) == 0 && st.st_size == 0) { + flags |= ZIP_TRUNCATE; + } + } +#endif + intern = zip_open(resolved_path, flags, &err); if (!intern || err) { efree(resolved_path); diff --git a/main/rfc1867.c b/main/rfc1867.c index 5949802..ee07ea5 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -690,7 +690,8 @@ char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL; char *lbuf = NULL, *abuf = NULL; zend_string *temp_filename = NULL; - int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0; + int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0; + size_t array_len = 0; int64_t total_bytes = 0, max_file_size = 0; int skip_upload = 0, anonindex = 0, is_anonymous; HashTable *uploaded_files = NULL; @@ -1124,7 +1125,7 @@ is_arr_upload = (start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ']'); if (is_arr_upload) { - array_len = (int)strlen(start_arr); + array_len = strlen(start_arr); if (array_index) { efree(array_index); } diff --git a/main/rfc1867.c b/main/rfc1867.c index ee07ea5..6159284 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -614,7 +614,7 @@ } /* read until a boundary condition */ -static int multipart_buffer_read(multipart_buffer *self, char *buf, size_t bytes, int *end) +static size_t multipart_buffer_read(multipart_buffer *self, char *buf, size_t bytes, int *end) { size_t len, max; char *bound; @@ -653,7 +653,7 @@ self->buf_begin += len; } - return (int)len; + return len; } /* @@ -663,7 +663,7 @@ static char *multipart_buffer_read_body(multipart_buffer *self, size_t *len) { char buf[FILLUNIT], *out=NULL; - int total_bytes=0, read_bytes=0; + size_t total_bytes=0, read_bytes=0; while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf), NULL))) { out = erealloc(out, total_bytes + read_bytes + 1); --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -704,7 +704,7 @@ efree(actual_alias); } - zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len, mydata); + zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata); } else { phar_archive_data *fd_ptr; diff --git a/NEWS b/NEWS index be7af22..bfde893 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,10 @@ Backported from 7.2.33 +- Core: + . Fixed bug #79877 (getimagesize function silently truncates after a null + byte) (cmb) + - Phar: . Fixed bug #79797 (Use of freed hash key in the phar_parse_zipfile function). (CVE-2020-7068) (cmb) diff --git a/ext/standard/image.c b/ext/standard/image.c index 2074d28..c2f4092 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -1403,6 +1403,11 @@ return; } + if (mode == FROM_PATH && CHECK_NULL_PATH(input, input_len)) { + php_error_docref(NULL, E_WARNING, "Invalid path"); + return; + } + if (argc == 2) { zval_dtor(info); array_init(info); --- /dev/null +++ b/ext/standard/tests/image/bug79877.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bug #79877 (getimagesize function silently truncates after a null byte) +--FILE-- + +--EXPECTF-- +Warning: getimagesize(): Invalid path in %s on line %d +NULL diff --git a/main/php_variables.c b/main/php_variables.c index d3cfb7f..50ecc66 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -464,7 +464,9 @@ size_t new_val_len; *val++ = '\0'; - php_url_decode(var, strlen(var)); + if (arg != PARSE_COOKIE) { + php_url_decode(var, strlen(var)); + } val_len = php_url_decode(val, strlen(val)); val = estrndup(val, val_len); if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) { @@ -475,7 +477,9 @@ size_t val_len; size_t new_val_len; - php_url_decode(var, strlen(var)); + if (arg != PARSE_COOKIE) { + php_url_decode(var, strlen(var)); + } val_len = 0; val = estrndup("", val_len); if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) { diff --git a/tests/basic/022.phpt b/tests/basic/022.phpt index 0ab70d4..bd1db13 100644 --- a/tests/basic/022.phpt +++ b/tests/basic/022.phpt @@ -10,7 +10,7 @@ var_dump($_COOKIE); ?> --EXPECT-- -array(10) { +array(12) { ["cookie1"]=> string(6) "val1 " ["cookie2"]=> @@ -19,11 +19,15 @@ string(6) "val 3." ["cookie_4"]=> string(10) " value 4 ;" + ["%20cookie1"]=> + string(6) "ignore" + ["+cookie1"]=> + string(6) "ignore" ["cookie__5"]=> string(7) " value" - ["cookie_6"]=> + ["cookie%206"]=> string(3) "þæö" - ["cookie_7"]=> + ["cookie+7"]=> string(0) "" ["$cookie_8"]=> string(0) "" diff --git a/tests/basic/023.phpt b/tests/basic/023.phpt index ca5f1dc..0e2e0ac 100644 --- a/tests/basic/023.phpt +++ b/tests/basic/023.phpt @@ -10,9 +10,11 @@ var_dump($_COOKIE); ?> --EXPECT-- -array(3) { +array(4) { ["c_o_o_k_i_e"]=> string(5) "value" + ["c%20o+o_k+i%20e"]=> + string(1) "v" ["name"]=> string(24) ""value","value",UEhQIQ==" ["UEhQIQ"]=> --- /dev/null +++ b/tests/basic/bug79699.phpt @@ -0,0 +1,22 @@ +--TEST-- +Cookies Security Bug +--INI-- +max_input_vars=1000 +filter.default=unsafe_raw +--COOKIE-- +__%48ost-evil=evil; __Host-evil=good; %66oo=baz;foo=bar +--FILE-- + +--EXPECT-- +array(4) { + ["__%48ost-evil"]=> + string(4) "evil" + ["__Host-evil"]=> + string(4) "good" + ["%66oo"]=> + string(3) "baz" + ["foo"]=> + string(3) "bar" +} diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt index e172061..80e164a 100644 --- a/ext/standard/tests/strings/url_t.phpt +++ b/ext/standard/tests/strings/url_t.phpt @@ -575,15 +575,13 @@ string(16) "some_page_ref123" } ---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { +--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { ["scheme"]=> string(4) "http" ["host"]=> - string(11) "www.php.net" + string(26) "secret@hideout@www.php.net" ["port"]=> int(80) - ["user"]=> - string(14) "secret@hideout" ["path"]=> string(10) "/index.php" ["query"]=> --- /dev/null +++ b/ext/standard/tests/url/bug77423.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #77423 (parse_url() will deliver a wrong host to user) +--FILE-- + +--EXPECT-- +bool(false) +array(3) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(19) "php.net\@aliyun.com" + ["path"]=> + string(7) "/aaa.do" +} +bool(false) +array(2) { + ["scheme"]=> + string(5) "https" + ["host"]=> + string(26) "example.com\uFF03@bing.com" +} diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt index e468066..c9e9d32 100644 --- a/ext/standard/tests/url/parse_url_basic_001.phpt +++ b/ext/standard/tests/url/parse_url_basic_001.phpt @@ -507,15 +507,13 @@ string(16) "some_page_ref123" } ---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { +--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { ["scheme"]=> string(4) "http" ["host"]=> - string(11) "www.php.net" + string(26) "secret@hideout@www.php.net" ["port"]=> int(80) - ["user"]=> - string(14) "secret@hideout" ["path"]=> string(10) "/index.php" ["query"]=> diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt index 70dc4bb..431de27 100644 --- a/ext/standard/tests/url/parse_url_basic_003.phpt +++ b/ext/standard/tests/url/parse_url_basic_003.phpt @@ -68,7 +68,7 @@ --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" ---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" +--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(26) "secret@hideout@www.php.net" --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" --> nntp://news.php.net : string(12) "news.php.net" --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : string(11) "ftp.gnu.org" diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt index b2ca06f..b2c1a1d 100644 --- a/ext/standard/tests/url/parse_url_basic_005.phpt +++ b/ext/standard/tests/url/parse_url_basic_005.phpt @@ -68,7 +68,7 @@ --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(0) "" --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" ---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(14) "secret@hideout" +--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" --> nntp://news.php.net : NULL --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : NULL diff --git a/ext/standard/url.c b/ext/standard/url.c index a9cc06b..3bb62c7 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -92,6 +92,22 @@ return php_url_parse_ex(str, strlen(str)); } +static int is_userinfo_valid(const char *str, size_t len) +{ + char *valid = "-._~!$&'()*+,;=:"; + char *p = str; + while (p - str < len) { + if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) { + p++; + } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) { + p += 3; + } else { + return 0; + } + } + return 1; +} + /* {{{ php_url_parse */ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) @@ -235,13 +251,18 @@ ret->pass = estrndup(pp, (p-pp)); php_replace_controlchars_ex(ret->pass, (p-pp)); } else { + if (!is_userinfo_valid(s, p-s)) { + goto check_port; + } ret->user = estrndup(s, (p-s)); php_replace_controlchars_ex(ret->user, (p-s)); + } s = p + 1; } +check_port: /* check for port */ if (s < ue && *s == '[' && *(e-1) == ']') { /* Short circuit portscan, --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -314,6 +314,8 @@ ctx->context = NULL; } +#define SAFE_STR(a) ((a)?a:"") + static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include) { sdlPtr tmpsdl = ctx->sdl; @@ -375,7 +377,7 @@ if (node_is_equal_ex(trav2, "schema", XSD_NAMESPACE)) { load_schema(ctx, trav2); } else if (is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name)); } trav2 = trav2->next; } @@ -436,7 +438,7 @@ soap_error0(E_ERROR, "Parsing WSDL: has no name attribute"); } } else if (!node_is_equal(trav,"documentation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name)); } trav = trav->next; } @@ -546,7 +548,7 @@ } smart_str_free(&key); } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name)); } trav = trav->next; } @@ -648,7 +650,7 @@ } smart_str_free(&key); } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name)); } trav = trav->next; } @@ -680,14 +682,14 @@ sdlParamPtr param; if (trav->ns != NULL && strcmp((char*)trav->ns->href, WSDL_NAMESPACE) != 0) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", trav->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", SAFE_STR(trav->name)); } if (node_is_equal(trav,"documentation")) { trav = trav->next; continue; } if (!node_is_equal(trav,"part")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name)); } part = trav; param = emalloc(sizeof(sdlParam)); @@ -696,7 +698,7 @@ name = get_attribute(part->properties, "name"); if (name == NULL) { - soap_error1(E_ERROR, "Parsing WSDL: No name associated with '%s'", message->name); + soap_error1(E_ERROR, "Parsing WSDL: No name associated with '%s'", SAFE_STR(message->name)); } param->paramName = estrdup((char*)name->children->content); @@ -765,7 +767,7 @@ continue; } if (!node_is_equal(trav,"port")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name)); } port = trav; @@ -804,7 +806,7 @@ } } if (trav2 != address && is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name)); } trav2 = trav2->next; } @@ -906,7 +908,7 @@ continue; } if (!node_is_equal(trav2,"operation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name)); } operation = trav2; @@ -925,7 +927,7 @@ !node_is_equal(trav3,"output") && !node_is_equal(trav3,"fault") && !node_is_equal(trav3,"documentation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav3->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav3->name)); } trav3 = trav3->next; } @@ -1103,7 +1105,7 @@ } } } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) { - soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name); + soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name)); } trav = trav->next; } diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index fb00c42..a9c6a56 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -204,7 +204,7 @@ int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns) { - if (name == NULL || strcmp((char*)node->name, name) == 0) { + if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) { if (ns) { xmlNsPtr nsPtr = attr_find_ns(node); if (nsPtr) { @@ -220,7 +220,7 @@ int node_is_equal_ex(xmlNodePtr node, char *name, char *ns) { - if (name == NULL || strcmp((char*)node->name, name) == 0) { + if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) { if (ns) { xmlNsPtr nsPtr = node_find_ns(node); if (nsPtr) { --- /dev/null +++ b/ext/soap/tests/bug80672.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #80672 Null Dereference in SoapClient +--SKIPIF-- + +--FILE-- +query(array('sXML' => 'something')); +} catch(SoapFault $e) { + print $e->getMessage(); +} +?> +--EXPECTF-- +SOAP-ERROR: Parsing WSDL: Unexpected WSDL element <> \ No newline at end of file --- /dev/null +++ b/ext/soap/tests/bug80672.xml @@ -0,0 +1,6 @@ + + + + diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c index 011cbc0..5f8c0da 100644 --- a/ext/imap/php_imap.c +++ b/ext/imap/php_imap.c @@ -3531,6 +3531,23 @@ } /* }}} */ +static zend_bool header_injection(zend_string *str, zend_bool adrlist) +{ + char *p = ZSTR_VAL(str); + + while ((p = strpbrk(p, "\r\n")) != NULL) { + if (!(p[0] == '\r' && p[1] == '\n') + /* adrlists do not support folding, but swallow trailing line breaks */ + && !((adrlist && p[1] == '\0') + /* other headers support folding */ + || !adrlist && (p[1] == ' ' || p[1] == '\t'))) { + return 1; + } + p++; + } + return 0; +} + /* {{{ proto string imap_mail_compose(array envelope, array body) Create a MIME message based on given envelope and body sections */ PHP_FUNCTION(imap_mail_compose) @@ -3551,6 +3568,13 @@ return; } +#define CHECK_HEADER_INJECTION(zstr, adrlist, header) \ + if (header_injection(zstr, adrlist)) { \ + php_error_docref(NULL, E_WARNING, "header injection attempt in " header); \ + RETVAL_FALSE; \ + goto done; \ + } + #define PHP_RFC822_PARSE_ADRLIST(target, value) \ str_copy = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); \ rfc822_parse_adrlist(target, str_copy, "NO HOST"); \ @@ -3559,46 +3583,57 @@ env = mail_newenvelope(); if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "remail", sizeof("remail") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "remail"); env->remail = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "return_path", sizeof("return_path") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "return_path"); PHP_RFC822_PARSE_ADRLIST(&env->return_path, pvalue); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "date", sizeof("date") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "date"); env->date = (unsigned char*)cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "from", sizeof("from") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "from"); PHP_RFC822_PARSE_ADRLIST(&env->from, pvalue); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "reply_to", sizeof("reply_to") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "reply_to"); PHP_RFC822_PARSE_ADRLIST(&env->reply_to, pvalue); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "in_reply_to", sizeof("in_reply_to") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "in_reply_to"); env->in_reply_to = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "subject", sizeof("subject") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "subject"); env->subject = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "to", sizeof("to") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "to"); PHP_RFC822_PARSE_ADRLIST(&env->to, pvalue); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "cc", sizeof("cc") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "cc"); PHP_RFC822_PARSE_ADRLIST(&env->cc, pvalue); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "bcc", sizeof("bcc") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "bcc"); PHP_RFC822_PARSE_ADRLIST(&env->bcc, pvalue); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "message_id", sizeof("message_id") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "message_id"); env->message_id=cpystr(Z_STRVAL_P(pvalue)); } @@ -3608,6 +3643,7 @@ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pvalue), env_data) { custom_headers_param = mail_newbody_parameter(); convert_to_string_ex(env_data); + CHECK_HEADER_INJECTION(Z_STR_P(env_data), 0, "custom_headers"); custom_headers_param->value = (char *) fs_get(Z_STRLEN_P(env_data) + 1); custom_headers_param->attribute = NULL; memcpy(custom_headers_param->value, Z_STRVAL_P(env_data), Z_STRLEN_P(env_data) + 1); @@ -3640,6 +3676,7 @@ } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset"); tmp_param = mail_newbody_parameter(); tmp_param->value = cpystr(Z_STRVAL_P(pvalue)); tmp_param->attribute = cpystr("CHARSET"); @@ -3650,9 +3687,11 @@ if(Z_TYPE_P(pvalue) == IS_ARRAY) { disp_param = tmp_param = NULL; ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { + CHECK_HEADER_INJECTION(key, 0, "body disposition key"); disp_param = mail_newbody_parameter(); disp_param->attribute = cpystr(ZSTR_VAL(key)); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value"); disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); disp_param->next = tmp_param; @@ -3663,18 +3702,22 @@ } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype"); bod->subtype = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id"); bod->id = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description"); bod->description = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type"); bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1); memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1); } @@ -3682,9 +3725,11 @@ if (Z_TYPE_P(pvalue) == IS_ARRAY) { disp_param = tmp_param = NULL; ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { + CHECK_HEADER_INJECTION(key, 0, "body type.parameters key"); disp_param = mail_newbody_parameter(); disp_param->attribute = cpystr(ZSTR_VAL(key)); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value"); disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); disp_param->next = tmp_param; @@ -3713,6 +3758,7 @@ } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5"); bod->md5 = cpystr(Z_STRVAL_P(pvalue)); } } else if (Z_TYPE_P(data) == IS_ARRAY) { @@ -3743,6 +3789,7 @@ } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset"); tmp_param = mail_newbody_parameter(); tmp_param->value = (char *) fs_get(Z_STRLEN_P(pvalue) + 1); memcpy(tmp_param->value, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue) + 1); @@ -3754,9 +3801,11 @@ if (Z_TYPE_P(pvalue) == IS_ARRAY) { disp_param = tmp_param = NULL; ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { + CHECK_HEADER_INJECTION(key, 0, "body type.parameters key"); disp_param = mail_newbody_parameter(); disp_param->attribute = cpystr(ZSTR_VAL(key)); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value"); disp_param->value = (char *)fs_get(Z_STRLEN_P(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); disp_param->next = tmp_param; @@ -3767,18 +3816,22 @@ } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype"); bod->subtype = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id"); bod->id = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description"); bod->description = cpystr(Z_STRVAL_P(pvalue)); } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type"); bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1); memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1); } @@ -3786,9 +3839,11 @@ if (Z_TYPE_P(pvalue) == IS_ARRAY) { disp_param = tmp_param = NULL; ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { + CHECK_HEADER_INJECTION(key, 0, "body disposition key"); disp_param = mail_newbody_parameter(); disp_param->attribute = cpystr(ZSTR_VAL(key)); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value"); disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); disp_param->next = tmp_param; @@ -3817,6 +3872,7 @@ } if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5"); bod->md5 = cpystr(Z_STRVAL_P(pvalue)); } } --- /dev/null +++ b/ext/imap/tests/bug80710_1.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #80710 (imap_mail_compose() header injection) - MIME Splitting Attack +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imap_mail_compose(): header injection attempt in from in %s on line %d --- /dev/null +++ b/ext/imap/tests/bug80710_2.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #80710 (imap_mail_compose() header injection) - Remail +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imap_mail_compose(): header injection attempt in remail in %s on line %d diff --git a/ext/interbase/config.m4 b/ext/interbase/config.m4 index ace3047..5b4cde5 100644 --- a/ext/interbase/config.m4 +++ b/ext/interbase/config.m4 @@ -3,39 +3,54 @@ install directory [/opt/firebird]]) if test "$PHP_INTERBASE" != "no"; then - if test "$PHP_INTERBASE" = "yes"; then - IBASE_INCDIR=/opt/firebird/include - IBASE_LIBDIR=/opt/firebird/lib + + AC_PATH_PROG(FB_CONFIG, fb_config, no) + + if test -x "$FB_CONFIG" && test "$PHP_INTERBASE" = "yes"; then + AC_MSG_CHECKING(for libfbconfig) + FB_CFLAGS=`$FB_CONFIG --cflags` + FB_LIBDIR=`$FB_CONFIG --libs` + FB_VERSION=`$FB_CONFIG --version` + AC_MSG_RESULT(version $FB_VERSION) + PHP_EVAL_LIBLINE($FB_LIBDIR, INTERBASE_SHARED_LIBADD) + PHP_EVAL_INCLINE($FB_CFLAGS) + else - IBASE_INCDIR=$PHP_INTERBASE/include - IBASE_LIBDIR=$PHP_INTERBASE/$PHP_LIBDIR - fi + if test "$PHP_INTERBASE" = "yes"; then + IBASE_INCDIR=/opt/firebird/include + IBASE_LIBDIR=/opt/firebird/lib + else + IBASE_INCDIR=$PHP_INTERBASE/include + IBASE_LIBDIR=$PHP_INTERBASE/$PHP_LIBDIR + fi - PHP_CHECK_LIBRARY(fbclient, isc_detach_database, - [ - IBASE_LIBNAME=fbclient - ], [ - PHP_CHECK_LIBRARY(gds, isc_detach_database, + PHP_CHECK_LIBRARY(fbclient, isc_detach_database, [ - IBASE_LIBNAME=gds + IBASE_LIBNAME=fbclient ], [ - PHP_CHECK_LIBRARY(ib_util, isc_detach_database, + PHP_CHECK_LIBRARY(gds, isc_detach_database, [ - IBASE_LIBNAME=ib_util + IBASE_LIBNAME=gds ], [ - AC_MSG_ERROR([libfbclient, libgds or libib_util not found! Check config.log for more information.]) + PHP_CHECK_LIBRARY(ib_util, isc_detach_database, + [ + IBASE_LIBNAME=ib_util + ], [ + AC_MSG_ERROR([libfbclient, libgds or libib_util not found! Check config.log for more information.]) + ], [ + -L$IBASE_LIBDIR + ]) ], [ -L$IBASE_LIBDIR ]) ], [ -L$IBASE_LIBDIR ]) - ], [ - -L$IBASE_LIBDIR - ]) - PHP_ADD_LIBRARY_WITH_PATH($IBASE_LIBNAME, $IBASE_LIBDIR, INTERBASE_SHARED_LIBADD) - PHP_ADD_INCLUDE($IBASE_INCDIR) + PHP_ADD_LIBRARY_WITH_PATH($IBASE_LIBNAME, $IBASE_LIBDIR, INTERBASE_SHARED_LIBADD) + PHP_ADD_INCLUDE($IBASE_INCDIR) + fi + AC_DEFINE(HAVE_IBASE,1,[ ]) PHP_NEW_EXTENSION(interbase, interbase.c ibase_query.c ibase_service.c ibase_events.c ibase_blobs.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_SUBST(INTERBASE_SHARED_LIBADD) diff --git a/ext/pdo_firebird/config.m4 b/ext/pdo_firebird/config.m4 index f9188a0..e6362cd 100644 --- a/ext/pdo_firebird/config.m4 +++ b/ext/pdo_firebird/config.m4 @@ -8,43 +8,56 @@ AC_MSG_ERROR([PDO is not enabled! Add --enable-pdo to your configure line.]) fi - if test "$PHP_PDO_FIREBIRD" = "yes"; then - FIREBIRD_INCDIR= - FIREBIRD_LIBDIR= - FIREBIRD_LIBDIR_FLAG= + AC_PATH_PROG(FB_CONFIG, fb_config, no) + + if test -x "$FB_CONFIG" && test "$PHP_PDO_FIREBIRD" = "yes"; then + AC_MSG_CHECKING(for libfbconfig) + FB_CFLAGS=`$FB_CONFIG --cflags` + FB_LIBDIR=`$FB_CONFIG --libs` + FB_VERSION=`$FB_CONFIG --version` + AC_MSG_RESULT(version $FB_VERSION) + PHP_EVAL_LIBLINE($FB_LIBDIR, PDO_FIREBIRD_SHARED_LIBADD) + PHP_EVAL_INCLINE($FB_CFLAGS) + else - FIREBIRD_INCDIR=$PHP_PDO_FIREBIRD/include - FIREBIRD_LIBDIR=$PHP_PDO_FIREBIRD/$PHP_LIBDIR - FIREBIRD_LIBDIR_FLAG=-L$FIREBIRD_LIBDIR - fi + if test "$PHP_PDO_FIREBIRD" = "yes"; then + FIREBIRD_INCDIR= + FIREBIRD_LIBDIR= + FIREBIRD_LIBDIR_FLAG= + else + FIREBIRD_INCDIR=$PHP_PDO_FIREBIRD/include + FIREBIRD_LIBDIR=$PHP_PDO_FIREBIRD/$PHP_LIBDIR + FIREBIRD_LIBDIR_FLAG=-L$FIREBIRD_LIBDIR + fi - PHP_CHECK_LIBRARY(fbclient, isc_detach_database, - [ - FIREBIRD_LIBNAME=fbclient - ], [ - PHP_CHECK_LIBRARY(gds, isc_detach_database, + PHP_CHECK_LIBRARY(fbclient, isc_detach_database, [ - FIREBIRD_LIBNAME=gds + FIREBIRD_LIBNAME=fbclient ], [ - PHP_CHECK_LIBRARY(ib_util, isc_detach_database, + PHP_CHECK_LIBRARY(gds, isc_detach_database, [ - FIREBIRD_LIBNAME=ib_util + FIREBIRD_LIBNAME=gds ], [ - AC_MSG_ERROR([libfbclient, libgds or libib_util not found! Check config.log for more information.]) + PHP_CHECK_LIBRARY(ib_util, isc_detach_database, + [ + FIREBIRD_LIBNAME=ib_util + ], [ + AC_MSG_ERROR([libfbclient, libgds or libib_util not found! Check config.log for more information.]) + ], [ + $FIREBIRD_LIBDIR_FLAG + ]) ], [ $FIREBIRD_LIBDIR_FLAG ]) ], [ $FIREBIRD_LIBDIR_FLAG ]) - ], [ - $FIREBIRD_LIBDIR_FLAG - ]) + PHP_ADD_LIBRARY_WITH_PATH($FIREBIRD_LIBNAME, $FIREBIRD_LIBDIR, PDO_FIREBIRD_SHARED_LIBADD) + PHP_ADD_INCLUDE($FIREBIRD_INCDIR) + fi PHP_CHECK_PDO_INCLUDES - PHP_ADD_LIBRARY_WITH_PATH($FIREBIRD_LIBNAME, $FIREBIRD_LIBDIR, PDO_FIREBIRD_SHARED_LIBADD) - PHP_ADD_INCLUDE($FIREBIRD_INCDIR) AC_DEFINE(HAVE_PDO_FIREBIRD,1,[ ]) PHP_NEW_EXTENSION(pdo_firebird, pdo_firebird.c firebird_driver.c firebird_statement.c, $ext_shared,,-I$pdo_cv_inc_path) PHP_SUBST(PDO_FIREBIRD_SHARED_LIBADD) diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 3feeedf..88be6da 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -294,7 +294,7 @@ unsigned short seg_len; ISC_STATUS stat; - *ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1); + *ptr = S->fetch_buf[colno] = erealloc(S->fetch_buf[colno], *len+1); for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) { --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76488.phpt @@ -0,0 +1,32 @@ +--TEST-- +PDO_Firebird: Bug #76488 Memory leak when fetching a BLOB field +--SKIPIF-- + +--FILE-- +prepare($sql); + $sth->execute(); + $rows = $sth->fetchAll(); + unset($rows); + unset($sth); + } + unset($dbh); + echo "OK"; +?> +--EXPECT-- +OK \ No newline at end of file diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index fde8971..537f6f4 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -133,8 +133,14 @@ } if (result[0] == isc_info_sql_records) { unsigned i = 3, result_size = isc_vax_integer(&result[1], 2); + if (result_size > sizeof(result)) { + goto error; + } while (result[i] != isc_info_end && i < result_size) { short len = (short) isc_vax_integer(&result[i + 1], 2); + if (len != 1 && len != 2 && len != 4) { + goto error; + } if (result[i] != isc_info_req_select_count) { affected_rows += isc_vax_integer(&result[i + 3], len); } @@ -158,6 +164,7 @@ return 1; } while (0); +error: RECORD_ERROR(stmt); return 0; --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76450.data @@ -0,0 +1 @@ +^ÿÿ€ Legacy_Auth\ Legacy_Auth      !ÿÿþÿ   ÿÿÿÿ   \ No newline at end of file --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76450.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #76450 (SIGSEGV in firebird_stmt_execute) +--SKIPIF-- + +--FILE-- + PDO::ERRMODE_EXCEPTION]); +$sql = "EXECUTE PROCEDURE test_proc 123"; +$query = $dbh->prepare($sql); +try { + $query->execute(); +} catch (Exception $ex) { + echo "{$ex->getMessage()}\n"; +} +?> +--EXPECT-- +SQLSTATE[HY000]: General error diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 2420489..8481d03 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -252,8 +252,17 @@ if (result[0] == isc_info_sql_records) { unsigned i = 3, result_size = isc_vax_integer(&result[1],2); + if (result_size > sizeof(result)) { + ret = -1; + goto free_statement; + } while (result[i] != isc_info_end && i < result_size) { short len = (short)isc_vax_integer(&result[i+1],2); + /* bail out on bad len */ + if (len != 1 && len != 2 && len != 4) { + ret = -1; + goto free_statement; + } if (result[i] != isc_info_req_select_count) { ret += isc_vax_integer(&result[i+3],len); } --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76449.data @@ -0,0 +1 @@ +^ÿÿ€ Legacy_Auth\ Legacy_Auth      !ÿÿþÿ   ÿÿÿÿ   \ No newline at end of file --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76449.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #76449 (SIGSEGV in firebird_handle_doer) +--SKIPIF-- + +--FILE-- + PDO::ERRMODE_EXCEPTION]); +var_dump($dbh->exec("INSERT INTO test VALUES ('hihi2', 'xxxxx')")); +?> +--EXPECT-- +bool(false) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 8481d03..cfcae47 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -555,14 +555,16 @@ } /* }}} */ +#define INFO_BUF_LEN 512 + /* callback to used to report database server info */ static void firebird_info_cb(void *arg, char const *s) /* {{{ */ { if (arg) { if (*(char*)arg) { /* second call */ - strcat(arg, " "); + strlcat(arg, " ", INFO_BUF_LEN); } - strcat(arg, s); + strlcat(arg, s, INFO_BUF_LEN); } } /* }}} */ @@ -573,7 +575,7 @@ pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; switch (attr) { - char tmp[512]; + char tmp[INFO_BUF_LEN]; case PDO_ATTR_AUTOCOMMIT: ZVAL_LONG(val,dbh->auto_commit); --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76448.data @@ -0,0 +1 @@ +^ÿÿ€ Legacy_Auth\ Legacy_Auth   @g$"WI-T4.0.0.998 Firebird 4.0 Alpha 1ÿWI-T4.0.0.998 Firebird 4.0 Alpha 1/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DDr  \ No newline at end of file --- /dev/null +++ b/ext/pdo_firebird/tests/bug_76448.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #76448 (Stack buffer overflow in firebird_info_cb) +--SKIPIF-- + +--FILE-- + PDO::ERRMODE_EXCEPTION]); +var_dump($dbh->getAttribute(PDO::ATTR_SERVER_INFO)); +?> +--EXPECT-- +bool(false) diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c index b48fa54..c7f97fd 100644 --- a/sapi/fpm/fpm/fpm_children.c +++ b/sapi/fpm/fpm/fpm_children.c @@ -239,7 +239,7 @@ fpm_child_unlink(child); - fpm_scoreboard_proc_free(wp->scoreboard, child->scoreboard_i); + fpm_scoreboard_proc_free(child); fpm_clock_get(&tv1); @@ -249,9 +249,9 @@ if (!fpm_pctl_can_spawn_children()) { severity = ZLOG_DEBUG; } - zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec); + zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec); } else { - zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec); + zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec); } fpm_child_close(child, 1 /* in event_loop */); @@ -317,7 +317,7 @@ return 0; } - if (0 > fpm_scoreboard_proc_alloc(wp->scoreboard, &c->scoreboard_i)) { + if (0 > fpm_scoreboard_proc_alloc(c)) { fpm_stdio_discard_pipes(c); fpm_child_free(c); return 0; @@ -329,7 +329,7 @@ static void fpm_resources_discard(struct fpm_child_s *child) /* {{{ */ { - fpm_scoreboard_proc_free(child->wp->scoreboard, child->scoreboard_i); + fpm_scoreboard_proc_free(child); fpm_stdio_discard_pipes(child); fpm_child_free(child); } @@ -342,10 +342,10 @@ if (wp == child->wp) { continue; } - fpm_scoreboard_free(wp->scoreboard); + fpm_scoreboard_free(wp); } - fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, getpid()); + fpm_scoreboard_child_use(child, getpid()); fpm_stdio_child_use_pipes(child); fpm_child_free(child); } diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c index 3f82a7d..a707fd2 100644 --- a/sapi/fpm/fpm/fpm_request.c +++ b/sapi/fpm/fpm/fpm_request.c @@ -287,7 +287,7 @@ struct fpm_scoreboard_proc_s *proc; /* no need in atomicity here */ - proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i); + proc = fpm_scoreboard_proc_get_from_child(child); if (!proc) { return 0; } @@ -302,7 +302,7 @@ if (!tv) return -1; - proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i); + proc = fpm_scoreboard_proc_get_from_child(child); if (!proc) { return -1; } diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 5693ce4..45d44f4 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -8,6 +8,7 @@ #include #include "fpm_config.h" +#include "fpm_children.h" #include "fpm_scoreboard.h" #include "fpm_shm.h" #include "fpm_sockets.h" @@ -25,7 +26,6 @@ int fpm_scoreboard_init_main() /* {{{ */ { struct fpm_worker_pool_s *wp; - unsigned int i; #ifdef HAVE_TIMES #if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)) @@ -42,7 +42,7 @@ for (wp = fpm_worker_all_pools; wp; wp = wp->next) { - size_t scoreboard_size, scoreboard_nprocs_size; + size_t scoreboard_procs_size; void *shm_mem; if (wp->config->pm_max_children < 1) { @@ -55,22 +55,15 @@ return -1; } - scoreboard_size = sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children) * sizeof(struct fpm_scoreboard_proc_s *); - scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children; - shm_mem = fpm_shm_alloc(scoreboard_size + scoreboard_nprocs_size); + scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children; + shm_mem = fpm_shm_alloc(sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size); if (!shm_mem) { return -1; } - wp->scoreboard = shm_mem; + wp->scoreboard = shm_mem; + wp->scoreboard->pm = wp->config->pm; wp->scoreboard->nprocs = wp->config->pm_max_children; - shm_mem += scoreboard_size; - - for (i = 0; i < wp->scoreboard->nprocs; i++, shm_mem += sizeof(struct fpm_scoreboard_proc_s)) { - wp->scoreboard->procs[i] = shm_mem; - } - - wp->scoreboard->pm = wp->config->pm; wp->scoreboard->start_epoch = time(NULL); strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool)); } @@ -164,28 +157,47 @@ } /* }}} */ -struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/ +static inline struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_ex( + struct fpm_scoreboard_s *scoreboard, int child_index, unsigned int nprocs) /* {{{*/ { if (!scoreboard) { - scoreboard = fpm_scoreboard; + return NULL; } - if (!scoreboard) { + if (child_index < 0 || (unsigned int)child_index >= nprocs) { return NULL; } + return &scoreboard->procs[child_index]; +} +/* }}} */ + +struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get( + struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/ +{ + if (!scoreboard) { + scoreboard = fpm_scoreboard; + } + if (child_index < 0) { child_index = fpm_scoreboard_i; } - if (child_index < 0 || child_index >= scoreboard->nprocs) { - return NULL; - } + return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->nprocs); +} + +struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/ +{ + struct fpm_worker_pool_s *wp = child->wp; + unsigned int nprocs = wp->config->pm_max_children; + struct fpm_scoreboard_s *scoreboard = wp->scoreboard; + int child_index = child->scoreboard_i; - return scoreboard->procs[child_index]; + return fpm_scoreboard_proc_get_ex(scoreboard, child_index, nprocs); } /* }}} */ + struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */ { struct fpm_scoreboard_s *s; @@ -236,28 +248,28 @@ proc->lock = 0; } -void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard) /* {{{ */ +void fpm_scoreboard_free(struct fpm_worker_pool_s *wp) /* {{{ */ { - size_t scoreboard_size, scoreboard_nprocs_size; + size_t scoreboard_procs_size; + struct fpm_scoreboard_s *scoreboard = wp->scoreboard; if (!scoreboard) { zlog(ZLOG_ERROR, "**scoreboard is NULL"); return; } - scoreboard_size = sizeof(struct fpm_scoreboard_s) + (scoreboard->nprocs) * sizeof(struct fpm_scoreboard_proc_s *); - scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs; - - fpm_shm_free(scoreboard, scoreboard_size + scoreboard_nprocs_size); + scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children; + + fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size); } /* }}} */ -void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */ +void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid) /* {{{ */ { struct fpm_scoreboard_proc_s *proc; - fpm_scoreboard = scoreboard; - fpm_scoreboard_i = child_index; - proc = fpm_scoreboard_proc_get(scoreboard, child_index); + fpm_scoreboard = child->wp->scoreboard; + fpm_scoreboard_i = child->scoreboard_i; + proc = fpm_scoreboard_proc_get_from_child(child); if (!proc) { return; } @@ -266,18 +278,22 @@ } /* }}} */ -void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{ */ +void fpm_scoreboard_proc_free(struct fpm_child_s *child) /* {{{ */ { + struct fpm_worker_pool_s *wp = child->wp; + struct fpm_scoreboard_s *scoreboard = wp->scoreboard; + int child_index = child->scoreboard_i; + if (!scoreboard) { return; } - if (child_index < 0 || child_index >= scoreboard->nprocs) { + if (child_index < 0 || child_index >= wp->config->pm_max_children) { return; } - if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) { - memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s)); + if (scoreboard->procs[child_index].used > 0) { + memset(&scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s)); } /* set this slot as free to avoid search on next alloc */ @@ -285,41 +301,44 @@ } /* }}} */ -int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index) /* {{{ */ +int fpm_scoreboard_proc_alloc(struct fpm_child_s *child) /* {{{ */ { int i = -1; + struct fpm_worker_pool_s *wp = child->wp; + struct fpm_scoreboard_s *scoreboard = wp->scoreboard; + int nprocs = wp->config->pm_max_children; - if (!scoreboard || !child_index) { + if (!scoreboard) { return -1; } /* first try the slot which is supposed to be free */ - if (scoreboard->free_proc >= 0 && scoreboard->free_proc < scoreboard->nprocs) { - if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) { + if (scoreboard->free_proc >= 0 && scoreboard->free_proc < nprocs) { + if (!scoreboard->procs[scoreboard->free_proc].used) { i = scoreboard->free_proc; } } if (i < 0) { /* the supposed free slot is not, let's search for a free slot */ zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool); - for (i = 0; i < scoreboard->nprocs; i++) { - if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */ + for (i = 0; i < nprocs; i++) { + if (!scoreboard->procs[i].used) { /* found */ break; } } } /* no free slot */ - if (i < 0 || i >= scoreboard->nprocs) { + if (i < 0 || i >= nprocs) { zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool); return -1; } - scoreboard->procs[i]->used = 1; - *child_index = i; + scoreboard->procs[i].used = 1; + child->scoreboard_i = i; /* supposed next slot is free */ - if (i + 1 >= scoreboard->nprocs) { + if (i + 1 >= nprocs) { scoreboard->free_proc = 0; } else { scoreboard->free_proc = i + 1; diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index f58a287..a0cc093 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -65,7 +65,7 @@ unsigned int nprocs; int free_proc; unsigned long int slow_rq; - struct fpm_scoreboard_proc_s *procs[]; + struct fpm_scoreboard_proc_s procs[]; }; int fpm_scoreboard_init_main(); @@ -74,18 +74,19 @@ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard); struct fpm_scoreboard_s *fpm_scoreboard_get(); struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index); +struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child); struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang); void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard); struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang); void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc); -void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard); +void fpm_scoreboard_free(struct fpm_worker_pool_s *wp); -void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid); +void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid); -void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index); -int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index); +void fpm_scoreboard_proc_free(struct fpm_child_s *child); +int fpm_scoreboard_proc_alloc(struct fpm_child_s *child); #ifdef HAVE_TIMES float fpm_scoreboard_get_tick(); diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index 3e82fac..666a1d9 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -402,10 +402,10 @@ first = 1; for (i=0; inprocs; i++) { - if (!scoreboard_p->procs[i] || !scoreboard_p->procs[i]->used) { + if (!scoreboard_p->procs[i].used) { continue; } - proc = *scoreboard_p->procs[i]; + proc = scoreboard_p->procs[i]; if (first) { first = 0; diff --git a/sapi/fpm/fpm/fpm_worker_pool.c b/sapi/fpm/fpm/fpm_worker_pool.c index a002291..c778b33 100644 --- a/sapi/fpm/fpm/fpm_worker_pool.c +++ b/sapi/fpm/fpm/fpm_worker_pool.c @@ -44,7 +44,7 @@ fpm_worker_pool_config_free(wp->config); fpm_children_free(wp->children); if ((which & FPM_CLEANUP_CHILD) == 0 && fpm_globals.parent_pid == getpid()) { - fpm_scoreboard_free(wp->scoreboard); + fpm_scoreboard_free(wp); } fpm_worker_pool_free(wp); } diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 8815e8a..88de8e1 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -101,8 +101,8 @@ return NULL; } - if (IS_SLASH(path[0])) { - return path + 1; + if (IS_ABSOLUTE_PATH(path, path_len)) { + return path + COPY_WHEN_ABSOLUTE(path) + 1; } i = path_len; --- /dev/null +++ b/ext/zip/tests/bug81420.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #81420 (ZipArchive::extractTo extracts outside of destination) +--SKIPIF-- + +--FILE-- +open(__DIR__ . "/bug81420.zip"); +$destination = __DIR__ . "/bug81420"; +mkdir($destination); +$zip->extractTo($destination); +var_dump(file_exists("$destination/nt1/zzr_noharm.php")); +?> +--CLEAN-- + +--EXPECT-- +bool(true) --- /dev/null +++ b/ext/zip/tests/bug81420.zip @@ -0,0 +1,2 @@ +PK›¦#S€õŒ(2/../nt1/zzr_noharm.phpË­ÌKÌMÍ,®ª*ŠÏËÏH,ÊÕ+È(P°µSàåÒ×ÓÓÏ+1ÔG•PK›¦#S€õŒ(2$ /../nt1/zzr_noharm.php + R®¦›Â ×å¿ý“ ×å¿ý“ ×PKh\ \ No newline at end of file diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index ee050e2..486a49d 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -114,6 +114,11 @@ pch2 = (xmlChar *) systemid; } + if (strstr(name, "%00")) { + php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes"); + RETURN_FALSE; + } + uri = xmlParseURI(name); if (uri != NULL && uri->opaque != NULL) { localname = xmlStrdup((xmlChar *) uri->opaque); --- /dev/null +++ b/ext/dom/tests/bug79971_2.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #79971 (special character is breaking the path in xml function) +--SKIPIF-- + +--FILE-- +createDocumentType("$uri%00foo")); +?> +--EXPECTF-- +Warning: DOMImplementation::createDocumentType(): URI must not contain percent-encoded NUL bytes in %s on line %d +bool(false) diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index da30004..f481353 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -308,6 +308,10 @@ int isescaped=0; xmlURI *uri; + if (strstr(filename, "%00")) { + php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes"); + return NULL; + } uri = xmlParseURI(filename); if (uri && (uri->scheme == NULL || @@ -438,6 +442,11 @@ if (URI == NULL) return(NULL); + if (strstr(URI, "%00")) { + php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes"); + return NULL; + } + puri = xmlParseURI(URI); if (puri != NULL) { if (puri->scheme != NULL) --- /dev/null +++ b/ext/simplexml/tests/bug79971_1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #79971 (special character is breaking the path in xml function) +--SKIPIF-- + +--FILE-- +asXML("$uri.out%00foo")); +?> +--EXPECTF-- +Warning: simplexml_load_file(): URI must not contain percent-encoded NUL bytes in %s on line %d + +Warning: simplexml_load_file(): I/O warning : failed to load external entity "%s/bug79971_1.xml%00foo" in %s on line %d +bool(false) + +Warning: SimpleXMLElement::asXML(): URI must not contain percent-encoded NUL bytes in %s on line %d +bool(false) --- /dev/null +++ b/ext/simplexml/tests/bug79971_1.xml @@ -0,0 +1,2 @@ + +