diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index ac4f5b7..1e99293 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 c8399c4..d7103b2 100644 --- a/php.ini-development +++ b/php.ini-development @@ -295,6 +295,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/mysql/config.m4 b/ext/mysql/config.m4 index fd7f52e..999c47b 100644 --- a/ext/mysql/config.m4 +++ b/ext/mysql/config.m4 @@ -77,7 +77,7 @@ Note that the MySQL client library is not bundled anymore!]) fi - if test "$enable_maintainer_zts" = "yes"; then + if true || test "$enable_maintainer_zts" = "yes"; then MYSQL_LIBNAME=mysqlclient_r else MYSQL_LIBNAME=mysqlclient diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 index f6c86e7..9192600 100644 --- a/ext/mysqli/config.m4 +++ b/ext/mysqli/config.m4 @@ -26,7 +26,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 f237f41..3483cca 100755 --- a/ext/pdo_mysql/config.m4 +++ b/ext/pdo_mysql/config.m4 @@ -55,7 +55,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 3eb2616..98e55ea 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 cb1224e..794f508 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 f472bad..9805bfc 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -656,7 +656,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: do_fstat(data, 1); diff --git a/ext/dba/dba.c b/ext/dba/dba.c index cf9674a..7554203 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -930,7 +930,7 @@ } } - if (error || hptr->open(info, &error TSRMLS_CC) != SUCCESS) { + if (error || (hptr->open)(info, &error TSRMLS_CC) != SUCCESS) { dba_close(info TSRMLS_CC); php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(args[0]), Z_STRVAL_PP(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 2d0ad86..ddb2440 100644 --- a/ext/dba/dba_db3.c +++ b/ext/dba/dba_db3.c @@ -91,7 +91,7 @@ if ((err=db_create(&dbp, NULL, 0)) == 0) { dbp->set_errcall(dbp, php_dba_db3_errcall_fcn); - if ((err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + if ((err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { dba_db3_data *data; data = pemalloc(sizeof(*data), info->flags&DBA_PERSISTENT); diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c index 2dfb33a..1aac4cc 100644 --- a/ext/dba/dba_db4.c +++ b/ext/dba/dba_db4.c @@ -126,9 +126,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 47dc3ac..69c39df 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -46,6 +46,18 @@ #undef gzseek #undef gztell +/* + * 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/Zend/zend_strtod.c b/Zend/zend_strtod.c index e74cf0e..7ec0366 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -152,14 +152,25 @@ #define IEEE_LITTLE_ENDIAN #endif -#if defined(__arm__) && !defined(__VFP_FP__) -/* - * * Although the CPU is little endian the FP has different - * * byte and word endianness. The byte order is still little endian - * * but the word order is big endian. - * */ -#define IEEE_BIG_ENDIAN +#if defined(__arm__) || defined(__thumb__) +/* ARM traditionally used big-endian words; and within those words the + byte ordering was big or little endian depending upon the target. + Modern floating-point formats are naturally ordered; in this case + __VFP_FP__ will be defined, even if soft-float. */ #undef IEEE_LITTLE_ENDIAN +#undef IEEE_BIG_ENDIAN +#if defined(__VFP_FP__) || defined(__MAVERICK__) +# ifdef __ARMEL__ +# define IEEE_LITTLE_ENDIAN +# else +# define IEEE_BIG_ENDIAN +# endif +#else +# define IEEE_BIG_ENDIAN +# ifdef __ARMEL__ +# define IEEE_BYTES_LITTLE_ENDIAN +# endif +#endif #endif #ifdef __vax__ @@ -287,7 +298,7 @@ * An alternative that might be better on some machines is * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) */ -#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__) +#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(IEEE_BYTES_LITTLE_ENDIAN) #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ ((unsigned short *)a)[0] = (unsigned short)c, a++) #else diff --git a/ext/mssql/php_mssql.c b/ext/mssql/php_mssql.c index 66497f1..6196690 100644 --- a/ext/mssql/php_mssql.c +++ b/ext/mssql/php_mssql.c @@ -178,6 +178,38 @@ PHP_FE(mssql_execute, arginfo_mssql_execute) PHP_FE(mssql_free_statement, arginfo_mssql_free_statement) PHP_FE(mssql_guid_string, arginfo_mssql_guid_string) +#if !defined(PHP_WIN32) && !defined(HAVE_SYBASE_CT) + PHP_FALIAS(sybase_connect, mssql_connect, arginfo_mssql_connect) + PHP_FALIAS(sybase_pconnect, mssql_pconnect, arginfo_mssql_connect) + PHP_FALIAS(sybase_close, mssql_close, arginfo_mssql_close) + PHP_FALIAS(sybase_select_db, mssql_select_db, arginfo_mssql_select_db) + PHP_FALIAS(sybase_query, mssql_query, arginfo_mssql_query) + PHP_FALIAS(sybase_fetch_batch, mssql_fetch_batch, arginfo_mssql_fetch_batch) + PHP_FALIAS(sybase_affected_rows, mssql_rows_affected, arginfo_mssql_rows_affected) + PHP_FALIAS(sybase_free_result, mssql_free_result, arginfo_mssql_fetch_batch) + PHP_FALIAS(sybase_get_last_message, mssql_get_last_message, arginfo_mssql_get_last_message) + PHP_FALIAS(sybase_num_rows, mssql_num_rows, arginfo_mssql_fetch_batch) + PHP_FALIAS(sybase_num_fields, mssql_num_fields, arginfo_mssql_fetch_batch) + PHP_FALIAS(sybase_fetch_field, mssql_fetch_field, arginfo_mssql_fetch_field) + PHP_FALIAS(sybase_fetch_row, mssql_fetch_row, arginfo_mssql_fetch_batch) + PHP_FALIAS(sybase_fetch_array, mssql_fetch_array, arginfo_mssql_fetch_array) + PHP_FALIAS(sybase_fetch_assoc, mssql_fetch_assoc, arginfo_mssql_fetch_assoc) + PHP_FALIAS(sybase_fetch_object, mssql_fetch_object, arginfo_mssql_fetch_batch) + PHP_FALIAS(sybase_field_length, mssql_field_length, arginfo_mssql_field_length) + PHP_FALIAS(sybase_field_name, mssql_field_name, arginfo_mssql_field_length) + PHP_FALIAS(sybase_field_type, mssql_field_type, arginfo_mssql_field_length) + PHP_FALIAS(sybase_data_seek, mssql_data_seek, arginfo_mssql_data_seek) + PHP_FALIAS(sybase_field_seek, mssql_field_seek, arginfo_mssql_fetch_field) + PHP_FALIAS(sybase_result, mssql_result, arginfo_mssql_result) + PHP_FALIAS(sybase_next_result, mssql_next_result, arginfo_mssql_fetch_assoc) + PHP_FALIAS(sybase_min_error_severity, mssql_min_error_severity, arginfo_mssql_min_error_severity) + PHP_FALIAS(sybase_min_message_severity, mssql_min_message_severity, arginfo_mssql_min_error_severity) + PHP_FALIAS(sybase_init, mssql_init, arginfo_mssql_init) + PHP_FALIAS(sybase_bind, mssql_bind, arginfo_mssql_bind) + PHP_FALIAS(sybase_execute, mssql_execute, arginfo_mssql_execute) + PHP_FALIAS(sybase_free_statement, mssql_free_statement, arginfo_mssql_free_statement) + PHP_FALIAS(sybase_guid_string, mssql_guid_string, arginfo_mssql_guid_string) +#endif PHP_FE_END }; /* }}} */ diff --git a/Zend/zend.h b/Zend/zend.h index 35fa013..3d93018 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -90,11 +90,11 @@ # endif # if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT) -# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT) +# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT) # elif defined(RTLD_DEEPBIND) -# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND) +# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND) # else -# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL) +# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL) # endif # define DL_UNLOAD dlclose # if defined(DLSYM_NEEDS_UNDERSCORE) diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index f170ea9..3b280dd 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -69,7 +69,7 @@ \$(mkinstalldirs) '$APXS_SYSCONFDIR' && \ $APXS -S LIBEXECDIR='$APXS_LIBEXECDIR' \ -S SYSCONFDIR='$APXS_SYSCONFDIR' \ - -i -a -n php5" + -i -n php5" fi case $host_alias in diff --git a/ext/mysql/php_mysql.c b/ext/mysql/php_mysql.c index 2d3ba60..679d417 100644 --- a/ext/mysql/php_mysql.c +++ b/ext/mysql/php_mysql.c @@ -735,13 +735,13 @@ E_DEPRECATED, "The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead"); -#if !defined(MYSQL_USE_MYSQLND) - if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Headers and client library minor version mismatch. Headers:%d Library:%ld", - MYSQL_VERSION_ID, mysql_get_client_version()); - } -#endif +/* #if !defined(MYSQL_USE_MYSQLND) */ +/* if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) { */ +/* php_error_docref(NULL TSRMLS_CC, E_WARNING, */ +/* "Headers and client library minor version mismatch. Headers:%d Library:%ld", */ +/* MYSQL_VERSION_ID, mysql_get_client_version()); */ +/* } */ +/* #endif */ connect_timeout = MySG(connect_timeout); diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index f1e805c..9ebdca1 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -74,13 +74,13 @@ zend_bool self_alloced = 0; -#if !defined(MYSQL_USE_MYSQLND) - if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Headers and client library minor version mismatch. Headers:%d Library:%ld", - MYSQL_VERSION_ID, mysql_get_client_version()); - } -#endif +/* #if !defined(MYSQL_USE_MYSQLND) */ +/* if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) { */ +/* php_error_docref(NULL TSRMLS_CC, E_WARNING, */ +/* "Headers and client library minor version mismatch. Headers:%d Library:%ld", */ +/* MYSQL_VERSION_ID, mysql_get_client_version()); */ +/* } */ +/* #endif */ if (getThis() && !ZEND_NUM_ARGS() && in_ctor) { php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU); diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index 57f050b..4af30f2 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/Zend/zend_gc.c b/Zend/zend_gc.c index e72655c..e7c5098 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -310,16 +310,25 @@ } } while (p != NULL) { - pz = *(zval**)p->pData; - if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { - pz->refcount__gc++; - } - if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) { - if (p->pListNext == NULL) { - goto tail_call; + if (p->pData != NULL) { + pz = *(zval**)p->pData; + if (pz != NULL) { + if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { + pz->refcount__gc++; + } + if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) { + if (p->pListNext == NULL) { + goto tail_call; + } else { + zval_scan_black(pz TSRMLS_CC); + } + } } else { - zval_scan_black(pz TSRMLS_CC); + /* Now this is really odd ... we've got a p->pData which references a NULL pointer */ } + } else { + /* shall we log something when encountering a p->pData == NULL */ + } p = p->pListNext; } @@ -353,12 +362,20 @@ } p = props->pListHead; while (p != NULL) { - pz = *(zval**)p->pData; - if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { - pz->refcount__gc++; - } - if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) { - zval_scan_black(pz TSRMLS_CC); + if (p->pData != NULL) { + pz = *(zval**)p->pData; + if (pz != NULL) { + if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { + pz->refcount__gc++; + } + if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) { + zval_scan_black(pz TSRMLS_CC); + } + } else { + /* pz is NULL - maybe there should be some logging? */ + } + } else { + /* p->pData is NULL - maybe there should be some logging? */ } p = p->pListNext; } @@ -417,14 +434,23 @@ } } while (p != NULL) { - pz = *(zval**)p->pData; - if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { - pz->refcount__gc--; - } - if (p->pListNext == NULL) { - goto tail_call; + if (p->pData != NULL) { + pz = *(zval**)p->pData; + if (pz != NULL) { + if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { + pz->refcount__gc--; + } + if (p->pListNext == NULL) { + goto tail_call; + } else { + zval_mark_grey(pz TSRMLS_CC); + } + } else { + /* Now this is odd - we have a valid pz and a pData which is NULL */ + + } } else { - zval_mark_grey(pz TSRMLS_CC); + /* Some logging maybe? p->pData is NULL */ } p = p->pListNext; } @@ -459,11 +485,19 @@ } p = props->pListHead; while (p != NULL) { - pz = *(zval**)p->pData; - if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { - pz->refcount__gc--; + if (p->pData != NULL) { + pz = *(zval**)p->pData; + if (pz != NULL) { + if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { + pz->refcount__gc--; + } + zval_mark_grey(pz TSRMLS_CC); + } else { + /* TODO: Some logging maybe? */ + } + } else { + /* TODO: Some logging maybe? */ } - zval_mark_grey(pz TSRMLS_CC); p = p->pListNext; } } diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 6e5cec2..850a6e6 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1385,6 +1385,9 @@ /* set up our manifest */ mydata = ecalloc(1, sizeof(phar_archive_data)); mydata->fname = expand_filepath(fname, NULL TSRMLS_CC); + 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 c083345..fbcf892 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1135,7 +1135,7 @@ zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &path, &len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); 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 cad29b7..47055a1 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3577,10 +3577,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); @@ -3588,8 +3588,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 @@ -3672,9 +3672,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 47055a1..5497068 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3519,7 +3519,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 @@ -3540,6 +3540,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; @@ -4183,7 +4187,9 @@ ZVAL_STRINGL(return_value, ImageInfo.Thumbnail.data, ImageInfo.Thumbnail.size, 1); if (arg_c >= 3) { if (!ImageInfo.Thumbnail.width || !ImageInfo.Thumbnail.height) { - exif_scan_thumbnail(&ImageInfo TSRMLS_CC); + if (!exif_scan_thumbnail(&ImageInfo TSRMLS_CC)) { + 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/phar/tar.c b/ext/phar/tar.c index 898ff85..7ad95eb 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -765,7 +765,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/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 9805bfc..a5a09e2 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -1132,34 +1132,50 @@ # ifdef EXDEV if (errno == EXDEV) { struct stat 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 TSRMLS_CC) == SUCCESS) { if (VCWD_STAT(url_from, &sb) == 0) { + success = 1; # if !defined(TSRM_WIN32) && !defined(NETWARE) - if (VCWD_CHMOD(url_to, sb.st_mode)) { + /* + * 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 TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); if (errno == EPERM) { - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); - VCWD_UNLINK(url_from); - return 1; + success = 0; } - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); - return 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 TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); - VCWD_UNLINK(url_from); - return 1; + if (errno == EPERM) { + success = 0; + } } - php_error_docref2(NULL TSRMLS_CC, 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 TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); } + } else { + php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); } - php_error_docref2(NULL TSRMLS_CC, 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/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 ce8db17..4350124 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2812,6 +2812,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 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -1660,10 +1660,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 TSRMLS_DC) +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 TSRMLS_DC) { size_t idex; - void *vptr; + void *vptr, *vptr_end; image_info_value *info_value; image_info_data *info_data; image_info_data *list; @@ -1685,8 +1685,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 { @@ -1708,6 +1712,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); @@ -1738,7 +1746,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]; } @@ -1774,7 +1787,7 @@ php_error_docref(NULL TSRMLS_CC, 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 TSRMLS_CC, E_WARNING, "Found value of type double"); @@ -1792,9 +1805,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 TSRMLS_DC) +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 TSRMLS_DC) { - exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, image_info->motorola_intel TSRMLS_CC); + exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, value_len, image_info->motorola_intel TSRMLS_CC); } /* }}} */ @@ -2218,7 +2231,7 @@ */ static void exif_process_COM (image_info_type *image_info, char *value, size_t length TSRMLS_DC) { - exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2 TSRMLS_CC); + exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2, length-2 TSRMLS_CC); } /* }}} */ @@ -2233,17 +2246,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 TSRMLS_CC); + exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value, length TSRMLS_CC); 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 TSRMLS_CC, 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 TSRMLS_CC); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "JPEG2000 comment section too small"); } } @@ -2837,7 +2850,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 TSRMLS_DC) { 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; @@ -3148,7 +3161,7 @@ } } } - exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table TSRMLS_CC), tag, format, components, value_ptr TSRMLS_CC); + exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table TSRMLS_CC), tag, format, components, value_ptr, byte_count TSRMLS_CC); EFREE_IF(outside); return TRUE; } @@ -3306,10 +3319,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 TSRMLS_CC); + exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2, l1 TSRMLS_CC); 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 TSRMLS_CC); + exif_iif_add_tag(ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1, l2 TSRMLS_CC); } } #ifdef EXIF_DEBUG @@ -4107,7 +4120,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 TSRMLS_CC); + exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data, ImageInfo.Thumbnail.size TSRMLS_CC); } if (!ImageInfo.Thumbnail.width || !ImageInfo.Thumbnail.height) { /* try to evaluate if thumbnail data is present */ diff --git a/ext/pdo_pgsql/tests/bug48764.phpt b/ext/pdo_pgsql/tests/bug48764.phpt index 83fa565..14c1f68 100644 --- a/ext/pdo_pgsql/tests/bug48764.phpt +++ b/ext/pdo_pgsql/tests/bug48764.phpt @@ -12,7 +12,7 @@ $client_version = $db->getAttribute(PDO::ATTR_CLIENT_VERSION); $server_version = $db->getAttribute(PDO::ATTR_SERVER_VERSION); -if (version_compare($server_version, '7.4', '<') || version_compare($client_version, '7.4', '<')) { +if (version_compare($server_version, '7.4', '<') || version_compare($client_version, '7.4', '<') || version_compare($server_version, '10', '>=')) { die('skip'); } --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2901,7 +2901,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 503ac82..99931a5 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 335dbd1..bbc4b0f 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 diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 15e091b..b6c3177 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3536,6 +3536,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; --- /dev/null +++ b/ext/exif/tests/bug77988.jpg @@ -0,0 +1 @@ +џи000000000000000џў00000000000џў00000000000џў0000000000000џс™ExifMM*‚˜0&’†0Oh00000000000000000000000000000000000000UNICODE00000000000000000†0000џиџџ0000000000000џ0„0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џР0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000R0000000000000000000000000000000000000000000000000000000000000000000000000000џ0„0000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000џР00000000000000џ000џ0?0000000000000000000000000000000000000000000000000000000000000000000000000)0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000H0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џк0 \ No newline at end of file --- /dev/null +++ b/ext/exif/tests/bug77988.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #77988 (heap-buffer-overflow on php_jpg_get16) +--SKIPIF-- + +--FILE-- + +DONE +--EXPECTF-- +DONE \ No newline at end of file diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 761b777..7bf873f 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -2062,6 +2062,15 @@ } #endif + if (strncmp(arg3, "file:", 5) == 0) { + /* starts with "file:" */ + if (!arg3[5]) { + return SQLITE_DENY; + } + if (php_check_open_basedir(arg3 + 5 TSRMLS_CC)) { + return SQLITE_DENY; + } + } if (php_check_open_basedir(arg3 TSRMLS_CC)) { return SQLITE_DENY; } diff --git a/run-tests.php b/run-tests.php index 0949d50..7dab5ab 100755 --- a/run-tests.php +++ b/run-tests.php @@ -1553,6 +1553,11 @@ $info = " (warn: $m[1])"; } } + + if (!strncasecmp('xfail', ltrim($output), 5)) { + // Pretend we have an XFAIL section + $section_text['XFAIL'] = trim(substr(ltrim($output), 5)); + } } } diff --git a/ext/phar/tests/phar_bz2.phpt b/ext/phar/tests/phar_bz2.phpt index 0e6e3ec..106fa89 100644 --- a/ext/phar/tests/phar_bz2.phpt +++ b/ext/phar/tests/phar_bz2.phpt @@ -5,6 +5,7 @@ if (!extension_loaded("phar")) die("skip"); if (!extension_loaded("spl")) die("skip SPL not available"); if (!extension_loaded("bz2")) die("skip bz2 not available"); +if (phpversion() < "7.0.0" && extension_loaded('Zend OPcache') && ini_get('opcache.enable_cli')==1) die("xfail for PHP version lower than 7 when OPcache enabled"); ?> --INI-- phar.readonly=0 diff --git a/ext/phar/tests/phar_gzip.phpt b/ext/phar/tests/phar_gzip.phpt index c722834..19d5606 100644 --- a/ext/phar/tests/phar_gzip.phpt +++ b/ext/phar/tests/phar_gzip.phpt @@ -7,6 +7,7 @@ if (!extension_loaded("spl")) die("skip SPL not available"); if (!extension_loaded("zlib")) die("skip zlib not available"); if (version_compare(phpversion(), '5.2.6', '<')) die("skip zlib is buggy in PHP < 5.2.6"); +if (phpversion() < "7.0.0" && extension_loaded('Zend OPcache') && ini_get('opcache.enable_cli')==1) die("xfail for PHP version lower than 7 when OPcache enabled"); ?> --INI-- phar.readonly=0 diff --git a/ext/phar/tests/tar/rename.phpt b/ext/phar/tests/tar/rename.phpt index 96588a6..9b2b4f4 100644 --- a/ext/phar/tests/tar/rename.phpt +++ b/ext/phar/tests/tar/rename.phpt @@ -1,7 +1,10 @@ --TEST-- Phar: rename test tar-based --SKIPIF-- - + --INI-- phar.readonly=0 phar.require_hash=0 diff --git a/ext/phar/tests/tar/rename_dir.phpt b/ext/phar/tests/tar/rename_dir.phpt index 0b95789..4ca8ceb 100644 --- a/ext/phar/tests/tar/rename_dir.phpt +++ b/ext/phar/tests/tar/rename_dir.phpt @@ -1,7 +1,10 @@ --TEST-- Phar: rename_dir test tar-based --SKIPIF-- - + --INI-- phar.readonly=0 phar.require_hash=0 diff --git a/ext/phar/tests/tar/rmdir.phpt b/ext/phar/tests/tar/rmdir.phpt index be03782..6cb5eab 100644 --- a/ext/phar/tests/tar/rmdir.phpt +++ b/ext/phar/tests/tar/rmdir.phpt @@ -1,7 +1,10 @@ --TEST-- Phar: rmdir test tar-based --SKIPIF-- - + --INI-- phar.readonly=0 phar.require_hash=0 diff --git a/ext/phar/tests/tar/tar_gzip.phpt b/ext/phar/tests/tar/tar_gzip.phpt index d44e1b1..a13a80a 100644 --- a/ext/phar/tests/tar/tar_gzip.phpt +++ b/ext/phar/tests/tar/tar_gzip.phpt @@ -7,6 +7,7 @@ if (!extension_loaded("spl")) die("skip SPL not available"); if (!extension_loaded("zlib")) die("skip zlib not available"); if (version_compare(phpversion(), '5.2.6', '<')) die("skip zlib is buggy in PHP < 5.2.6"); +if (phpversion() < "7.0.0" && extension_loaded('Zend OPcache') && ini_get('opcache.enable_cli')==1) die("xfail for PHP version lower than 7 when OPcache enabled"); ?> --INI-- phar.readonly=0 diff --git a/ext/phar/tests/zip/rename.phpt b/ext/phar/tests/zip/rename.phpt index 9b1f5c9..776bcae 100644 --- a/ext/phar/tests/zip/rename.phpt +++ b/ext/phar/tests/zip/rename.phpt @@ -1,7 +1,10 @@ --TEST-- Phar: rename test zip-based --SKIPIF-- - + --INI-- phar.readonly=0 phar.require_hash=0 diff --git a/ext/phar/tests/zip/rename_dir.phpt b/ext/phar/tests/zip/rename_dir.phpt index bb03c7f..3452f8f 100644 --- a/ext/phar/tests/zip/rename_dir.phpt +++ b/ext/phar/tests/zip/rename_dir.phpt @@ -1,7 +1,10 @@ --TEST-- Phar: rename_dir test zip-based --SKIPIF-- - + --INI-- phar.readonly=0 phar.require_hash=0 diff --git a/ext/phar/tests/zip/rmdir.phpt b/ext/phar/tests/zip/rmdir.phpt index c7ef9da..7d062d5 100644 --- a/ext/phar/tests/zip/rmdir.phpt +++ b/ext/phar/tests/zip/rmdir.phpt @@ -1,7 +1,10 @@ --TEST-- Phar: rmdir test zip-based --SKIPIF-- - + --INI-- phar.readonly=0 phar.require_hash=0 diff --git a/ext/exif/exif.c b/ext/exif/exif.c index b6c3177..a5fa0b8 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3508,7 +3508,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 a5fa0b8..ec362f7 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2628,7 +2628,7 @@ { int a; char *decode; - size_t len;; + size_t len; *pszEncoding = NULL; /* Copy the comment */ @@ -2641,11 +2641,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/pcre/pcrelib/pcre_compile.c b/ext/pcre/pcrelib/pcre_compile.c index c9171cb..1d37671 100644 --- a/ext/pcre/pcrelib/pcre_compile.c +++ b/ext/pcre/pcrelib/pcre_compile.c @@ -485,7 +485,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" @@ -6734,6 +6734,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/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/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 d2097f1..a217127 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_getcolumnmeta.phpt @@ -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); diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 0848fd8..c4bb370 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1245,8 +1245,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) { diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c index c484c15..a5e7850 100644 --- 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_)); --- /dev/null +++ b/ext/bcmath/tests/bug78878.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #78878 (Buffer underflow in bc_shift_addsub) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bc math warning: non-zero scale in modulus +0 diff --git a/ext/standard/link_win32.c b/ext/standard/link_win32.c index 059201c..4c537db 100644 --- a/ext/standard/link_win32.c +++ b/ext/standard/link_win32.c @@ -208,7 +208,7 @@ /*First argument to link function is the target and hence should go to frompath Second argument to link function is the link itself and hence should go to topath */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &frompath, &frompath_len, &topath, &topath_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pp", &frompath, &frompath_len, &topath, &topath_len) == FAILURE) { return; } --- /dev/null +++ b/ext/standard/tests/file/windows_links/bug78862.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #78862 (link() silently truncates after a null byte on Windows) +--FILE-- + +--EXPECTF-- +Warning: link() expects parameter 1 to be a valid path, string given in %s on line %d +NULL +bool(false) +--CLEAN-- + diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index fbcf892..3a22357 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -691,10 +691,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() TSRMLS_CC, "s|l", &path, &len, &flags); + parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "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() TSRMLS_CC, "s", &path, &len); + parsed = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &path, &len); } if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_SKIPDOTS)) { flags |= SPL_FILE_DIR_SKIPDOTS; --- /dev/null +++ b/ext/spl/tests/bug78863.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #78863 (DirectoryIterator class silently truncates after a null byte) +--FILE-- +isDot()) { + var_dump($fileinfo->getFilename()); + } +} +?> +--EXPECTF-- +Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct() expects parameter 1 to be a valid path, string given in %s:%d +Stack trace: +#0 %s(%d): DirectoryIterator->__construct('%s') +#1 {main} + thrown in %s on line %d +--CLEAN-- + diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 6a3bb91..f64a14e 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2759,7 +2759,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; } --- /dev/null +++ b/ext/exif/tests/bug78910.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #78910: Heap-buffer-overflow READ in exif (OSS-Fuzz #19044) +--FILE-- + +--EXPECTF-- +Notice: exif_read_data(): Read from TIFF: tag(0x927C, MakerNote ): Illegal format code 0x2020, switching to BYTE in %s on line %d + +Warning: exif_read_data(): Process tag(x927C=MakerNote ): Illegal format code 0x2020, suppose BYTE in %s on line %d + +Warning: exif_read_data(): IFD data too short: 0x0000 offset 0x000C in %s on line %d + +Warning: exif_read_data(): Invalid TIFF file in %s on line %d +bool(false) 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/phar/tests/tar/phar_commitwrite.phpt b/ext/phar/tests/tar/phar_commitwrite.phpt index 262ea1d..bfbac61 100644 --- a/ext/phar/tests/tar/phar_commitwrite.phpt +++ b/ext/phar/tests/tar/phar_commitwrite.phpt @@ -5,9 +5,6 @@ --INI-- phar.require_hash=0 phar.readonly=0 ---ENV-- -TEMP=. -TMP=. --FILE-- */ break; - } else if (state == 2 && *(p-1) != '\\') { + } else if (state == 2 && p >= buf + 1 && *(p-1) != '\\') { if (lc == c) { lc = '\0'; } else if (lc != '\\') { @@ -4797,7 +4797,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 { @@ -4824,7 +4824,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 099f8e6..e04d81d 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/session/session.c b/ext/session/session.c index 5380d2b..2fe9651 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2820,9 +2820,11 @@ if (PS(rfc1867_cleanup)) { php_session_rfc1867_cleanup(progress TSRMLS_CC); } else { - add_assoc_bool_ex(progress->data, "done", sizeof("done"), 1); - Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; - php_session_rfc1867_update(progress, 1 TSRMLS_CC); + if (progress->data) { + add_assoc_bool_ex(progress->data, "done", sizeof("done"), 1); + Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; + php_session_rfc1867_update(progress, 1 TSRMLS_CC); + } } php_rshutdown_session_globals(TSRMLS_C); } --- /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; char *str = "[stream]"; + php_stream_statbuf ssb; iter->funcs->get_current_data(iter, &value TSRMLS_CC); @@ -1709,6 +1710,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/exif/exif.c b/ext/exif/exif.c index f64a14e..bf2fd61 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -3253,6 +3253,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; @@ -3405,7 +3410,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/exec.c b/ext/standard/exec.c index 88a6b4a..a586b78 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -537,6 +537,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 d6e71fa..0278bd4 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -545,7 +545,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; @@ -647,7 +647,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; --- /dev/null +++ b/ext/openssl/tests/bug72333.phpt @@ -0,0 +1,54 @@ +--TEST-- +Bug #72333: fwrite() on non-blocking SSL sockets doesn't work +--SKIPIF-- + +--FILE-- + ['local_cert' => __DIR__ . '/bug54992.pem']]); + + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $fp = stream_socket_server("ssl://127.0.0.1:10011", $errornum, $errorstr, $flags, $context); + phpt_notify(); + $conn = stream_socket_accept($fp); + + for ($i = 0; $i < 5; $i++) { + fread($conn, 100000); + usleep(200000); + } +CODE; + +$clientCode = <<<'CODE' + $context = stream_context_create(['ssl' => ['verify_peer' => false, 'peer_name' => 'bug54992.local']]); + + phpt_wait(); + $fp = stream_socket_client("ssl://127.0.0.1:10011", $errornum, $errorstr, 3000, STREAM_CLIENT_CONNECT, $context); + stream_set_blocking($fp, 0); + + function blocking_fwrite($fp, $buf) { + $write = [$fp]; + $total = 0; + while (stream_select($read, $write, $except, 180)) { + $result = fwrite($fp, $buf); + $total += $result; + if ($total >= strlen($buf)) { + return $total; + } + $buf = substr($buf, $total); + } + } + + $str1 = str_repeat("a", 5000000); + blocking_fwrite($fp, $str1); + echo "done"; +CODE; + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +?> +--EXPECT-- +done + diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index c2d477c..6a7dcd7 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1714,6 +1714,14 @@ if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0 TSRMLS_CC)) { sslsock->s.is_blocked = 0; + SSL_set_mode( + sslsock->ssl_handle, + ( + SSL_get_mode(sslsock->ssl_handle) | + SSL_MODE_ENABLE_PARTIAL_WRITE | + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER + ) + ); } timeout = sslsock->is_client ? &sslsock->connect_timeout : &sslsock->s.timeout; diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 52f058c..8fa14f3 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -1572,6 +1572,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) { + struct stat 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); --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -1398,6 +1398,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); diff --git a/main/php_variables.c b/main/php_variables.c index 6da79bd..084b10f 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -472,7 +472,9 @@ unsigned int 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 TSRMLS_CC)) { @@ -483,7 +485,9 @@ int val_len; unsigned int 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 TSRMLS_CC)) { 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" +} --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -318,6 +318,8 @@ ctx->context = NULL; } +#define SAFE_STR(a) ((a)?a:"") + static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC) { sdlPtr tmpsdl = ctx->sdl; @@ -379,7 +381,7 @@ if (node_is_equal_ex(trav2, "schema", XSD_NAMESPACE)) { load_schema(ctx, trav2 TSRMLS_CC); } 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; } @@ -440,7 +442,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; } @@ -550,7 +552,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; } @@ -655,7 +657,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; } @@ -687,14 +689,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)); @@ -703,7 +705,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); @@ -773,7 +775,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; @@ -812,7 +814,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; } @@ -914,7 +916,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; @@ -933,7 +935,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; } @@ -1111,7 +1113,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 f3b49df..4694b4e 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -205,7 +205,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) { @@ -221,7 +221,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 b30440f..5dfe122 100644 --- a/ext/imap/php_imap.c +++ b/ext/imap/php_imap.c @@ -3491,6 +3491,21 @@ } /* }}} */ +static zend_bool header_injection(char *p, zend_bool adrlist) +{ + 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) @@ -3511,6 +3526,13 @@ return; } +#define CHECK_HEADER_INJECTION(zstr, adrlist, header) \ + if (header_injection(zstr, adrlist)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "header injection attempt in " header); \ + RETVAL_FALSE; \ + goto done; \ + } + #define PHP_RFC822_PARSE_ADRLIST(target, value) \ str_copy = estrndup(Z_STRVAL_PP(value), Z_STRLEN_PP(value)); \ rfc822_parse_adrlist(target, str_copy, "NO HOST"); \ @@ -3519,46 +3541,57 @@ env = mail_newenvelope(); if (zend_hash_find(Z_ARRVAL_P(envelope), "remail", sizeof("remail"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "remail"); env->remail = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_P(envelope), "return_path", sizeof("return_path"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 1, "return_path"); PHP_RFC822_PARSE_ADRLIST(&env->return_path, pvalue); } if (zend_hash_find(Z_ARRVAL_P(envelope), "date", sizeof("date"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "date"); env->date = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_P(envelope), "from", sizeof("from"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 1, "from"); PHP_RFC822_PARSE_ADRLIST(&env->from, pvalue); } if (zend_hash_find(Z_ARRVAL_P(envelope), "reply_to", sizeof("reply_to"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 1, "reply_to"); PHP_RFC822_PARSE_ADRLIST(&env->reply_to, pvalue); } if (zend_hash_find(Z_ARRVAL_P(envelope), "in_reply_to", sizeof("in_reply_to"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "in_reply_to"); env->in_reply_to = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_P(envelope), "subject", sizeof("subject"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "subject"); env->subject = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_P(envelope), "to", sizeof("to"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 1, "to"); PHP_RFC822_PARSE_ADRLIST(&env->to, pvalue); } if (zend_hash_find(Z_ARRVAL_P(envelope), "cc", sizeof("cc"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 1, "cc"); PHP_RFC822_PARSE_ADRLIST(&env->cc, pvalue); } if (zend_hash_find(Z_ARRVAL_P(envelope), "bcc", sizeof("bcc"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 1, "bcc"); PHP_RFC822_PARSE_ADRLIST(&env->bcc, pvalue); } if (zend_hash_find(Z_ARRVAL_P(envelope), "message_id", sizeof("message_id"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "message_id"); env->message_id=cpystr(Z_STRVAL_PP(pvalue)); } @@ -3568,6 +3601,7 @@ while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &env_data) == SUCCESS) { custom_headers_param = mail_newbody_parameter(); convert_to_string_ex(env_data); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(env_data), 0, "custom_headers"); custom_headers_param->value = (char *) fs_get(Z_STRLEN_PP(env_data) + 1); custom_headers_param->attribute = NULL; memcpy(custom_headers_param->value, Z_STRVAL_PP(env_data), Z_STRLEN_PP(env_data) + 1); @@ -3598,6 +3632,7 @@ } if (zend_hash_find(Z_ARRVAL_PP(data), "charset", sizeof("charset"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body charset"); tmp_param = mail_newbody_parameter(); tmp_param->value = cpystr(Z_STRVAL_PP(pvalue)); tmp_param->attribute = cpystr("CHARSET"); @@ -3608,10 +3643,12 @@ if(Z_TYPE_PP(pvalue) == IS_ARRAY) { disp_param = tmp_param = NULL; while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) { + CHECK_HEADER_INJECTION(key, 0, "body disposition key"); disp_param = mail_newbody_parameter(); zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0); disp_param->attribute = cpystr(key); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(disp_data), 0, "body disposition value"); disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1); zend_hash_move_forward(Z_ARRVAL_PP(pvalue)); @@ -3623,18 +3660,22 @@ } if (zend_hash_find(Z_ARRVAL_PP(data), "subtype", sizeof("subtype"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body subtype"); bod->subtype = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_PP(data), "id", sizeof("id"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body id"); bod->id = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_PP(data), "description", sizeof("description"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body description"); bod->description = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_PP(data), "disposition.type", sizeof("disposition.type"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body disposition.type"); bod->disposition.type = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1); memcpy(bod->disposition.type, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue)+1); } @@ -3642,10 +3683,12 @@ if (Z_TYPE_PP(pvalue) == IS_ARRAY) { disp_param = tmp_param = NULL; while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) { + CHECK_HEADER_INJECTION(key, 0, "body type.parameters key"); disp_param = mail_newbody_parameter(); zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0); disp_param->attribute = cpystr(key); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(disp_data), 0, "body type.parameters value"); disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1); zend_hash_move_forward(Z_ARRVAL_PP(pvalue)); @@ -3675,6 +3718,7 @@ } if (zend_hash_find(Z_ARRVAL_PP(data), "md5", sizeof("md5"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body md5"); bod->md5 = cpystr(Z_STRVAL_PP(pvalue)); } } @@ -3710,6 +3754,7 @@ } if (zend_hash_find(Z_ARRVAL_PP(data), "charset", sizeof("charset"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body charset"); tmp_param = mail_newbody_parameter(); tmp_param->value = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1); memcpy(tmp_param->value, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue) + 1); @@ -3723,8 +3768,10 @@ while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) { disp_param = mail_newbody_parameter(); zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0); + CHECK_HEADER_INJECTION(key, 0, "body type.parameters key"); disp_param->attribute = cpystr(key); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(disp_data), 0, "body type.parameters value"); disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1); zend_hash_move_forward(Z_ARRVAL_PP(pvalue)); @@ -3736,18 +3783,22 @@ } if (zend_hash_find(Z_ARRVAL_PP(data), "subtype", sizeof("subtype"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body subtype"); bod->subtype = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_PP(data), "id", sizeof("id"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body id"); bod->id = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_PP(data), "description", sizeof("description"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body description"); bod->description = cpystr(Z_STRVAL_PP(pvalue)); } if (zend_hash_find(Z_ARRVAL_PP(data), "disposition.type", sizeof("disposition.type"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body disposition.type"); bod->disposition.type = (char *) fs_get(Z_STRLEN_PP(pvalue) + 1); memcpy(bod->disposition.type, Z_STRVAL_PP(pvalue), Z_STRLEN_PP(pvalue)+1); } @@ -3757,8 +3808,10 @@ while (zend_hash_get_current_data(Z_ARRVAL_PP(pvalue), (void **) &disp_data) == SUCCESS) { disp_param = mail_newbody_parameter(); zend_hash_get_current_key(Z_ARRVAL_PP(pvalue), &key, &ind, 0); + CHECK_HEADER_INJECTION(key, 0, "body disposition key"); disp_param->attribute = cpystr(key); convert_to_string_ex(disp_data); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(disp_data), 0, "body disposition value"); disp_param->value = (char *) fs_get(Z_STRLEN_PP(disp_data) + 1); memcpy(disp_param->value, Z_STRVAL_PP(disp_data), Z_STRLEN_PP(disp_data) + 1); zend_hash_move_forward(Z_ARRVAL_PP(pvalue)); @@ -3788,6 +3841,7 @@ } if (zend_hash_find(Z_ARRVAL_PP(data), "md5", sizeof("md5"), (void **) &pvalue)== SUCCESS) { convert_to_string_ex(pvalue); + CHECK_HEADER_INJECTION(Z_STRVAL_PP(pvalue), 0, "body md5"); bod->md5 = cpystr(Z_STRVAL_PP(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 6aa1b36..8bb4c2e 100644 --- a/ext/interbase/config.m4 +++ b/ext/interbase/config.m4 @@ -3,39 +3,54 @@ install directory [/usr/interbase]]) if test "$PHP_INTERBASE" != "no"; then - if test "$PHP_INTERBASE" = "yes"; then - IBASE_INCDIR=/usr/interbase/include - IBASE_LIBDIR=/usr/interbase/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=/usr/interbase/include + IBASE_LIBDIR=/usr/interbase/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([libgds, libib_util or libfbclient not found! Check config.log for more information.]) + PHP_CHECK_LIBRARY(ib_util, isc_detach_database, + [ + IBASE_LIBNAME=ib_util + ], [ + AC_MSG_ERROR([libgds, libib_util or libfbclient 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) 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 d1f1012..8b8f822 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -267,8 +267,8 @@ 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) { unsigned short chunk_size = (*len-cur_len) > USHRT_MAX ? USHRT_MAX --- /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 cb7e4bd..a87bcc1 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -120,8 +120,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); } @@ -145,7 +151,8 @@ return 1; } while (0); - RECORD_ERROR(stmt); +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 2e71d9d..baa1b96 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 baa1b96..23bf8d8 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -539,14 +539,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); } } /* }}} */ @@ -557,8 +559,8 @@ 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); return 1; --- /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/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 23bf8d8..f8a44e7 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -239,14 +239,16 @@ /* execute the statement */ if (isc_dsql_execute2(H->isc_status, &H->tr, &stmt, PDO_FB_SQLDA_VERSION, &in_sqlda, &out_sqlda)) { RECORD_ERROR(dbh); - return -1; + ret = -1; + goto free_statement; } /* find out how many rows were affected */ if (isc_dsql_sql_info(H->isc_status, &stmt, sizeof(info_count), const_cast(info_count), sizeof(result), result)) { RECORD_ERROR(dbh); - return -1; + ret = -1; + goto free_statement; } if (result[0] == isc_info_sql_records) { @@ -275,6 +277,12 @@ RECORD_ERROR(dbh); } +free_statement: + + if (isc_dsql_free_statement(H->isc_status, &stmt, DSQL_drop)) { + RECORD_ERROR(dbh); + } + return ret; } /* }}} */ diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index f8a44e7..c53fd31 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -139,7 +139,7 @@ HashTable *np; do { - isc_stmt_handle s = NULL; + isc_stmt_handle s = PDO_FIREBIRD_HANDLE_INITIALIZER; XSQLDA num_sqlda; static char const info[] = { isc_info_sql_stmt_type }; char result[8]; @@ -220,7 +220,7 @@ static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC) /* {{{ */ { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; - isc_stmt_handle stmt = NULL; + isc_stmt_handle stmt = PDO_FIREBIRD_HANDLE_INITIALIZER; static char const info_count[] = { isc_info_sql_records }; char result[64]; int ret = 0; diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index a87bcc1..dc64c19 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -230,7 +230,7 @@ { pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data; pdo_firebird_db_handle *H = S->H; - isc_blob_handle blobh = NULL; + isc_blob_handle blobh = PDO_FIREBIRD_HANDLE_INITIALIZER; char const bl_item = isc_info_blob_total_length; char bl_info[20]; unsigned short i; @@ -424,7 +424,7 @@ { pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data; pdo_firebird_db_handle *H = S->H; - isc_blob_handle h = NULL; + isc_blob_handle h = PDO_FIREBIRD_HANDLE_INITIALIZER; unsigned long put_cnt = 0, rem_cnt; unsigned short chunk_size; int result = 1; diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h index 796f383..09cd485 100644 --- a/ext/pdo_firebird/php_pdo_firebird_int.h +++ b/ext/pdo_firebird/php_pdo_firebird_int.h @@ -61,6 +61,12 @@ #define min(a,b) ((a)<(b)?(a):(b)) #endif +#if defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(_WIN64) +# define PDO_FIREBIRD_HANDLE_INITIALIZER 0U +#else +# define PDO_FIREBIRD_HANDLE_INITIALIZER NULL +#endif + typedef struct { /* the result of the last API call */ diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 8fa14f3..0768c48 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -122,8 +122,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; diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index d79430b..5f2b4e6 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -111,6 +111,11 @@ if (systemid_len > 0) pch2 = systemid; + if (strstr(name, "%00")) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "URI must not contain percent-encoded NUL bytes"); + RETURN_FALSE; + } + uri = xmlParseURI(name); if (uri != NULL && uri->opaque != NULL) { localname = xmlStrdup(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 b252cb6..d4a47ff 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -301,6 +301,11 @@ TSRMLS_FETCH(); + if (strstr(filename, "%00")) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "URI must not contain percent-encoded NUL bytes"); + return NULL; + } + uri = xmlParseURI(filename); if (uri && (uri->scheme == NULL || (xmlStrncmp(BAD_CAST uri->scheme, BAD_CAST "file", 4) == 0))) { @@ -431,6 +436,11 @@ if (URI == NULL) return(NULL); + if (strstr(URI, "%00")) { + php_error_docref(NULL TSRMLS_CC, 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 @@ + + diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index d4a47ff..02453ff 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -433,6 +433,8 @@ void *context = NULL; char *unescaped = NULL; + TSRMLS_FETCH(); + if (URI == NULL) return(NULL);