[packages/php/PHP_5_2] Rel 52; security fixes from php-src-backports PHP-5.2 branch and php-src
arekm
arekm at pld-linux.org
Thu Oct 22 10:34:11 CEST 2026
commit 24c44f02abb01ce95ff4864624427e17afb6d12d
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Thu Oct 22 10:33:29 2026 +0200
Rel 52; security fixes from php-src-backports PHP-5.2 branch and php-src
Includes CVE-2026-109618/109619, CVE-2026-6722, CVE-2026-91765/91766, CVE-2025-1735/1736, CVE-2016-10397 and more, see security-backports.patch.
php-5.2.17-bug-323016.patch | 48 -
php.spec | 16 +-
security-backports.patch | 8602 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 8613 insertions(+), 53 deletions(-)
---
diff --git a/php.spec b/php.spec
index c2d10c3..6a7f17f 100644
--- a/php.spec
+++ b/php.spec
@@ -112,7 +112,7 @@ ERROR: You need to select at least one Apache SAPI to build shared modules.
%define magic_mime /usr/share/misc/magic.mime
%endif
-%define rel 51
+%define rel 52
%define orgname php
%define ver_suffix 52
%define php_suffix %{!?with_default_php:%{ver_suffix}}
@@ -236,6 +236,7 @@ Patch86: mbstring.patch
Patch87: pgsql.patch
Patch88: zip.patch
Patch89: xmlwriter.patch
+Patch90: security-backports.patch
# CENTALT patches
# Backport from 5.3.6
Patch311: php-5.3.6-bug-47435.patch
@@ -243,8 +244,6 @@ Patch314: php-5.3.6-39199.patch
# 5.3.7
#Patch333: php-5.3.7-bug-54924.patch
Patch355: php-5.3.7-bug-55323.patch
-# Bug-323016 CVE-2012-0831
-Patch402: php-5.2.17-bug-323016.patch
URL: https://code.google.com/archive/p/php52-backports/
%{?with_interbase:%{!?with_interbase_inst:BuildRequires: Firebird-devel >= 1.0.2.908-2}}
%{?with_pspell:BuildRequires: aspell-devel >= 2:0.50.0}
@@ -306,6 +305,7 @@ BuildRequires: pam-devel
BuildRequires: pkgconfig
%{?with_pgsql:BuildRequires: postgresql-backend-devel >= 7.2}
%{?with_pgsql:BuildRequires: postgresql-devel}
+BuildRequires: re2c
BuildRequires: readline-devel
%{?with_recode:BuildRequires: recode-devel >= 3.5d-3}
BuildRequires: rpm >= 4.4.9-56
@@ -2011,11 +2011,17 @@ done
# Bugfix backport from 5.3.6
%patch -P311 -p1 -b .bug-47435
%patch -P314 -p1 -b .bug-39199
+%patch -P90 -p1
+
+# security-backports.patch changes only the .re scanner sources, and the
+# Makefiles have regeneration rules for just two of these four
+for f in ext/date/lib/parse_date ext/pdo/pdo_sql_parser ext/standard/url_scanner_ex ext/standard/var_unserializer; do
+ re2c -b -o $f.c $f.re
+done
+
# Bugfix backport from 5.3.7
#accert %%patch -P333 -p1 -b .bug-54924
#soap %%patch -P355 -p1 -b .bug-55323
-# causes regression -> magic_quotes_gpc setting cannot be changed
-#%%patch -P402 -p1 -b .bug-323016
# cleanup backups after patching
find '(' -name '*~' -o -name '*.orig' ')' -print0 | xargs -0 -r -l512 rm -f
diff --git a/php-5.2.17-bug-323016.patch b/php-5.2.17-bug-323016.patch
deleted file mode 100644
index cc482d2..0000000
--- a/php-5.2.17-bug-323016.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-diff -up php-5.2.17/main/php_variables.c.bug-323016 php-5.2.17/main/php_variables.c
---- php-5.2.17/main/php_variables.c.bug-323016 2012-02-16 09:26:09.000000000 +0700
-+++ php-5.2.17/main/php_variables.c 2012-02-16 09:29:47.000000000 +0700
-@@ -29,6 +29,7 @@
- #include "SAPI.h"
- #include "php_logos.h"
- #include "zend_globals.h"
-+#include "php_ini.h"
-
- /* for systems that need to override reading of environment variables */
- void _php_import_environment_variables(zval *array_ptr TSRMLS_DC);
-@@ -438,7 +439,10 @@ void _php_import_environment_variables(z
-
- /* turn off magic_quotes while importing environment variables */
- int magic_quotes_gpc = PG(magic_quotes_gpc);
-- PG(magic_quotes_gpc) = 0;
-+
-+ if (PG(magic_quotes_gpc)) {
-+ zend_alter_ini_entry_ex("magic_quotes_gpc", sizeof("magic_quotes_gpc"), "0", 1, ZEND_INI_SYSTEM, ZEND_INI_STAGE_ACTIVATE, 1);
-+ }
-
- for (env = environ; env != NULL && *env != NULL; env++) {
- p = strchr(*env, '=');
-@@ -581,7 +585,9 @@ static inline void php_register_server_v
- zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_SERVER]);
- }
- PG(http_globals)[TRACK_VARS_SERVER] = array_ptr;
-- PG(magic_quotes_gpc) = 0;
-+ if (PG(magic_quotes_gpc)) {
-+ zend_alter_ini_entry_ex("magic_quotes_gpc", sizeof("magic_quotes_gpc"), "0", 1, ZEND_INI_SYSTEM, ZEND_INI_STAGE_ACTIVATE, 1);
-+ }
-
- /* Server variables */
- if (sapi_module.register_server_variables) {
-diff -up php-5.2.17/sapi/cgi/cgi_main.c.bug-323016 php-5.2.17/sapi/cgi/cgi_main.c
---- php-5.2.17/sapi/cgi/cgi_main.c.bug-323016 2010-01-03 15:23:27.000000000 +0600
-+++ php-5.2.17/sapi/cgi/cgi_main.c 2012-02-16 09:26:09.000000000 +0700
-@@ -609,7 +609,9 @@ void cgi_php_import_environment_variable
- int filter_arg = (array_ptr == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER;
-
- /* turn off magic_quotes while importing environment variables */
-- PG(magic_quotes_gpc) = 0;
-+ if (PG(magic_quotes_gpc)) {
-+ zend_alter_ini_entry_ex("magic_quotes_gpc", sizeof("magic_quotes_gpc"), "0", 1, ZEND_INI_SYSTEM, ZEND_INI_STAGE_ACTIVATE, 1);
-+ }
- for (zend_hash_internal_pointer_reset_ex(&request->env, &pos);
- zend_hash_get_current_key_ex(&request->env, &var, &var_len, &idx, 0, &pos) == HASH_KEY_IS_STRING &&
- zend_hash_get_current_data_ex(&request->env, (void **) &val, &pos) == SUCCESS;
diff --git a/security-backports.patch b/security-backports.patch
new file mode 100644
index 0000000..5998769
--- /dev/null
+++ b/security-backports.patch
@@ -0,0 +1,8602 @@
+Security fixes for PHP 5.2.17 from the PHP-5.2-security-backports branch of
+https://github.com/shivammathur/php-src-backports (up to ff60deb117a7, which
+includes the CVE-2026-109618/CVE-2026-109619 backport), minus what
+php52-backports and PLD patches already carry, adapted to that tree.
+
+Ported from php-src on top of that:
+- 3655b79c7bfa CVE-2026-91765 (GHSA-rgrp-mwpx-f6rm) SOAP unbounded recursion
+- 5af9465ca890, 795440a704d4 CVE-2026-91766 (GHSA-fpwc-w8rq-cr92) credentials
+ sent to another origin on redirect
+- 547566f17a12, 64664758cd8e CVE-2026-93682 (GHSA-7875-c8px-7q5f) empty Location
+- 41d49abbd99d CVE-2025-1736 (GHSA-hgf5-96fm-v528) user header detection
+- b4e3397ec8f4 CVE-2026-92842 (GHSA-88hq-2827-7pg6) convert.* lbchars with NUL
+- b11bd1d9390b CVE-2025-14181 (GHSA-cj93-vc83-wgqv) SOAP HTTP body size overflow
+- 7ac9700d0d46 GHSA-ch8v-r6jh-4vvr FILTER_SANITIZE_ENCODED and 0xFF
+- c5f28c7cf0a0 CVE-2025-14177 (GHSA-3237-qqm7-mfv7) getimagesize APPn short read
+- 9164dc11e232, 0e715e71d945 GHSA-wg4p-4hqh-c3g9 XML_OPTION_SKIP_TAGSTART
+- ed70b1ea43a9 GHSA-www2-q4fc-65wf NUL bytes in dns/inet/getserv* arguments
+- 66bd809ac922 CVE-2025-1735 (GHSA-hrwm-9436-5mv3) pgsql escaping errors
+- a38418777f65 CVE-2026-7258 (GHSA-m8rr-4c36-8gq4) urldecode isxdigit()
+- metaphone(): int overflow of the 5.2 phoneme buffer (CVE-2026-7568 area)
+- b061fa909de7 CVE-2016-10397 (bug #73192) parse_url() host confusion
+- 4a89e726bd4d parse_url() userinfo parsing restored, as upstream did after
+ the #77423 fix; FILTER_VALIDATE_URL keeps the userinfo check
+- aee3b3ac9b81 CVE-2026-6722 (GHSA-85c2-q967-79q5): the SOAP ref_map references
+ are released after decoding, as upstream does
+- 3584a98bda0f GHSA-w8hw-w9fx-j79w: post_max_size enforced for multipart bodies
+ without a Content-Length (the session upload progress part has no 5.2
+ counterpart)
+Generated re2c scanners are not part of this patch; the spec regenerates them
+from the patched .re files. Regression tests live in the branch above.
+
+diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c
+index b7d0f3604..261d0a5a7 100644
+--- a/TSRM/tsrm_virtual_cwd.c
++++ b/TSRM/tsrm_virtual_cwd.c
+@@ -682,10 +682,9 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
+
+ use_cache = ((use_realpath != CWD_EXPAND) && CWDG(realpath_cache_size_limit));
+
+- if (path_length == 0)
+- return (1);
+- if (path_length >= MAXPATHLEN)
+- return (1);
++ if (path_length <= 0 || path_length >= MAXPATHLEN-1) {
++ return 1;
++ }
+
+ #if VIRTUAL_CWD_DEBUG
+ fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
+diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c
+index fa14f0de3..b21faa233 100644
+--- a/TSRM/tsrm_win32.c
++++ b/TSRM/tsrm_win32.c
+@@ -237,6 +237,10 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
+ }
+
+ cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c "));
++ if (!cmd) {
++ return NULL;
++ }
++
+ sprintf(cmd, "%s /c %s", TWG(comspec), command);
+ if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW, env, cwd, &startup, &process)) {
+ free(cmd);
+diff --git a/Zend/zend.h b/Zend/zend.h
+index 015b3b8f9..65ee68b2d 100644
+--- a/Zend/zend.h
++++ b/Zend/zend.h
+@@ -331,6 +331,14 @@ struct _zval_struct {
+ };
+
+
++#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
++# define EXPECTED(condition) __builtin_expect(condition, 1)
++# define UNEXPECTED(condition) __builtin_expect(condition, 0)
++#else
++# define EXPECTED(condition) (condition)
++# define UNEXPECTED(condition) (condition)
++#endif
++
+ /* excpt.h on Digital Unix 4.0 defines function_table */
+ #undef function_table
+
+@@ -598,6 +606,20 @@ END_EXTERN_C()
+ (z)->refcount = 1; \
+ (z)->is_ref = 0;
+
++#ifndef INIT_PZVAL_COPY
++#define INIT_PZVAL_COPY(z,v) \
++ (z)->value = (v)->value; \
++ (z)->type = (v)->type; \
++ (z)->refcount = 1; \
++ (z)->is_ref = 0;
++#endif
++
++#ifndef MAKE_COPY_ZVAL
++#define MAKE_COPY_ZVAL(ppzv, pzv) \
++ INIT_PZVAL_COPY(pzv, *(ppzv));\
++ zval_copy_ctor((pzv));
++#endif
++
+ #define INIT_ZVAL(z) z = zval_used_for_init;
+
+ #define ALLOC_INIT_ZVAL(zp) \
+diff --git a/Zend/zend_API.c b/Zend/zend_API.c
+index bd3f69ad5..489956eb7 100644
+--- a/Zend/zend_API.c
++++ b/Zend/zend_API.c
+@@ -398,6 +398,7 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp
+ }
+ break;
+
++ case 'p':
+ case 's':
+ {
+ char **p = va_arg(*va, char **);
+@@ -418,17 +419,23 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp
+ convert_to_string_ex(arg);
+ *p = Z_STRVAL_PP(arg);
+ *pl = Z_STRLEN_PP(arg);
++ if (c == 'p' && CHECK_ZVAL_NULL_PATH(*arg)) {
++ return "valid path";
++ }
+ break;
+
+ case IS_OBJECT:
+ if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) {
++ if (c == 'p' && CHECK_ZVAL_NULL_PATH(*arg)) {
++ return "valid path";
++ }
+ break;
+ }
+
+ case IS_ARRAY:
+ case IS_RESOURCE:
+ default:
+- return "string";
++ return c == 's' ? "string" : "valid path";
+ }
+ }
+ break;
+@@ -659,7 +666,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl
+ case 'o': case 'O':
+ case 'z': case 'Z':
+ case 'C': case 'h':
+- case 'f':
++ case 'f': case 'p':
+ max_num_args++;
+ break;
+
+@@ -831,6 +838,16 @@ ZEND_API int _array_init(zval *arg ZEND_FILE_LINE_DC)
+ return SUCCESS;
+ }
+
++ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC)
++{
++ _array_init(arg ZEND_FILE_LINE_RELAY_CC);
++ /* Buckets are allocated eagerly in these branches; shrink the storage and mask. */
++ Z_ARRVAL_P(arg)->arBuckets = (Bucket **) erealloc_rel(Z_ARRVAL_P(arg)->arBuckets, 2 * sizeof(Bucket *));
++ Z_ARRVAL_P(arg)->nTableSize = 2;
++ Z_ARRVAL_P(arg)->nTableMask = 1;
++ return SUCCESS;
++}
++
+
+ static int zend_merge_property(zval **value, int num_args, va_list args, zend_hash_key *hash_key)
+ {
+diff --git a/Zend/zend_API.h b/Zend/zend_API.h
+index 2bc825687..aa7e6b6ec 100644
+--- a/Zend/zend_API.h
++++ b/Zend/zend_API.h
+@@ -280,10 +280,12 @@ ZEND_API char *zend_get_type_by_const(int type);
+ #endif
+
+ #define array_init(arg) _array_init((arg) ZEND_FILE_LINE_CC)
++#define array_init_singleton(arg) _array_init_singleton((arg) ZEND_FILE_LINE_CC)
+ #define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC TSRMLS_CC)
+ #define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC TSRMLS_CC)
+ #define object_and_properties_init(arg, ce, properties) _object_and_properties_init((arg), (ce), (properties) ZEND_FILE_LINE_CC TSRMLS_CC)
+ ZEND_API int _array_init(zval *arg ZEND_FILE_LINE_DC);
++ZEND_API int _array_init_singleton(zval *arg ZEND_FILE_LINE_DC);
+ ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC);
+ ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC TSRMLS_DC);
+ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC);
+@@ -437,6 +439,9 @@ END_EXTERN_C()
+ #define CHECK_ZVAL_STRING_REL(z)
+ #endif
+
++#define CHECK_ZVAL_NULL_PATH(p) (Z_STRLEN_P(p) != strlen(Z_STRVAL_P(p)))
++#define CHECK_NULL_PATH(p, l) (strlen(p) != l)
++
+ #define ZVAL_RESOURCE(z, l) { \
+ Z_TYPE_P(z) = IS_RESOURCE; \
+ Z_LVAL_P(z) = l; \
+@@ -464,6 +469,9 @@ END_EXTERN_C()
+ #define ZVAL_STRING(z, s, duplicate) { \
+ char *__s=(s); \
+ (z)->value.str.len = strlen(__s); \
++ if (UNEXPECTED(Z_STRLEN_P(z) < 0)) { \
++ zend_error(E_ERROR, "String size overflow"); \
++ } \
+ (z)->value.str.val = (duplicate?estrndup(__s, (z)->value.str.len):__s); \
+ (z)->type = IS_STRING; \
+ }
+@@ -526,6 +534,19 @@ END_EXTERN_C()
+ #define RETURN_FALSE { RETVAL_FALSE; return; }
+ #define RETURN_TRUE { RETVAL_TRUE; return; }
+
++/* Check that returned string length fits int */
++#define RETVAL_STRINGL_CHECK(s, len, dup) do { \
++ size_t __len = (len); \
++ if (UNEXPECTED(__len > INT_MAX)) { \
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "String too long, max is %d", INT_MAX); \
++ if(!(dup)) { \
++ efree((s)); \
++ } \
++ RETURN_FALSE; \
++ } \
++ RETVAL_STRINGL((s), (int)__len, (dup)); \
++} while (0)
++
+ #define SET_VAR_STRING(n, v) { \
+ { \
+ zval *var; \
+diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
+index 8835c3dd3..25fe27c92 100644
+--- a/Zend/zend_alloc.c
++++ b/Zend/zend_alloc.c
+@@ -22,6 +22,7 @@
+
+ #include "zend.h"
+ #include "zend_alloc.h"
++#include "zend_execute.h"
+ #include "zend_globals.h"
+ #include "zend_operators.h"
+
+@@ -93,7 +94,7 @@ static void zend_mm_panic(const char *message)
+ #if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
+ kill(getpid(), SIGSEGV);
+ #endif
+- exit(1);
++ _exit(1);
+ }
+
+ /*******************/
+@@ -1699,6 +1700,36 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent
+ }
+ }
+
++ZEND_API void zend_mm_safe_error_ex(const char *format, ...)
++{
++ const char *script_filename = NULL;
++ uint script_lineno = 0;
++ va_list args;
++ char buf[1024];
++ TSRMLS_FETCH();
++
++ if (zend_is_executing(TSRMLS_C)) {
++ script_filename = zend_get_executed_filename(TSRMLS_C);
++ script_lineno = zend_get_executed_lineno(TSRMLS_C);
++ } else if (zend_is_compiling(TSRMLS_C)) {
++ script_filename = zend_get_compiled_filename(TSRMLS_C);
++ script_lineno = zend_get_compiled_lineno(TSRMLS_C);
++ }
++
++ va_start(args, format);
++ vsnprintf(buf, sizeof(buf), format, args);
++ buf[sizeof(buf) - 1] = '\0';
++ va_end(args);
++ fprintf(stderr, "\nFatal error: %s in %s on line %d\n",
++ buf, script_filename ? script_filename : "Unknown", script_lineno);
++
++ /* See http://support.microsoft.com/kb/190351 */
++#ifdef ZEND_WIN32
++ fflush(stderr);
++#endif
++ _exit(1);
++}
++
+ static void zend_mm_safe_error(zend_mm_heap *heap,
+ const char *format,
+ size_t limit,
+@@ -1708,55 +1739,12 @@ static void zend_mm_safe_error(zend_mm_heap *heap,
+ #endif
+ size_t size)
+ {
+- if (heap->reserve) {
+- _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
+- heap->reserve = NULL;
+- }
+- if (heap->overflow == 0) {
+- char *error_filename;
+- uint error_lineno;
+- TSRMLS_FETCH();
+- if (zend_is_compiling(TSRMLS_C)) {
+- error_filename = zend_get_compiled_filename(TSRMLS_C);
+- error_lineno = zend_get_compiled_lineno(TSRMLS_C);
+- } else if (EG(in_execution)) {
+- error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
+- error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
+- } else {
+- error_filename = NULL;
+- error_lineno = 0;
+- }
+- if (!error_filename) {
+- error_filename = "Unknown";
+- }
+- heap->overflow = 1;
+- zend_try {
+- zend_error_noreturn(E_ERROR,
+- format,
+- limit,
+-#if ZEND_DEBUG
+- filename,
+- lineno,
+-#endif
+- size);
+- } zend_catch {
+- if (heap->overflow == 2) {
+- fprintf(stderr, "\nFatal error: ");
+- fprintf(stderr,
+- format,
+- limit,
++ (void) heap;
++ zend_mm_safe_error_ex(format, limit,
+ #if ZEND_DEBUG
+- filename,
+- lineno,
++ filename, lineno,
+ #endif
+- size);
+- fprintf(stderr, " in %s on line %d\n", error_filename, error_lineno);
+- }
+- } zend_end_try();
+- } else {
+- heap->overflow = 2;
+- }
+- zend_bailout();
++ size);
+ }
+
+ static zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *heap, size_t true_size)
+@@ -2455,7 +2443,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+ "rm"(offset));
+
+ if (UNEXPECTED(overflow)) {
+- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
+ return 0;
+ }
+ return res;
+@@ -2485,7 +2473,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+ #undef LP_SUFF
+
+ if (UNEXPECTED(overflow)) {
+- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
+ return 0;
+ }
+ return res;
+@@ -2500,7 +2488,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+ double _delta = (double)res - _d;
+
+ if (UNEXPECTED((_d + _delta ) != _d)) {
+- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
+ return 0;
+ }
+ return res;
+diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
+index 93641e350..fe584e1df 100644
+--- a/Zend/zend_alloc.h
++++ b/Zend/zend_alloc.h
+@@ -24,6 +24,12 @@
+
+ #include <stdio.h>
+
++#ifdef ZEND_WIN32
++# include <process.h>
++#elif defined(HAVE_UNISTD_H)
++# include <unistd.h>
++#endif
++
+ #include "../TSRM/TSRM.h"
+ #include "zend.h"
+
+@@ -38,6 +44,8 @@ typedef struct _zend_leak_info {
+
+ BEGIN_EXTERN_C()
+
++ZEND_API void zend_mm_safe_error_ex(const char *format, ...);
++
+ ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_MALLOC;
+
+ ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
+@@ -83,7 +91,7 @@ inline static void * __zend_malloc(size_t len)
+ return tmp;
+ }
+ fprintf(stderr, "Out of memory\n");
+- exit(1);
++ _exit(1);
+ }
+
+ inline static void * __zend_calloc(size_t nmemb, size_t len)
+@@ -100,7 +108,7 @@ inline static void * __zend_realloc(void *p, size_t len)
+ return p;
+ }
+ fprintf(stderr, "Out of memory\n");
+- exit(1);
++ _exit(1);
+ }
+
+
+diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
+index 3f94159f3..2cbd31c62 100644
+--- a/Zend/zend_builtin_functions.c
++++ b/Zend/zend_builtin_functions.c
+@@ -514,6 +514,10 @@ repeat:
+ }
+ c.flags = case_sensitive; /* non persistent */
+ c.name = zend_strndup(name, name_len);
++ if (c.name == NULL) {
++ zval_dtor(&c.value);
++ RETURN_FALSE;
++ }
+ c.name_len = name_len+1;
+ c.module_number = PHP_USER_CONSTANT;
+ if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
+diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
+index da0090935..d0373c1db 100644
+--- a/Zend/zend_exceptions.c
++++ b/Zend/zend_exceptions.c
+@@ -437,6 +437,9 @@ ZEND_METHOD(exception, getTraceAsString)
+ str = &res;
+
+ trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC);
++ if(Z_TYPE_P(trace) != IS_ARRAY) {
++ RETURN_FALSE;
++ }
+ zend_hash_apply_with_arguments(Z_ARRVAL_P(trace), (apply_func_args_t)_build_trace_string, 3, str, len, &num);
+
+ s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 7 + 1);
+diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
+index 7b8dc2687..67e16cdcc 100644
+--- a/Zend/zend_execute_API.c
++++ b/Zend/zend_execute_API.c
+@@ -321,6 +321,16 @@ void shutdown_executor(TSRMLS_D)
+ }
+ } zend_end_try();
+ EG(active) = 0;
++
++ /* May be accessed before init_executor(). */
++ EG(user_error_handler) = NULL;
++ EG(user_exception_handler) = NULL;
++ memset(&EG(user_error_handlers_error_reporting), 0, sizeof(EG(user_error_handlers_error_reporting)));
++ memset(&EG(user_error_handlers), 0, sizeof(EG(user_error_handlers)));
++ memset(&EG(user_exception_handlers), 0, sizeof(EG(user_exception_handlers)));
++ EG(exception) = NULL;
++ EG(objects_store).object_buckets = NULL;
++ EG(objects_store).top = 1;
+ }
+
+
+diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y
+index 7fc8ce202..77b7b725f 100644
+--- a/Zend/zend_ini_parser.y
++++ b/Zend/zend_ini_parser.y
+@@ -56,7 +56,7 @@ void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
+ {
+ int i_result;
+ int i_op1, i_op2;
+- char str_result[MAX_LENGTH_OF_LONG];
++ char str_result[MAX_LENGTH_OF_LONG+1];
+
+ i_op1 = atoi(Z_STRVAL_P(op1));
+ free(Z_STRVAL_P(op1));
+diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
+index 2b0e3de9f..449a1d1f6 100644
+--- a/Zend/zend_llist.c
++++ b/Zend/zend_llist.c
+@@ -298,6 +298,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
+ current = next;
+ }
+
++ l->head = NULL;
++ l->tail = NULL;
+ l->count = 0;
+ }
+
+diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
+index a3912f762..6ac06bbb9 100644
+--- a/Zend/zend_operators.c
++++ b/Zend/zend_operators.c
+@@ -1180,8 +1180,11 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
+ /* must support result==op1 */
+ ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2)
+ {
++ if (UNEXPECTED(Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op1) == INT_MAX)) {
++ zend_mm_safe_error_ex("String size overflow");
++ }
+ result->value.str.len = op1->value.str.len + 1;
+- result->value.str.val = (char *) erealloc(op1->value.str.val, result->value.str.len+1);
++ result->value.str.val = (char *) erealloc(op1->value.str.val, (size_t)result->value.str.len + 1);
+ result->value.str.val[result->value.str.len - 1] = (char) op2->value.lval;
+ result->value.str.val[result->value.str.len] = 0;
+ result->type = IS_STRING;
+@@ -1192,9 +1195,15 @@ ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2)
+ /* must support result==op1 */
+ ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2)
+ {
+- int length = op1->value.str.len + op2->value.str.len;
++ int length;
++
++ if (UNEXPECTED(Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 ||
++ Z_STRLEN_P(op1) > INT_MAX - Z_STRLEN_P(op2))) {
++ zend_mm_safe_error_ex("String size overflow");
++ }
++ length = op1->value.str.len + op2->value.str.len;
+
+- result->value.str.val = (char *) erealloc(op1->value.str.val, length+1);
++ result->value.str.val = (char *) erealloc(op1->value.str.val, (size_t)length + 1);
+ memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
+ result->value.str.val[length] = 0;
+ result->value.str.len = length;
+@@ -1227,23 +1236,22 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
++ if (UNEXPECTED(Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 ||
++ Z_STRLEN_P(op1) > INT_MAX - Z_STRLEN_P(op2))) {
++ zend_mm_safe_error_ex("String size overflow");
++ }
+ if (result==op1) { /* special case, perform operations on result */
+ uint res_len = op1->value.str.len + op2->value.str.len;
+
+- if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
+- efree(Z_STRVAL_P(result));
+- ZVAL_EMPTY_STRING(result);
+- zend_error(E_ERROR, "String size overflow");
+- }
+
+- result->value.str.val = erealloc(result->value.str.val, res_len+1);
++ result->value.str.val = erealloc(result->value.str.val, (size_t)res_len + 1);
+
+ memcpy(result->value.str.val+result->value.str.len, op2->value.str.val, op2->value.str.len);
+ result->value.str.val[res_len]=0;
+ result->value.str.len = res_len;
+ } else {
+ result->value.str.len = op1->value.str.len + op2->value.str.len;
+- result->value.str.val = (char *) emalloc(result->value.str.len + 1);
++ result->value.str.val = (char *) safe_emalloc(result->value.str.len, 1, 1);
+ memcpy(result->value.str.val, op1->value.str.val, op1->value.str.len);
+ memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
+ result->value.str.val[result->value.str.len] = 0;
+diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
+index f215b5a16..af92531f8 100644
+--- a/Zend/zend_strtod.c
++++ b/Zend/zend_strtod.c
+@@ -475,7 +475,7 @@ static Bigint * Balloc(int k)
+ Bigint *rv;
+
+ if (k > Kmax) {
+- zend_error(E_ERROR, "Balloc() allocation exceeds list boundary");
++ zend_mm_safe_error_ex("Balloc() allocation exceeds list boundary");
+ }
+
+ _THREAD_PRIVATE_MUTEX_LOCK(dtoa_mutex);
+@@ -486,7 +486,7 @@ static Bigint * Balloc(int k)
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
+ if (!rv) {
+ _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa_mutex);
+- zend_error(E_ERROR, "Balloc() failed to allocate memory");
++ zend_mm_safe_error_ex("Balloc() failed to allocate memory");
+ }
+ rv->k = k;
+ rv->maxwds = x;
+diff --git a/Zend/zend_ts_hash.c b/Zend/zend_ts_hash.c
+index 506688b17..68f5e2cbd 100644
+--- a/Zend/zend_ts_hash.c
++++ b/Zend/zend_ts_hash.c
+@@ -151,7 +151,6 @@ ZEND_API void zend_ts_hash_graceful_destroy(TsHashTable *ht)
+
+ #ifdef ZTS
+ tsrm_mutex_free(ht->mx_reader);
+- tsrm_mutex_free(ht->mx_reader);
+ #endif
+ }
+
+diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c
+index 15f90f8f5..2f5987a79 100644
+--- a/ext/bcmath/bcmath.c
++++ b/ext/bcmath/bcmath.c
+@@ -210,6 +210,21 @@ static void php_str2num(bc_num *num, char *str TSRMLS_DC)
+ }
+ /* }}} */
+
++/* {{{ split_bc_num
++ * Convert to bc_num detecting scale */
++static bc_num split_bc_num(bc_num num) {
++ bc_num newnum;
++ if (num->n_refs >= 1) {
++ return num;
++ }
++ newnum = _bc_new_num_ex(0, 0, 0);
++ *newnum = *num;
++ newnum->n_refs = 1;
++ num->n_refs--;
++ return newnum;
++}
++/* }}} */
++
+ /* {{{ proto string bcadd(string left_operand, string right_operand [, int scale])
+ Returns the sum of two arbitrary precision numbers */
+ PHP_FUNCTION(bcadd)
+@@ -244,6 +259,7 @@ PHP_FUNCTION(bcadd)
+ php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
+ bc_add (first, second, &result, scale);
+ if (result->n_scale > scale) {
++ result = split_bc_num(result);
+ result->n_scale = scale;
+ }
+ Z_STRVAL_P(return_value) = bc_num2str(result);
+@@ -290,6 +306,7 @@ PHP_FUNCTION(bcsub)
+ php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
+ bc_sub (first, second, &result, scale);
+ if (result->n_scale > scale) {
++ result = split_bc_num(result);
+ result->n_scale = scale;
+ }
+ Z_STRVAL_P(return_value) = bc_num2str(result);
+@@ -336,6 +353,7 @@ PHP_FUNCTION(bcmul)
+ php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
+ bc_multiply (first, second, &result, scale TSRMLS_CC);
+ if (result->n_scale > scale) {
++ result = split_bc_num(result);
+ result->n_scale = scale;
+ }
+ Z_STRVAL_P(return_value) = bc_num2str(result);
+@@ -383,6 +401,7 @@ PHP_FUNCTION(bcdiv)
+ switch (bc_divide(first, second, &result, scale TSRMLS_CC)) {
+ case 0: /* OK */
+ if (result->n_scale > scale) {
++ result = split_bc_num(result);
+ result->n_scale = scale;
+ }
+ Z_STRVAL_P(return_value) = bc_num2str(result);
+@@ -466,8 +485,9 @@ PHP_FUNCTION(bcpowmod)
+ scale_int = (int) ((int)scale < 0) ? 0 : scale;
+
+ if (bc_raisemod(first, second, mod, &result, scale_int TSRMLS_CC) != -1) {
+- if (result->n_scale > scale) {
+- result->n_scale = scale;
++ if (result->n_scale > scale_int) {
++ result = split_bc_num(result);
++ result->n_scale = scale_int;
+ }
+ Z_STRVAL_P(return_value) = bc_num2str(result);
+ Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
+@@ -518,6 +538,7 @@ PHP_FUNCTION(bcpow)
+ php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
+ bc_raise (first, second, &result, scale TSRMLS_CC);
+ if (result->n_scale > scale) {
++ result = split_bc_num(result);
+ result->n_scale = scale;
+ }
+ Z_STRVAL_P(return_value) = bc_num2str(result);
+@@ -560,6 +581,7 @@ PHP_FUNCTION(bcsqrt)
+ php_str2num(&result, Z_STRVAL_PP(left) TSRMLS_CC);
+ if (bc_sqrt (&result, scale TSRMLS_CC) != 0) {
+ if (result->n_scale > scale) {
++ result = split_bc_num(result);
+ result->n_scale = scale;
+ }
+ Z_STRVAL_P(return_value) = bc_num2str(result);
+diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c
+index c484c158e..a5e785016 100644
+--- a/ext/bcmath/libbcmath/src/str2num.c
++++ b/ext/bcmath/libbcmath/src/str2num.c
+@@ -57,9 +57,9 @@ bc_str2num (bc_num *num, char *str, int scale TSRMLS_DC)
+ 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_));
+diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
+index 2639af5d4..4e6474737 100644
+--- a/ext/bz2/bz2.c
++++ b/ext/bz2/bz2.c
+@@ -135,29 +135,34 @@ struct php_bz2_stream_data_t {
+ static size_t php_bz2iop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
+ {
+ struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *) stream->abstract;
+- size_t ret;
+-
+- ret = BZ2_bzread(self->bz_file, buf, count);
++ int bz2_ret;
++
++ bz2_ret = BZ2_bzread(self->bz_file, buf, count);
+
+- if (ret == 0) {
++ if (bz2_ret < 0) {
+ stream->eof = 1;
++ return -1;
+ }
+
+- return ret;
++ if (bz2_ret == 0) {
++ stream->eof = 1;
++ }
++
++ return (size_t)bz2_ret;
+ }
+
+ static size_t php_bz2iop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
+ {
+ struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *) stream->abstract;
+
+- return BZ2_bzwrite(self->bz_file, (char*)buf, count);
++ return BZ2_bzwrite(self->bz_file, (char*)buf, count);
+ }
+
+ static int php_bz2iop_close(php_stream *stream, int close_handle TSRMLS_DC)
+ {
+ struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *)stream->abstract;
+ int ret = EOF;
+-
++
+ if (close_handle) {
+ BZ2_bzclose(self->bz_file);
+ }
+@@ -571,15 +576,25 @@ static PHP_FUNCTION(bzdecompress)
+ /* compression is better then 2:1, need to allocate more memory */
+ bzs.avail_out = source_len;
+ size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
++ if (size > INT_MAX) {
++ /* no reason to continue if we're going to drop it anyway */
++ break;
++ }
+ dest = safe_erealloc(dest, 1, bzs.avail_out+1, size );
+ bzs.next_out = dest + size;
+ }
+
+ if (error == BZ_STREAM_END || error == BZ_OK) {
+ size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
+- dest = safe_erealloc(dest, 1, size, 1);
+- dest[size] = '\0';
+- RETVAL_STRINGL(dest, size, 0);
++ if (size > INT_MAX) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Decompressed size too big, max is %d", INT_MAX);
++ efree(dest);
++ RETVAL_LONG(BZ_MEM_ERROR);
++ } else {
++ dest = safe_erealloc(dest, 1, size, 1);
++ dest[size] = '\0';
++ RETVAL_STRINGL(dest, size, 0);
++ }
+ } else { /* real error */
+ efree(dest);
+ RETVAL_LONG(error);
+diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c
+index 9625e04e5..634457b31 100644
+--- a/ext/com_dotnet/com_dotnet.c
++++ b/ext/com_dotnet/com_dotnet.c
+@@ -129,6 +129,9 @@ static HRESULT dotnet_init(char **p_where TSRMLS_DC)
+ char *where = "";
+
+ stuff = malloc(sizeof(*stuff));
++ if (!stuff) {
++ return S_FALSE;
++ }
+ memset(stuff, 0, sizeof(*stuff));
+
+ where = "CoCreateInstance";
+diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c
+index 70f180b5d..c53b126d5 100644
+--- a/ext/com_dotnet/com_typeinfo.c
++++ b/ext/com_dotnet/com_typeinfo.c
+@@ -187,6 +187,10 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa
+ const_name = php_com_olestring_to_string(bstr_ids, &c.name_len, codepage TSRMLS_CC);
+ c.name = zend_strndup(const_name, c.name_len);
+ efree(const_name);
++ if(c.name == NULL) {
++ ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
++ continue;
++ }
+ c.name_len++; /* include NUL */
+ SysFreeString(bstr_ids);
+
+diff --git a/ext/curl/interface.c b/ext/curl/interface.c
+index ec884cef7..053da5f5c 100644
+--- a/ext/curl/interface.c
++++ b/ext/curl/interface.c
+@@ -680,6 +680,9 @@ PHP_MINIT_FUNCTION(curl)
+ int i, c = CRYPTO_num_locks();
+
+ php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T));
++ if (!php_curl_openssl_tsl) {
++ return FAILURE;
++ }
+
+ for (i = 0; i < c; ++i) {
+ php_curl_openssl_tsl[i] = tsrm_mutex_alloc();
+diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re
+index 11e655300..37d1d4ae8 100644
+--- a/ext/date/lib/parse_date.re
++++ b/ext/date/lib/parse_date.re
+@@ -850,7 +850,7 @@ datefull = day ([ \t.-])* monthtext ([ \t.-])* year;
+ datenoday = monthtext ([ .\t-])* year4;
+ datenodayrev = year4 ([ .\t-])* monthtext;
+ datetextual = monthtext ([ .\t-])* day [,.stndrh\t ]+ year;
+-datenoyear = monthtext ([ .\t-])* day [,.stndrh\t ]*;
++datenoyear = monthtext ([ .\t-])* day ([,.stndrh\t ]+|[\000]);
+ datenoyearrev = day ([ .\t-])* monthtext;
+ datenocolon = year4 monthlz daylz;
+
+diff --git a/ext/dom/document.c b/ext/dom/document.c
+index 06f8cebe7..15c2a2ca8 100644
+--- a/ext/dom/document.c
++++ b/ext/dom/document.c
+@@ -1607,7 +1607,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int sourc
+ int validate, recover, resolve_externals, keep_blanks, substitute_ent;
+ int resolved_path_len;
+ int old_error_reporting = 0;
+- char *directory=NULL, resolved_path[MAXPATHLEN];
++ char *directory=NULL, resolved_path[MAXPATHLEN + 1];
+
+ if (id != NULL) {
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+@@ -1628,6 +1628,9 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int sourc
+ xmlInitParser();
+
+ if (mode == DOM_LOAD_FILE) {
++ if (strlen(source) != source_len) {
++ return NULL;
++ }
+ char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (file_dest) {
+ ctxt = xmlCreateFileParserCtxt(file_dest);
+@@ -1682,6 +1685,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int sourc
+ options |= XML_PARSE_NOBLANKS;
+ }
+
++ php_libxml_sanitize_parse_ctxt_options(ctxt);
+ xmlCtxtUseOptions(ctxt, options);
+
+ ctxt->recovery = recover;
+@@ -1805,7 +1809,7 @@ PHP_FUNCTION(dom_document_save)
+ char *file;
+ long options = 0;
+
+- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) {
++ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) {
+ return;
+ }
+
+@@ -1897,7 +1901,7 @@ PHP_FUNCTION(dom_document_savexml)
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ xmlSaveNoEmptyTags = saveempty;
+ }
+- if (!size) {
++ if (!size || !mem) {
+ RETURN_FALSE;
+ }
+ RETVAL_STRINGL(mem, size, 1);
+@@ -1960,7 +1964,9 @@ PHP_FUNCTION(dom_document_xinclude)
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
++ PHP_LIBXML_SANITIZE_GLOBALS(xinclude);
+ err = xmlXIncludeProcessFlags(docp, flags);
++ PHP_LIBXML_RESTORE_GLOBALS(xinclude);
+
+ /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
+ are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
+@@ -2003,6 +2009,7 @@ PHP_FUNCTION(dom_document_validate)
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No DTD given in XML-Document");
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(validate);
+ cvp = xmlNewValidCtxt();
+
+ cvp->userData = NULL;
+@@ -2014,6 +2021,7 @@ PHP_FUNCTION(dom_document_validate)
+ } else {
+ RETVAL_FALSE;
+ }
++ PHP_LIBXML_RESTORE_GLOBALS(validate);
+
+ xmlFreeValidCtxt(cvp);
+
+@@ -2046,10 +2054,18 @@ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
++ PHP_LIBXML_SANITIZE_GLOBALS(new_parser_ctxt);
++
+ switch (type) {
+ case DOM_LOAD_FILE:
++ if (strlen(source) != source_len) {
++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt);
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source");
++ RETURN_FALSE;
++ }
+ valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (!valid_file) {
++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source");
+ RETURN_FALSE;
+ }
+@@ -2070,6 +2086,7 @@ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
+ parser);
+ sptr = xmlSchemaParse(parser);
+ xmlSchemaFreeParserCtxt(parser);
++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt);
+ if (!sptr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema");
+ RETURN_FALSE;
+@@ -2084,10 +2101,12 @@ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
+ RETURN_FALSE;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(validate);
+ xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+ is_valid = xmlSchemaValidateDoc(vptr, docp);
+ xmlSchemaFree(sptr);
+ xmlSchemaFreeValidCtxt(vptr);
++ PHP_LIBXML_RESTORE_GLOBALS(validate);
+
+ if (is_valid == 0) {
+ RETURN_TRUE;
+@@ -2138,6 +2157,10 @@ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
+
+ switch (type) {
+ case DOM_LOAD_FILE:
++ if (strlen(source) != source_len) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source");
++ RETURN_FALSE;
++ }
+ valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (!valid_file) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source");
+@@ -2154,12 +2177,14 @@ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type)
+ return;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(parse);
+ xmlRelaxNGSetParserErrors(parser,
+ (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler,
+ (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler,
+ parser);
+ sptr = xmlRelaxNGParse(parser);
+ xmlRelaxNGFreeParserCtxt(parser);
++ PHP_LIBXML_RESTORE_GLOBALS(parse);
+ if (!sptr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG");
+ RETURN_FALSE;
+@@ -2216,7 +2241,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode)
+
+ id = getThis();
+
+- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) {
++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &source, &source_len) == FAILURE) {
+ return;
+ }
+
+@@ -2226,6 +2251,10 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode)
+ }
+
+ if (mode == DOM_LOAD_FILE) {
++ if (strlen(source) != source_len) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid file source");
++ RETURN_FALSE;
++ }
+ ctxt = htmlCreateFileParserCtxt(source, NULL);
+ } else {
+ source_len = xmlStrlen(source);
+@@ -2242,6 +2271,9 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode)
+ ctxt->sax->error = php_libxml_ctx_error;
+ ctxt->sax->warning = php_libxml_ctx_warning;
+ }
++
++ php_libxml_sanitize_parse_ctxt_options(ctxt);
++
+ htmlParseDocument(ctxt);
+ newdoc = ctxt->myDoc;
+ htmlFreeParserCtxt(ctxt);
+@@ -2308,7 +2340,7 @@ PHP_FUNCTION(dom_document_save_html_file)
+ dom_doc_propsptr doc_props;
+ char *file;
+
+- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &file, &file_len) == FAILURE) {
++ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &file, &file_len) == FAILURE) {
+ return;
+ }
+
+@@ -2350,7 +2382,7 @@ PHP_FUNCTION(dom_document_save_html)
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ htmlDocDumpMemory(docp, &mem, &size);
+- if (!size) {
++ if (!size || !mem) {
+ if (mem)
+ xmlFree(mem);
+ RETURN_FALSE;
+diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c
+index 4fa40d0e6..e994a8e3e 100644
+--- a/ext/dom/documentfragment.c
++++ b/ext/dom/documentfragment.c
+@@ -140,7 +140,9 @@ PHP_METHOD(domdocumentfragment, appendXML) {
+ }
+
+ if (data) {
++ PHP_LIBXML_SANITIZE_GLOBALS(parse);
+ err = xmlParseBalancedChunkMemory(nodep->doc, NULL, NULL, 0, data, &lst);
++ PHP_LIBXML_RESTORE_GLOBALS(parse);
+ if (err != 0) {
+ RETURN_FALSE;
+ }
+diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c
+index cda7ab83d..96c30b5fa 100644
+--- a/ext/dom/domimplementation.c
++++ b/ext/dom/domimplementation.c
+@@ -117,6 +117,10 @@ PHP_METHOD(domimplementation, createDocumentType)
+ if (systemid_len > 0)
+ pch2 = systemid;
+
++ if (strstr(name, "%00")) {
++ RETURN_FALSE;
++ }
++
+ uri = xmlParseURI(name);
+ if (uri != NULL && uri->opaque != NULL) {
+ localname = xmlStrdup(uri->opaque);
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 809a568a0..d81231473 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -1310,7 +1310,7 @@ static size_t exif_convert_any_to_int(void *value, int format, int motorola_inte
+ if (s_den == 0) {
+ return 0;
+ } else {
+- return php_ifd_get32s(value, motorola_intel) / s_den;
++ return (size_t)((double)php_ifd_get32s(value, motorola_intel) / s_den);
+ }
+
+ case TAG_FMT_SSHORT: return php_ifd_get16u(value, motorola_intel);
+@@ -1667,15 +1667,16 @@ static int exif_file_sections_free(image_info_type *ImageInfo)
+ /* {{{ exif_iif_add_value
+ Add a value to image_info
+ */
+-static void exif_iif_add_value(image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value, int motorola_intel TSRMLS_DC)
++static void exif_iif_add_value(image_info_type *image_info, int section_index, char *name, int tag, int format, size_t 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;
+
+- if (length < 0) {
++ if (length > INT_MAX) {
++ exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "Value too large");
+ return;
+ }
+
+@@ -1692,10 +1693,16 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
+
+ switch (format) {
+ case TAG_FMT_STRING:
++ if (length > value_len) {
++ exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %zu > %zu", length, value_len);
++ value = NULL;
++ }
+ if (value) {
+ length = php_strnlen(value, length);
+ if (PG(magic_quotes_runtime)) {
+- info_value->s = php_addslashes(value, length, &length, 0 TSRMLS_CC);
++ int escaped_length;
++ info_value->s = php_addslashes(value, (int)length, &escaped_length, 0 TSRMLS_CC);
++ length = escaped_length;
+ } else {
+ info_value->s = estrndup(value, length);
+ }
+@@ -1719,10 +1726,16 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
+ if (!length)
+ break;
+ case TAG_FMT_UNDEFINED:
++ if (length > value_len) {
++ exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %zu > %zu", length, value_len);
++ value = NULL;
++ }
+ if (value) {
+ /* do not recompute length here */
+ if (PG(magic_quotes_runtime)) {
+- info_value->s = php_addslashes(value, length, &length, 0 TSRMLS_CC);
++ int escaped_length;
++ info_value->s = php_addslashes(value, (int)length, &escaped_length, 0 TSRMLS_CC);
++ length = escaped_length;
+ } else {
+ info_value->s = estrndup(value, length);
+ }
+@@ -1743,13 +1756,19 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
+ case TAG_FMT_DOUBLE:
+ if (length==0) {
+ break;
+- } else
++ }
+ if (length>1) {
+ info_value->list = safe_emalloc(length, sizeof(image_info_value), 0);
+ } else {
+ info_value = &info_data->value;
+ }
+- for (idex=0,vptr=value; idex<(size_t)length; idex++,vptr=(char *) vptr + php_tiff_bytes_per_format[format]) {
++ vptr_end = (char *) value + value_len;
++ for (idex=0,vptr=value; idex<length; idex++,vptr=(char *) vptr + php_tiff_bytes_per_format[format]) {
++ if ((char *) vptr_end - (char *) vptr < php_tiff_bytes_per_format[format]) {
++ exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "Value too short");
++ info_data->length = idex;
++ break;
++ }
+ if (length>1) {
+ info_value = &info_data->value.list[idex];
+ }
+@@ -1784,13 +1803,14 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
+ #ifdef EXIF_DEBUG
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Found value of type single");
+ #endif
+- info_value->f = *(float *)value;
++ memcpy(&info_value->f, vptr, sizeof(info_value->f));
++ break;
+
+ case TAG_FMT_DOUBLE:
+ #ifdef EXIF_DEBUG
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Found value of type double");
+ #endif
+- info_value->d = *(double *)value;
++ memcpy(&info_value->d, vptr, sizeof(info_value->d));
+ break;
+ }
+ }
+@@ -1803,9 +1823,9 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
+ /* {{{ exif_iif_add_tag
+ Add a tag from IFD to image_info
+ */
+-static void exif_iif_add_tag(image_info_type *image_info, int section_index, char *name, int tag, int format, size_t length, void* value 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, length, value, value_len, image_info->motorola_intel TSRMLS_CC);
+ }
+ /* }}} */
+
+@@ -2241,7 +2261,7 @@ static void add_assoc_image_info(zval *value, int sub_array, image_info_type *im
+ */
+ static void exif_process_COM (image_info_type *image_info, char *value, size_t length 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);
+ }
+ /* }}} */
+
+@@ -2256,17 +2276,17 @@ static void exif_process_CME (image_info_type *image_info, char *value, size_t l
+ if (length>3) {
+ switch(value[2]) {
+ case 0:
+- exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value 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 TSRMLS_CC);
+ 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");
+ }
+ }
+@@ -2445,11 +2465,11 @@ static void* exif_ifd_make_value(image_info_data *info_data, int motorola_intel
+ data_ptr += 8;
+ break;
+ case TAG_FMT_SINGLE:
+- memmove(data_ptr, &info_data->value.f, byte_count);
++ memmove(data_ptr, &info_value->f, 4);
+ data_ptr += 4;
+ break;
+ case TAG_FMT_DOUBLE:
+- memmove(data_ptr, &info_data->value.d, byte_count);
++ memmove(data_ptr, &info_value->d, 8);
+ data_ptr += 8;
+ break;
+ }
+@@ -2570,7 +2590,10 @@ static void exif_thumbnail_extract(image_info_type *ImageInfo, char *offset, siz
+ return;
+ }
+ /* Check to make sure we are not going to go past the ExifLength */
+- if ((ImageInfo->Thumbnail.offset + ImageInfo->Thumbnail.size) > length) {
++ if (ImageInfo->Thumbnail.size > length
++ || (ImageInfo->Thumbnail.offset + ImageInfo->Thumbnail.size) > length
++ || ImageInfo->Thumbnail.offset > length - ImageInfo->Thumbnail.size
++ ) {
+ EXIF_ERRLOG_THUMBEOF(ImageInfo)
+ return;
+ }
+@@ -2641,7 +2664,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
+
+ #if EXIF_USE_MBSTRING
+ char *decode;
+- size_t len;;
++ size_t len;
+ #endif
+
+ *pszEncoding = NULL;
+@@ -2655,11 +2678,11 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
+ /* 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;
+@@ -2745,10 +2768,10 @@ static int exif_process_unicode(image_info_type *ImageInfo, xp_field_type *xp_fi
+ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * value_ptr, int value_len, char *offset_base, size_t IFDlength, size_t displacement TSRMLS_DC)
+ {
+ int de, i=0, section_index = SECTION_MAKERNOTE;
+- int NumDirEntries, old_motorola_intel;
+- int offset_diff;
++ int NumDirEntries, old_motorola_intel, offset_diff;
+ const maker_note_type *maker_note;
+ char *dir_start;
++ int data_len;
+
+ for (i=0; i<=sizeof(maker_note_array)/sizeof(maker_note_type); i++) {
+ if (i==sizeof(maker_note_array)/sizeof(maker_note_type))
+@@ -2760,11 +2783,18 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
+ 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;
+ }
+
++ if (value_len < 2 || maker_note->offset >= value_len - 1) {
++ /* Do not go past the value end */
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->offset);
++ return FALSE;
++ }
++
+ dir_start = value_ptr + maker_note->offset;
+
+ #ifdef EXIF_DEBUG
+@@ -2791,27 +2821,49 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
+ switch (maker_note->offset_mode) {
+ case MN_OFFSET_MAKER:
+ offset_base = value_ptr;
++ data_len = value_len;
+ break;
+ case MN_OFFSET_GUESS:
++ if (maker_note->offset + 10 + 4 >= value_len) {
++ /* Can not read dir_start+10 since it's beyond value end */
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X", value_len);
++ return FALSE;
++ }
+ offset_diff = 2 + NumDirEntries*12 + 4 - php_ifd_get32u(dir_start+10, ImageInfo->motorola_intel);
+ #ifdef EXIF_DEBUG
+ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Using automatic offset correction: 0x%04X", ((int)dir_start-(int)offset_base+maker_note->offset+displacement) + offset_diff);
+ #endif
++ if (offset_diff < 0 || offset_diff >= value_len ) {
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data bad offset: 0x%04X length 0x%04X", offset_diff, value_len);
++ return FALSE;
++ }
+ offset_base = value_ptr + offset_diff;
++ data_len = value_len - offset_diff;
+ break;
+ default:
+ case MN_OFFSET_NORMAL:
++ data_len = value_len;
+ break;
+ }
+
+ if ((2+NumDirEntries*12) > value_len) {
+- exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + x%04X*12 = x%04X > x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
++ return FALSE;
++ }
++ if ((dir_start - value_ptr) > value_len - (2+NumDirEntries*12)) {
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 0x%04X > 0x%04X", (dir_start - value_ptr) + (2+NumDirEntries*12), value_len);
+ return FALSE;
+ }
+
+ for (de=0;de<NumDirEntries;de++) {
+- if (!exif_process_IFD_TAG(ImageInfo, dir_start + 2 + 12 * de,
+- offset_base, IFDlength, displacement, section_index, 0, maker_note->tag_table TSRMLS_CC)) {
++ size_t offset = 2 + 12 * de;
++ /* data_len - offset is passed as size_t IFDlength; it must not wrap */
++ if (offset > (size_t)data_len) {
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD offset: 0x%04X > 0x%04X", (int)offset, data_len);
++ return FALSE;
++ }
++ if (!exif_process_IFD_TAG(ImageInfo, dir_start + offset,
++ offset_base, data_len - offset, displacement, section_index, 0, maker_note->tag_table TSRMLS_CC)) {
+ return FALSE;
+ }
+ }
+@@ -2829,7 +2881,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
+ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table 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;
+@@ -2875,7 +2927,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
+ offset_val = php_ifd_get32u(dir_entry+8, ImageInfo->motorola_intel);
+ /* If its bigger than 4 bytes, the dir entry contains an offset. */
+ value_ptr = offset_base+offset_val;
+- if (byte_count > IFDlength || offset_val > IFDlength-byte_count || value_ptr < dir_entry) {
++ 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. */
+@@ -2986,7 +3038,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
+ /* When there are any characters after the first NUL */
+ ImageInfo->CopyrightPhotographer = estrdup(value_ptr);
+ ImageInfo->CopyrightEditor = estrdup(value_ptr+length+1);
+- spprintf(&ImageInfo->Copyright, 0, "%s, %s", value_ptr, value_ptr+length+1);
++ spprintf(&ImageInfo->Copyright, 0, "%s, %s", ImageInfo->CopyrightPhotographer, ImageInfo->CopyrightEditor);
+ /* format = TAG_FMT_UNDEFINED; this musn't be ASCII */
+ /* but we are not supposed to change this */
+ /* keep in mind that image_info does not store editor value */
+@@ -3089,7 +3141,10 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
+ break;
+
+ case TAG_MAKER_NOTE:
+- exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement TSRMLS_CC);
++ if (!exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement TSRMLS_CC)) {
++ EFREE_IF(outside);
++ return FALSE;
++ }
+ break;
+
+ case TAG_EXIF_IFD_POINTER:
+@@ -3135,7 +3190,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
+ }
+ }
+ }
+- exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table 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;
+ }
+@@ -3155,6 +3210,11 @@ static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start,
+
+ ImageInfo->sections_found |= FOUND_IFD0;
+
++ if ((dir_start + 2) >= (offset_base+IFDlength)) {
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size");
++ return FALSE;
++ }
++
+ NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->motorola_intel);
+
+ if ((dir_start+2+NumDirEntries*12) > (offset_base+IFDlength)) {
+@@ -3178,6 +3238,10 @@ static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start,
+ * Hack to make it process IDF1 I hope
+ * There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail
+ */
++ if ((dir_start+2+12*de + 4) >= (offset_base+IFDlength)) {
++ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size");
++ return FALSE;
++ }
+ NextDirOffset = php_ifd_get32u(dir_start+2+12*de, ImageInfo->motorola_intel);
+ if (NextDirOffset) {
+ /* the next line seems false but here IFDlength means length of all IFDs */
+@@ -3216,6 +3280,11 @@ static void exif_process_TIFF_in_JPEG(image_info_type *ImageInfo, char *CharBuf,
+ {
+ 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;
+@@ -3227,9 +3296,13 @@ static void exif_process_TIFF_in_JPEG(image_info_type *ImageInfo, char *CharBuf,
+ }
+
+ /* Check the next two values for correctness. */
++ if (length < 8) {
++ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid TIFF start (1)");
++ return;
++ }
+ exif_value_2a = php_ifd_get16u(CharBuf+2, ImageInfo->motorola_intel);
+ offset_of_ifd = php_ifd_get32u(CharBuf+4, ImageInfo->motorola_intel);
+- if ( exif_value_2a != 0x2a || offset_of_ifd < 0x08) {
++ if (exif_value_2a != 0x2a || offset_of_ifd < 0x08) {
+ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid TIFF start (1)");
+ return;
+ }
+@@ -3280,10 +3353,10 @@ static void exif_process_APP12(image_info_type *ImageInfo, char *buffer, size_t
+ size_t l1, l2=0;
+
+ if ((l1 = php_strnlen(buffer+2, length-2)) > 0) {
+- exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2 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);
++ 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, l2 TSRMLS_CC);
+ }
+ }
+ #ifdef EXIF_DEBUG
+@@ -3364,7 +3437,7 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo TSRMLS_DC)
+ 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. */
+@@ -3465,7 +3538,7 @@ static int exif_scan_thumbnail(image_info_type *ImageInfo TSRMLS_DC)
+ 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)) {
+@@ -3493,8 +3566,10 @@ static int exif_scan_thumbnail(image_info_type *ImageInfo TSRMLS_DC)
+ if (c == 0xFF)
+ return FALSE;
+ marker = c;
++ if (pos>=ImageInfo->Thumbnail.size)
++ return FALSE;
+ 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
+@@ -3515,6 +3590,10 @@ static int exif_scan_thumbnail(image_info_type *ImageInfo TSRMLS_DC)
+ 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;
+@@ -3752,6 +3831,10 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
+ fgot = php_stream_read(ImageInfo->infile, ImageInfo->Thumbnail.data, ImageInfo->Thumbnail.size);
+ if (fgot < ImageInfo->Thumbnail.size) {
+ EXIF_ERRLOG_THUMBEOF(ImageInfo)
++ efree(ImageInfo->Thumbnail.data);
++ ImageInfo->Thumbnail.data = NULL;
++ } else {
++ exif_thumbnail_build(ImageInfo TSRMLS_CC);
+ }
+ exif_thumbnail_build(ImageInfo TSRMLS_CC);
+ }
+@@ -4084,7 +4167,7 @@ PHP_FUNCTION(exif_read_data)
+ if (ImageInfo.Thumbnail.size) {
+ if (read_thumbnail) {
+ /* not exif_iif_add_str : this is a buffer */
+- exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data 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 */
+@@ -4169,7 +4252,9 @@ PHP_FUNCTION(exif_thumbnail)
+ 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);
+diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
+index 1c8f71407..9adc8c0e2 100644
+--- a/ext/filter/logical_filters.c
++++ b/ext/filter/logical_filters.c
+@@ -437,6 +437,22 @@ void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
+ }
+ /* }}} */
+
++static int is_userinfo_valid(char *str)
++{
++ const char *valid = "-._~!$&'()*+,;=:";
++ const char *p = str;
++ while (p - str < strlen(str)) {
++ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
++ p++;
++ } else if (*p == '%' && p - str <= strlen(str) - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) {
++ p += 3;
++ } else {
++ return 0;
++ }
++ }
++ return 1;
++}
++
+ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
+ {
+ php_url *url;
+@@ -492,6 +508,14 @@ bad_url:
+ php_url_free(url);
+ RETURN_VALIDATION_FAILED
+ }
++
++ if (url->user != NULL && !is_userinfo_valid(url->user)
++ || url->pass != NULL && !is_userinfo_valid(url->pass)
++ ) {
++ php_url_free(url);
++ RETURN_VALIDATION_FAILED
++ }
++
+ php_url_free(url);
+ }
+ /* }}} */
+diff --git a/ext/filter/sanitizing_filters.c b/ext/filter/sanitizing_filters.c
+index ae210815c..d2f192fb7 100644
+--- a/ext/filter/sanitizing_filters.c
++++ b/ext/filter/sanitizing_filters.c
+@@ -71,7 +71,7 @@ static void php_filter_encode_url(zval *value, const unsigned char* chars, const
+ unsigned char *s = (unsigned char *)chars;
+ unsigned char *e = s + char_len;
+
+- memset(tmp, 1, sizeof(tmp)-1);
++ memset(tmp, 1, sizeof(tmp));
+
+ while (s < e) {
+ tmp[*s++] = 0;
+diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
+index c0c0c27fc..e7acc517c 100644
+--- a/ext/ftp/ftp.c
++++ b/ext/ftp/ftp.c
+@@ -694,7 +694,7 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
+ char *ptr;
+ union ipbox ipbox;
+ unsigned long b[6];
+- socklen_t n;
++ socklen_t n;
+ struct sockaddr *sa;
+ struct sockaddr_in *sin;
+
+@@ -1595,8 +1595,8 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
+ databuf_t *data = NULL;
+ char *ptr;
+ int ch, lastch;
+- int size, rcvd;
+- int lines;
++ size_t size, rcvd;
++ size_t lines;
+ char **ret = NULL;
+ char **entry;
+ char *text;
+@@ -1638,7 +1638,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
+ lines = 0;
+ lastch = 0;
+ while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {
+- if (rcvd == -1) {
++ if (rcvd == -1 || rcvd > ((size_t)(-1))-size) {
+ goto bail;
+ }
+
+diff --git a/ext/gd/gd.c b/ext/gd/gd.c
+index f3bce50a2..53ff7089c 100644
+--- a/ext/gd/gd.c
++++ b/ext/gd/gd.c
+@@ -1594,6 +1594,10 @@ PHP_FUNCTION(imageloadfont)
+
+ convert_to_string_ex(file);
+
++ if (strlen(Z_STRVAL_PP(file)) != Z_STRLEN_PP(file)) {
++ RETURN_FALSE;
++ }
++
+ stream = php_stream_open_wrapper(Z_STRVAL_PP(file), "rb", ENFORCE_SAFE_MODE | IGNORE_PATH | IGNORE_URL_WIN | REPORT_ERRORS, NULL);
+ if (stream == NULL) {
+ RETURN_FALSE;
+@@ -1800,11 +1804,11 @@ PHP_FUNCTION(imagetruecolortopalette)
+ convert_to_boolean_ex(dither);
+ convert_to_long_ex(ncolors);
+
+- if (Z_LVAL_PP(ncolors) <= 0) {
+- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of colors has to be greater than zero");
++ if (Z_LVAL_PP(ncolors) <= 0 || Z_LVAL_PP(ncolors) > INT_MAX) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of colors has to be greater than zero and no more than %d", INT_MAX);
+ RETURN_FALSE;
+ }
+- gdImageTrueColorToPalette(im, Z_LVAL_PP(dither), Z_LVAL_PP(ncolors));
++ gdImageTrueColorToPalette(im, Z_LVAL_PP(dither), (int)Z_LVAL_PP(ncolors));
+
+ RETURN_TRUE;
+ }
+@@ -2601,6 +2605,10 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
+
+ convert_to_string_ex(file);
+
++ if (strlen(Z_STRVAL_PP(file)) != Z_STRLEN_PP(file)) {
++ RETURN_FALSE;
++ }
++
+ if (argc == 5 && image_type == PHP_GDIMG_TYPE_GD2PART) {
+ multi_convert_to_long_ex(4, srcx, srcy, width, height);
+ if (Z_LVAL_PP(width) < 1 || Z_LVAL_PP(height) < 1) {
+@@ -2833,7 +2841,10 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
+
+ if (argc >= 2 && Z_STRLEN_PP(file)) {
+ PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
+-
++ if (Z_STRLEN_PP(file) != strlen(Z_STRVAL_PP(file))) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 2nd parameter, filename must not contain null bytes");
++ RETURN_FALSE;
++ }
+ fp = VCWD_FOPEN(fn, "wb");
+ if (!fp) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' for writing", fn);
+@@ -3364,6 +3375,11 @@ PHP_FUNCTION(imagegammacorrect)
+ input = Z_DVAL_PP(inputgamma);
+ output = Z_DVAL_PP(outputgamma);
+
++ if ( input <= 0.0 || output <= 0.0 ) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Gamma values should be positive");
++ RETURN_FALSE;
++ }
++
+ ZEND_FETCH_RESOURCE(im, gdImagePtr, IM, -1, "Image", le_gd);
+
+ #if HAVE_LIBGD20
+@@ -4379,7 +4395,9 @@ PHP_FUNCTION(imagepsloadfont)
+ }
+
+ convert_to_string_ex(file);
+-
++ if (strlen(Z_STRVAL_PP(file)) != Z_STRLEN_PP(file)) {
++ RETURN_FALSE;
++ }
+ #ifdef PHP_WIN32
+ if (VCWD_STAT(Z_STRVAL_PP(file), &st) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Font file not found (%s)", Z_STRVAL_PP(file));
+@@ -4492,6 +4510,10 @@ PHP_FUNCTION(imagepsencodefont)
+
+ convert_to_string_ex(enc);
+
++ if (strlen(Z_STRVAL_PP(enc)) != Z_STRLEN_PP(enc)) {
++ RETURN_FALSE;
++ }
++
+ ZEND_FETCH_RESOURCE(f_ind, int *, fnt, -1, "Type 1 font", le_ps_font);
+
+ if ((enc_vector = T1_LoadEncoding(Z_STRVAL_PP(enc))) == NULL) {
+diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c
+index 2a0ef8721..6608bab75 100644
+--- a/ext/gd/gd_ctx.c
++++ b/ext/gd/gd_ctx.c
+@@ -92,6 +92,10 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
+ if (argc > 1 && (Z_TYPE_PP(file) != IS_NULL && ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))))) {
+
+ PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
++ if (Z_STRLEN_PP(file) != strlen(Z_STRVAL_PP(file))) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid 2nd parameter, filename must not contain null bytes");
++ RETURN_FALSE;
++ }
+
+ fp = VCWD_FOPEN(fn, "wb");
+ if (!fp) {
+diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
+index 94934f599..e08a32edf 100644
+--- a/ext/gd/libgd/gd.c
++++ b/ext/gd/libgd/gd.c
+@@ -1097,7 +1097,7 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
+ }
+
+ /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
+- if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {
++ if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)-1) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im)-1)) {
+ return;
+ }
+
+@@ -1281,55 +1281,10 @@ void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
+ long x, y, inc;
+ long dx, dy,tmp;
+
+- if (y1 < 0 && y2 < 0) {
+- return;
+- }
+- if (y1 < 0) {
+- x1 += (y1 * (x1 - x2)) / (y2 - y1);
+- y1 = 0;
+- }
+- if (y2 < 0) {
+- x2 += (y2 * (x1 - x2)) / (y2 - y1);
+- y2 = 0;
+- }
+-
+- /* bottom edge */
+- if (y1 >= im->sy && y2 >= im->sy) {
+- return;
+- }
+- if (y1 >= im->sy) {
+- x1 -= ((im->sy - y1) * (x1 - x2)) / (y2 - y1);
+- y1 = im->sy - 1;
+- }
+- if (y2 >= im->sy) {
+- x2 -= ((im->sy - y2) * (x1 - x2)) / (y2 - y1);
+- y2 = im->sy - 1;
+- }
+-
+- /* left edge */
+- if (x1 < 0 && x2 < 0) {
+- return;
+- }
+- if (x1 < 0) {
+- y1 += (x1 * (y1 - y2)) / (x2 - x1);
+- x1 = 0;
+- }
+- if (x2 < 0) {
+- y2 += (x2 * (y1 - y2)) / (x2 - x1);
+- x2 = 0;
+- }
+- /* right edge */
+- if (x1 >= im->sx && x2 >= im->sx) {
++ /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */
++ if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)-1) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im)-1)) {
+ return;
+ }
+- if (x1 >= im->sx) {
+- y1 -= ((im->sx - x1) * (y1 - y2)) / (x2 - x1);
+- x1 = im->sx - 1;
+- }
+- if (x2 >= im->sx) {
+- y2 -= ((im->sx - x2) * (y1 - y2)) / (x2 - x1);
+- x2 = im->sx - 1;
+- }
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+@@ -1853,7 +1808,7 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
+ int leftLimit = -1, rightLimit;
+ int i, restoreAlphaBlending = 0;
+
+- if (border < 0) {
++ if (border < 0 || color < 0) {
+ /* Refuse to fill to a non-solid border */
+ return;
+ }
+@@ -1863,9 +1818,13 @@ void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
+
+ if (x >= im->sx) {
+ x = im->sx - 1;
++ } else if (x < 0) {
++ x = 0;
+ }
+ if (y >= im->sy) {
+ y = im->sy - 1;
++ } else if (y < 0) {
++ y = 0;
+ }
+
+ for (i = x; i >= 0; i--) {
+diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c
+index efc6ef47a..81e27198c 100644
+--- a/ext/gd/libgd/gd_gd2.c
++++ b/ext/gd/libgd/gd_gd2.c
+@@ -136,13 +136,23 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in
+ GD2_DBG(php_gd_error("%d Chunks vertically", *ncy));
+
+ if (gd2_compressed(*fmt)) {
++ if (*ncx <= 0 || *ncy <= 0 || *ncx > INT_MAX / *ncy) {
++ GD2_DBG(printf ("Illegal chunk counts: %d * %d\n", *ncx, *ncy));
++ goto fail1;
++ }
+ nc = (*ncx) * (*ncy);
+ GD2_DBG(php_gd_error("Reading %d chunk index entries", nc));
++ if (overflow2(sizeof(t_chunk_info), nc)) {
++ goto fail1;
++ }
+ sidx = sizeof(t_chunk_info) * nc;
+ if (sidx <= 0) {
+ goto fail1;
+ }
+ cidx = gdCalloc(sidx, 1);
++ if (cidx == NULL) {
++ goto fail1;
++ }
+ for (i = 0; i < nc; i++) {
+ if (gdGetInt(&cidx[i].offset, in) != 1) {
+ goto fail1;
+@@ -150,6 +160,9 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in
+ if (gdGetInt(&cidx[i].size, in) != 1) {
+ goto fail1;
+ }
++ if (cidx[i].offset < 0 || cidx[i].size < 0) {
++ goto fail1;
++ }
+ }
+ *chunkIdx = cidx;
+ }
+@@ -327,12 +340,16 @@ gdImagePtr gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
+ for (x = xlo; x < xhi; x++) {
+ if (im->trueColor) {
+ if (!gdGetInt(&im->tpixels[y][x], in)) {
+- im->tpixels[y][x] = 0;
++ php_gd_error("gd2: EOF while reading\n");
++ gdImageDestroy(im);
++ return NULL;
+ }
+ } else {
+ int ch;
+ if (!gdGetByte(&ch, in)) {
+- ch = 0;
++ php_gd_error("gd2: EOF while reading\n");
++ gdImageDestroy(im);
++ return NULL;
+ }
+ im->pixels[y][x] = ch;
+ }
+diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c
+index ee88a2fc8..0ec1ad0e5 100644
+--- a/ext/gd/libgd/gd_gif_in.c
++++ b/ext/gd/libgd/gd_gif_in.c
+@@ -145,6 +145,9 @@ gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr fd) /* {{{ */
+ int haveGlobalColormap;
+ gdImagePtr im = 0;
+
++ memset(ColorMap, 0, 3 * MAXCOLORMAPSIZE);
++ memset(localColorMap, 0, 3 * MAXCOLORMAPSIZE);
++
+ /*1.4//imageNumber = 1; */
+ if (! ReadOK(fd,buf,6)) {
+ return 0;
+@@ -256,10 +259,6 @@ terminated:
+ if (!im) {
+ return 0;
+ }
+- if (!im->colorsTotal) {
+- gdImageDestroy(im);
+- return 0;
+- }
+ /* Check for open colors at the end, so
+ we can reduce colorsTotal and ultimately
+ BitsPerPixel */
+@@ -270,6 +269,10 @@ terminated:
+ break;
+ }
+ }
++ if (!im->colorsTotal) {
++ gdImageDestroy(im);
++ return 0;
++ }
+ return im;
+ }
+ /* }}} */
+@@ -370,7 +373,7 @@ static int
+ GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
+ {
+ int i, j, ret;
+- unsigned char count;
++ int count;
+
+ if (flag) {
+ scd->curbit = 0;
+diff --git a/ext/gd/libgd/gd_io_dp.c b/ext/gd/libgd/gd_io_dp.c
+index bfeb4cb4b..4dcedde8c 100644
+--- a/ext/gd/libgd/gd_io_dp.c
++++ b/ext/gd/libgd/gd_io_dp.c
+@@ -237,7 +237,7 @@ static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
+ if (remain >= len) {
+ rlen = len;
+ } else {
+- if (remain == 0) {
++ if (remain <= 0) {
+ return EOF;
+ }
+ rlen = remain;
+diff --git a/ext/gd/libgd/gd_topal.c b/ext/gd/libgd/gd_topal.c
+index d2cd13f5b..f55dcd591 100644
+--- a/ext/gd/libgd/gd_topal.c
++++ b/ext/gd/libgd/gd_topal.c
+@@ -2091,8 +2091,8 @@ int gdImageColorMatch (gdImagePtr im1, gdImagePtr im2)
+ return -4; /* At least 1 color must be allocated */
+ }
+
+- buf = (unsigned long *)safe_emalloc(sizeof(unsigned long), 5 * im2->colorsTotal, 0);
+- memset( buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal );
++ buf = (unsigned long *)safe_emalloc(sizeof(unsigned long), 5 * gdMaxColors, 0);
++ memset( buf, 0, sizeof(unsigned long) * 5 * gdMaxColors );
+
+ for (x=0; x<im1->sx; x++) {
+ for( y=0; y<im1->sy; y++ ) {
+diff --git a/ext/gd/libgd/xbm.c b/ext/gd/libgd/xbm.c
+index 053d22315..838043c3b 100644
+--- a/ext/gd/libgd/xbm.c
++++ b/ext/gd/libgd/xbm.c
+@@ -135,7 +135,11 @@ gdImagePtr gdImageCreateFromXbm(FILE * fd)
+ }
+ 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) {
+diff --git a/ext/hash/hash.c b/ext/hash/hash.c
+index 7bdda75ff..3d17f3bda 100644
+--- a/ext/hash/hash.c
++++ b/ext/hash/hash.c
+@@ -157,6 +157,14 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
+ RETURN_FALSE;
+ }
+ if (isfilename) {
++ if (strlen(data) != data_len) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path");
++ RETURN_FALSE;
++ }
++ if (strlen(data) != data_len) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path");
++ RETURN_FALSE;
++ }
+ stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL, DEFAULT_CONTEXT);
+ if (!stream) {
+ /* Stream will report errors opening file */
+@@ -381,7 +389,7 @@ PHP_FUNCTION(hash_update_file)
+ char *filename, buf[1024];
+ int filename_len, n;
+
+- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) {
++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rp|r", &zhash, &filename, &filename_len, &zcontext) == FAILURE) {
+ return;
+ }
+
+diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c
+index 7806db0d4..2a9a90f53 100644
+--- a/ext/iconv/iconv.c
++++ b/ext/iconv/iconv.c
+@@ -2556,6 +2556,9 @@ static int php_iconv_stream_filter_append_bucket(
+ tcnt = 0;
+ break;
+ }
++ } else {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "iconv stream filter (\"%s\"=>\"%s\"): invalid multibyte sequence", self->from_charset, self->to_charset);
++ goto out_failure;
+ }
+ break;
+
+diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c
+index 009ca135f..51bfd80e7 100644
+--- a/ext/imap/php_imap.c
++++ b/ext/imap/php_imap.c
+@@ -188,6 +188,15 @@ static zend_module_dep imap_deps[] = {
+ };
+ /* }}} */
+
++
++/* {{{ PHP_INI
++ */
++PHP_INI_BEGIN()
++STD_PHP_INI_BOOLEAN("imap.enable_insecure_rsh", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_rsh, zend_imap_globals, imap_globals)
++PHP_INI_END()
++/* }}} */
++
++
+ /* {{{ imap_module_entry
+ */
+ zend_module_entry imap_module_entry = {
+@@ -503,6 +512,8 @@ PHP_MINIT_FUNCTION(imap)
+ {
+ unsigned long sa_all = SA_MESSAGES | SA_RECENT | SA_UNSEEN | SA_UIDNEXT | SA_UIDVALIDITY;
+
++ REGISTER_INI_ENTRIES();
++
+ #ifndef PHP_WIN32
+ mail_link(&unixdriver); /* link in the unix driver */
+ mail_link(&mhdriver); /* link in the mh driver */
+@@ -544,6 +555,9 @@ PHP_MINIT_FUNCTION(imap)
+ mail_parameters(NIL, SET_WRITETIMEOUT, (void *) FG(default_socket_timeout));
+ mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) FG(default_socket_timeout));
+
++ /* disable rsh globally */
++ mail_parameters(NIL, SET_RSHTIMEOUT, 0);
++
+ /* timeout constants */
+ REGISTER_LONG_CONSTANT("IMAP_OPENTIMEOUT", 1, CONST_PERSISTENT | CONST_CS);
+ REGISTER_LONG_CONSTANT("IMAP_READTIMEOUT", 2, CONST_PERSISTENT | CONST_CS);
+@@ -717,6 +731,12 @@ PHP_MINIT_FUNCTION(imap)
+ ENCOTHER unknown
+ */
+
++ if (!IMAPG(enable_rsh)) {
++ /* disable SSH and RSH, see https://bugs.php.net/bug.php?id=77153 */
++ mail_parameters (NIL, SET_RSHTIMEOUT, 0);
++ mail_parameters (NIL, SET_SSHTIMEOUT, 0);
++ }
++
+ le_imap = zend_register_list_destructors_ex(mail_close_it, NULL, "imap", module_number);
+ return SUCCESS;
+ }
+@@ -2221,7 +2241,7 @@ PHP_FUNCTION(imap_base64)
+ RETURN_FALSE;
+ }
+
+- RETVAL_STRINGL(decode, newlength, 1);
++ RETVAL_STRINGL_CHECK(decode, newlength, 1);
+ fs_give((void**) &decode);
+ }
+ /* }}} */
+@@ -3687,7 +3707,7 @@ int _php_imap_mail(char *to, char *subject, char *message, char *headers, char *
+ char *tsm_errmsg = NULL;
+ ADDRESS *addr;
+ char *bufferTo = NULL, *bufferCc = NULL, *bufferBcc = NULL, *bufferHeader = NULL;
+- int offset, bufferLen = 0;
++ size_t offset, bufferLen = 0;
+ size_t bt_len;
+
+ if (headers) {
+@@ -3871,7 +3891,6 @@ PHP_FUNCTION(imap_mail)
+ } else {
+ /* this is not really an error, so it is allowed. */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No message string in mail command");
+- message = NULL;
+ }
+
+ /* other headers */
+diff --git a/ext/imap/php_imap.h b/ext/imap/php_imap.h
+index 5a3880780..720dd1e95 100644
+--- a/ext/imap/php_imap.h
++++ b/ext/imap/php_imap.h
+@@ -219,6 +219,7 @@ ZEND_BEGIN_MODULE_GLOBALS(imap)
+ #endif
+ /* php_stream for php_mail_gets() */
+ php_stream *gets_stream;
++ zend_bool enable_rsh;
+ ZEND_END_MODULE_GLOBALS(imap)
+
+ #ifdef ZTS
+diff --git a/ext/interbase/interbase.c b/ext/interbase/interbase.c
+index 0a027510e..8a6aafb19 100644
+--- a/ext/interbase/interbase.c
++++ b/ext/interbase/interbase.c
+@@ -725,9 +725,12 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /*
+ ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
+ } else {
+ zend_rsrc_list_entry new_le;
+-
++
+ ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
+-
++ if (!ib_link) {
++ RETURN_FALSE;
++ }
++
+ /* hash it up */
+ Z_TYPE(new_le) = le_plink;
+ new_le.ptr = ib_link;
+diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
+index bfdd6a91e..d6b8914f4 100644
+--- a/ext/ldap/ldap.c
++++ b/ext/ldap/ldap.c
+@@ -1112,7 +1112,11 @@ PHP_FUNCTION(ldap_get_entries)
+
+ add_assoc_long(tmp1, "count", num_attrib);
+ dn = ldap_get_dn(ldap, ldap_result_entry);
+- add_assoc_string(tmp1, "dn", dn, 1);
++ if (dn) {
++ add_assoc_string(tmp1, "dn", dn, 1);
++ } else {
++ add_assoc_null(tmp1, "dn");
++ }
+ #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+ ldap_memfree(dn);
+ #else
+diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
+index 3bb8db5f0..307c382ac 100644
+--- a/ext/libxml/libxml.c
++++ b/ext/libxml/libxml.c
+@@ -296,6 +296,9 @@ static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char
+ xmlURI *uri;
+
+ TSRMLS_FETCH();
++ if (strstr(filename, "%00")) {
++ return NULL;
++ }
+
+ uri = xmlParseURI((xmlChar *)filename);
+ if (uri && (uri->scheme == NULL || (xmlStrncmp(uri->scheme, "file", 4) == 0))) {
+@@ -366,17 +369,16 @@ static int php_libxml_streams_IO_close(void *context)
+ return php_stream_close((php_stream*)context);
+ }
+
+-static xmlParserInputBufferPtr
+-php_libxml_input_buffer_noload(const char *URI, xmlCharEncoding enc)
+-{
+- return NULL;
+-}
+-
+ static xmlParserInputBufferPtr
+ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
+ {
+ xmlParserInputBufferPtr ret;
+ void *context = NULL;
++ TSRMLS_FETCH();
++
++ if (LIBXML(entity_loader_disabled)) {
++ return NULL;
++ }
+
+ if (URI == NULL)
+ return(NULL);
+@@ -414,6 +416,10 @@ php_libxml_output_buffer_create_filename(const char *URI,
+ if (URI == NULL)
+ return(NULL);
+
++ if (strstr(URI, "%00")) {
++ return NULL;
++ }
++
+ puri = xmlParseURI(URI);
+ if (puri != NULL) {
+ if (puri->scheme != NULL)
+@@ -668,6 +674,7 @@ static PHP_MINIT_FUNCTION(libxml)
+
+ static PHP_RINIT_FUNCTION(libxml)
+ {
++ LIBXML(entity_loader_disabled) = 0;
+ /* report errors via handler rather than stderr */
+ xmlSetGenericErrorFunc(NULL, php_libxml_error_handler);
+ xmlParserInputBufferCreateFilenameDefault(php_libxml_input_buffer_create_filename);
+@@ -858,28 +865,25 @@ static PHP_FUNCTION(libxml_clear_errors)
+ }
+ /* }}} */
+
++PHP_LIBXML_API zend_bool php_libxml_disable_entity_loader(zend_bool disable TSRMLS_DC)
++{
++ zend_bool old = LIBXML(entity_loader_disabled);
++
++ LIBXML(entity_loader_disabled) = disable;
++ return old;
++}
++
+ /* {{{ proto bool libxml_disable_entity_loader([boolean disable])
+ Disable/Enable ability to load external entities */
+ static PHP_FUNCTION(libxml_disable_entity_loader)
+ {
+ zend_bool disable = 1;
+- xmlParserInputBufferCreateFilenameFunc old;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &disable) == FAILURE) {
+ return;
+ }
+
+- if (disable == 0) {
+- old = xmlParserInputBufferCreateFilenameDefault(php_libxml_input_buffer_create_filename);
+- } else {
+- old = xmlParserInputBufferCreateFilenameDefault(php_libxml_input_buffer_noload);
+- }
+-
+- if (old == php_libxml_input_buffer_noload) {
+- RETURN_TRUE;
+- }
+-
+- RETURN_FALSE;
++ RETURN_BOOL(php_libxml_disable_entity_loader(disable TSRMLS_CC));
+ }
+ /* }}} */
+
+diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h
+index 2621dbeb1..746ee8106 100644
+--- a/ext/libxml/php_libxml.h
++++ b/ext/libxml/php_libxml.h
+@@ -96,6 +96,7 @@ void php_libxml_ctx_error(void *ctx, const char *msg, ...);
+ PHP_LIBXML_API int php_libxml_xmlCheckUTF8(const unsigned char *s);
+ PHP_LIBXML_API zval *php_libxml_switch_context(zval *context TSRMLS_DC);
+ PHP_LIBXML_API void php_libxml_issue_error(int level, const char *msg TSRMLS_DC);
++PHP_LIBXML_API zend_bool php_libxml_disable_entity_loader(zend_bool disable TSRMLS_DC);
+
+ /* Init/shutdown functions*/
+ PHP_LIBXML_API void php_libxml_initialize(void);
+@@ -107,6 +108,42 @@ PHP_LIBXML_API void php_libxml_shutdown(void);
+ #define LIBXML(v) (libxml_globals.v)
+ #endif
+
++/* Other extension may override the global state options, these global options
++ * are copied initially to ctxt->options. Set the options to a known good value.
++ * See libxml2 globals.c and parserInternals.c.
++ * The unique_name argument allows multiple sanitizes and restores within the
++ * same function, even nested is necessary. */
++#define PHP_LIBXML_SANITIZE_GLOBALS(unique_name) \
++ int xml_old_loadsubset_##unique_name = xmlLoadExtDtdDefaultValue; \
++ xmlLoadExtDtdDefaultValue = 0; \
++ int xml_old_validate_##unique_name = xmlDoValidityCheckingDefaultValue; \
++ xmlDoValidityCheckingDefaultValue = 0; \
++ int xml_old_pedantic_##unique_name = xmlPedanticParserDefault(0); \
++ int xml_old_substitute_##unique_name = xmlSubstituteEntitiesDefault(0); \
++ int xml_old_linenrs_##unique_name = xmlLineNumbersDefault(0); \
++ int xml_old_blanks_##unique_name = xmlKeepBlanksDefault(1);
++
++#define PHP_LIBXML_RESTORE_GLOBALS(unique_name) \
++ xmlLoadExtDtdDefaultValue = xml_old_loadsubset_##unique_name; \
++ xmlDoValidityCheckingDefaultValue = xml_old_validate_##unique_name; \
++ (void) xmlPedanticParserDefault(xml_old_pedantic_##unique_name); \
++ (void) xmlSubstituteEntitiesDefault(xml_old_substitute_##unique_name); \
++ (void) xmlLineNumbersDefault(xml_old_linenrs_##unique_name); \
++ (void) xmlKeepBlanksDefault(xml_old_blanks_##unique_name);
++
++/* Alternative for above, working directly on the context and not setting globals.
++ * Generally faster because no locking is involved, and this has the advantage that it sets the options to a known good value. */
++static void php_libxml_sanitize_parse_ctxt_options(xmlParserCtxtPtr ctxt)
++{
++ ctxt->loadsubset = 0;
++ ctxt->validate = 0;
++ ctxt->pedantic = 0;
++ ctxt->replaceEntities = 0;
++ ctxt->linenumbers = 0;
++ ctxt->keepBlanks = 1;
++ ctxt->options = 0;
++}
++
+ #else /* HAVE_LIBXML */
+ #define libxml_module_ptr NULL
+ #endif
+diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
+index bcf606598..6b7c45bfe 100644
+--- a/ext/mbstring/mbstring.c
++++ b/ext/mbstring/mbstring.c
+@@ -2779,7 +2779,7 @@ PHP_FUNCTION(mb_encode_mimeheader)
+ mbfl_string_init(&result);
+ ret = mbfl_mime_header_encode(&string, &result, charset, transenc, linefeed, indent);
+ if (ret != NULL) {
+- RETVAL_STRINGL((char *)ret->val, ret->len, 0) /* the string is already strdup()'ed */
++ RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */
+ } else {
+ RETVAL_FALSE;
+ }
+@@ -2803,7 +2803,7 @@ PHP_FUNCTION(mb_decode_mimeheader)
+ mbfl_string_init(&result);
+ ret = mbfl_mime_header_decode(&string, &result, MBSTRG(current_internal_encoding));
+ if (ret != NULL) {
+- RETVAL_STRINGL((char *)ret->val, ret->len, 0) /* the string is already strdup()'ed */
++ RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */
+ } else {
+ RETVAL_FALSE;
+ }
+@@ -2906,7 +2906,7 @@ PHP_FUNCTION(mb_convert_kana)
+
+ ret = mbfl_ja_jp_hantozen(&string, &result, opt);
+ if (ret != NULL) {
+- RETVAL_STRINGL((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */
++ RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */
+ } else {
+ RETVAL_FALSE;
+ }
+@@ -3204,7 +3204,7 @@ php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type)
+
+ ret = mbfl_html_numeric_entity(&string, &result, convmap, mapsize, type);
+ if (ret != NULL) {
+- RETVAL_STRINGL((char *)ret->val, ret->len, 0);
++ RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0);
+ } else {
+ RETVAL_FALSE;
+ }
+diff --git a/ext/mbstring/oniguruma/enc/utf16_be.c b/ext/mbstring/oniguruma/enc/utf16_be.c
+index 33b520a23..92ac464f5 100755
+--- a/ext/mbstring/oniguruma/enc/utf16_be.c
++++ b/ext/mbstring/oniguruma/enc/utf16_be.c
+@@ -79,11 +79,13 @@ utf16be_mbc_to_code(const UChar* p, const UChar* end)
+ OnigCodePoint code;
+
+ if (UTF16_IS_SURROGATE_FIRST(*p)) {
++ if (end - p < 4) return 0;
+ code = ((((p[0] - 0xd8) << 2) + ((p[1] & 0xc0) >> 6) + 1) << 16)
+ + ((((p[1] & 0x3f) << 2) + (p[2] - 0xdc)) << 8)
+ + p[3];
+ }
+ else {
++ if (end - p < 2) return 0;
+ code = p[0] * 256 + p[1];
+ }
+ return code;
+diff --git a/ext/mbstring/oniguruma/enc/utf16_le.c b/ext/mbstring/oniguruma/enc/utf16_le.c
+index 94fa8c3a7..a333491e1 100755
+--- a/ext/mbstring/oniguruma/enc/utf16_le.c
++++ b/ext/mbstring/oniguruma/enc/utf16_le.c
+@@ -82,11 +82,13 @@ utf16le_is_mbc_newline(const UChar* p, const UChar* end)
+ static OnigCodePoint
+ utf16le_mbc_to_code(const UChar* p, const UChar* end)
+ {
++ if (end - p < 2) return 0;
+ OnigCodePoint code;
+ UChar c0 = *p;
+ UChar c1 = *(p+1);
+
+ if (UTF16_IS_SURROGATE_FIRST(c1)) {
++ if (end - p < 4) return 0;
+ code = ((((c1 - 0xd8) << 2) + ((c0 & 0xc0) >> 6) + 1) << 16)
+ + ((((c0 & 0x3f) << 2) + (p[3] - 0xdc)) << 8)
+ + p[2];
+diff --git a/ext/mbstring/oniguruma/enc/utf32_be.c b/ext/mbstring/oniguruma/enc/utf32_be.c
+index 1ed127087..3783a5409 100755
+--- a/ext/mbstring/oniguruma/enc/utf32_be.c
++++ b/ext/mbstring/oniguruma/enc/utf32_be.c
+@@ -56,6 +56,7 @@ utf32be_is_mbc_newline(const UChar* p, const UChar* end)
+ static OnigCodePoint
+ utf32be_mbc_to_code(const UChar* p, const UChar* end)
+ {
++ if (end - p < 4) return 0;
+ return (OnigCodePoint )(((p[0] * 256 + p[1]) * 256 + p[2]) * 256 + p[3]);
+ }
+
+diff --git a/ext/mbstring/oniguruma/enc/utf32_le.c b/ext/mbstring/oniguruma/enc/utf32_le.c
+index 13fcd65d9..2c9f65909 100755
+--- a/ext/mbstring/oniguruma/enc/utf32_le.c
++++ b/ext/mbstring/oniguruma/enc/utf32_le.c
+@@ -56,6 +56,7 @@ utf32le_is_mbc_newline(const UChar* p, const UChar* end)
+ static OnigCodePoint
+ utf32le_mbc_to_code(const UChar* p, const UChar* end)
+ {
++ if (end - p < 4) return 0;
+ return (OnigCodePoint )(((p[3] * 256 + p[2]) * 256 + p[1]) * 256 + p[0]);
+ }
+
+diff --git a/ext/mbstring/oniguruma/regcomp.c b/ext/mbstring/oniguruma/regcomp.c
+index 726f4b531..f732bac85 100644
+--- a/ext/mbstring/oniguruma/regcomp.c
++++ b/ext/mbstring/oniguruma/regcomp.c
+@@ -451,13 +451,13 @@ compile_length_string_node(Node* node, regex_t* reg)
+ ambig = NSTRING_IS_AMBIG(node);
+
+ p = prev = sn->s;
+- prev_len = enc_len(enc, p);
++ SAFE_ENC_LEN(enc, p, sn->end, prev_len);
+ p += prev_len;
+ slen = 1;
+ rlen = 0;
+
+ for (; p < sn->end; ) {
+- len = enc_len(enc, p);
++ SAFE_ENC_LEN(enc, p, sn->end, len);
+ if (len == prev_len) {
+ slen++;
+ }
+@@ -500,12 +500,12 @@ compile_string_node(Node* node, regex_t* reg)
+ ambig = NSTRING_IS_AMBIG(node);
+
+ p = prev = sn->s;
+- prev_len = enc_len(enc, p);
++ SAFE_ENC_LEN(enc, p, end, prev_len);
+ p += prev_len;
+ slen = 1;
+
+ for (; p < end; ) {
+- len = enc_len(enc, p);
++ SAFE_ENC_LEN(enc, p, end, len);
+ if (len == prev_len) {
+ slen++;
+ }
+diff --git a/ext/mbstring/oniguruma/regexec.c b/ext/mbstring/oniguruma/regexec.c
+index e34c8ea36..c7e91a7a4 100644
+--- a/ext/mbstring/oniguruma/regexec.c
++++ b/ext/mbstring/oniguruma/regexec.c
+@@ -1570,14 +1570,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
+ break;
+
+ case OP_EXACT1: STAT_OP_IN(OP_EXACT1);
+-#if 0
+ DATA_ENSURE(1);
+ if (*p != *s) goto fail;
+ p++; s++;
+-#endif
+- if (*p != *s++) goto fail;
+- DATA_ENSURE(0);
+- p++;
+ STAT_OP_OUT;
+ break;
+
+@@ -2954,6 +2949,7 @@ str_lower_case_match(OnigEncoding enc, int ambig_flag,
+ lowlen = ONIGENC_MBC_TO_NORMALIZE(enc, ambig_flag, &p, end, lowbuf);
+ q = lowbuf;
+ while (lowlen > 0) {
++ if (t >= tend) return 0;
+ if (*t++ != *q++) {
+ if ((ambig_flag & ONIGENC_AMBIGUOUS_MATCH_COMPOUND) != 0) {
+ ambig_flag &= ~ONIGENC_AMBIGUOUS_MATCH_COMPOUND;
+@@ -3302,6 +3298,8 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
+ }
+ else {
+ UChar *q = p + reg->dmin;
++
++ if (q >= end) return 0; /* fail */
+ while (p < q) p += enc_len(reg->enc, p);
+ }
+ }
+@@ -3380,7 +3378,13 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
+ else {
+ if (reg->dmax != ONIG_INFINITE_DISTANCE) {
+ *low = p - reg->dmax;
+- if (*low > s) {
++ if (p - str < reg->dmax) {
++ *low = (UChar* )str;
++ if (low_prev)
++ *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low);
++ }
++ else {
++ if (*low > s) {
+ *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
+ *low, (const UChar** )low_prev);
+ if (low_prev && IS_NULL(*low_prev))
+@@ -3393,6 +3397,7 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
+ (pprev ? pprev : str), *low);
+ }
+ }
++ }
+ }
+ /* no needs to adjust *high, *high is used as range check only */
+ *high = p - reg->dmin;
+diff --git a/ext/mbstring/oniguruma/regext.c b/ext/mbstring/oniguruma/regext.c
+index e9ddbdabd..aa0854a9e 100755
+--- 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 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
+
+ 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 @@ onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
+ 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/mbstring/oniguruma/regparse.c b/ext/mbstring/oniguruma/regparse.c
+index 1f87b2d09..680437942 100644
+--- a/ext/mbstring/oniguruma/regparse.c
++++ b/ext/mbstring/oniguruma/regparse.c
+@@ -2898,7 +2898,7 @@ fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
+ PUNFETCH;
+ prev = p;
+ num = scan_unsigned_octal_number(&p, end, 3, enc);
+- if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
++ if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER;
+ if (p == prev) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+@@ -3262,7 +3262,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
+ if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
+ prev = p;
+ num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
+- if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
++ if (num < 0 || num >= 256) return ONIGERR_TOO_BIG_NUMBER;
+ if (p == prev) { /* can't read nothing. */
+ num = 0; /* but, it's not error */
+ }
+@@ -3383,7 +3383,9 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
+ tok->u.code = (OnigCodePoint )num;
+ }
+ else { /* string */
+- p = tok->backp + enc_len(enc, tok->backp);
++ int len;
++ SAFE_ENC_LEN(enc, tok->backp, end, len);
++ p = tok->backp + len;
+ }
+ break;
+ }
+@@ -3957,7 +3959,9 @@ next_state_class(CClassNode* cc, OnigCodePoint* vs, enum CCVALTYPE* type,
+ }
+ }
+
+- *state = CCS_VALUE;
++ if (*state != CCS_START)
++ *state = CCS_VALUE;
++
+ *type = CCV_CLASS;
+ return 0;
+ }
+@@ -3973,7 +3977,11 @@ next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v,
+ switch (*state) {
+ case CCS_VALUE:
+ if (*type == CCV_SB)
++ {
++ if (*vs > 0xff)
++ return ONIGERR_INVALID_WIDE_CHAR_VALUE;
+ BITSET_SET_BIT(cc->bs, (int )(*vs));
++ }
+ else if (*type == CCV_CODE_POINT) {
+ r = add_code_range(&(cc->mbuf), env, *vs, *vs);
+ if (r < 0) return r;
+diff --git a/ext/mbstring/oniguruma/regparse.h b/ext/mbstring/oniguruma/regparse.h
+index 62e9326e9..11d138220 100644
+--- a/ext/mbstring/oniguruma/regparse.h
++++ b/ext/mbstring/oniguruma/regparse.h
+@@ -325,4 +325,16 @@ extern int onig_print_names(FILE*, regex_t*);
+ #endif
+ #endif
+
++#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
++# define UNEXPECTED(condition) __builtin_expect(condition, 0)
++#else
++# define UNEXPECTED(condition) (condition)
++#endif
++
++#define SAFE_ENC_LEN(enc, p, end, res) do { \
++ int __res = enc_len(enc, p); \
++ if (UNEXPECTED(p + __res > end)) __res = end - p; \
++ res = __res; \
++} while(0);
++
+ #endif /* REGPARSE_H */
+diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c
+index 611a318f9..996cd7937 100644
+--- a/ext/mbstring/php_mbregex.c
++++ b/ext/mbstring/php_mbregex.c
+@@ -823,7 +823,8 @@ PHP_FUNCTION(mb_split)
+ OnigUChar *pos;
+ int string_len;
+
+- int n, err;
++ int err;
++ size_t n;
+ long count = -1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &arg_pattern, &arg_pattern_len, &string, &string_len, &count) == FAILURE) {
+@@ -882,8 +883,8 @@ PHP_FUNCTION(mb_split)
+ }
+
+ /* otherwise we just have one last element to add to the array */
+- n = ((OnigUChar *)(string + string_len) - pos);
+- if (n > 0) {
++ if ((OnigUChar *)(string + string_len) > pos) {
++ n = ((OnigUChar *)(string + string_len) - pos);
+ add_next_index_stringl(return_value, pos, n, 1);
+ } else {
+ add_next_index_stringl(return_value, "", 0, 1);
+diff --git a/ext/mssql/php_mssql.c b/ext/mssql/php_mssql.c
+index 1763cfc31..d4b07ab7f 100644
+--- a/ext/mssql/php_mssql.c
++++ b/ext/mssql/php_mssql.c
+@@ -592,6 +592,13 @@ static void php_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+
+ /* hash it up */
+ mssql_ptr = (mssql_link *) malloc(sizeof(mssql_link));
++ if (!mssql_ptr) {
++ efree(hashed_details);
++ dbfreelogin(mssql.login);
++ dbclose(mssql.link);
++ RETURN_FALSE;
++ }
++
+ memcpy(mssql_ptr, &mssql, sizeof(mssql_link));
+ Z_TYPE(new_le) = le_plink;
+ new_le.ptr = mssql_ptr;
+diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
+index 91749a1de..15682dc26 100644
+--- a/ext/odbc/php_odbc.c
++++ b/ext/odbc/php_odbc.c
+@@ -725,6 +725,14 @@ int odbc_bindcols(odbc_result *result TSRMLS_DC)
+ NULL, 0, NULL, &displaysize);
+ displaysize = displaysize <= result->longreadlen ? displaysize :
+ result->longreadlen;
++#if defined(ODBCVER) && (ODBCVER >= 0x0300)
++ /* Workaround for drivers that report NVARCHAR(MAX) columns as SQL_WVARCHAR with size 0 (bug #69975) */
++ if (result->values[i].coltype == SQL_WVARCHAR && displaysize == 0) {
++ result->values[i].coltype = SQL_WLONGVARCHAR;
++ result->values[i].value = NULL;
++ break;
++ }
++#endif
+ /* Workaround for Oracle ODBC Driver bug (#50162) when fetching TIMESTAMP column */
+ if (result->values[i].coltype == SQL_TIMESTAMP) {
+ displaysize += 3;
+@@ -1054,7 +1062,7 @@ PHP_FUNCTION(odbc_execute)
+ if (Z_STRLEN_PP(tmp) > 2 &&
+ Z_STRVAL_PP(tmp)[0] == '\'' &&
+ Z_STRVAL_PP(tmp)[Z_STRLEN_PP(tmp) - 1] == '\'') {
+- if (strlen(tmp) != Z_STRLEN_PP(tmp)) {
++ if (strlen(Z_STRVAL_PP(tmp)) != Z_STRLEN_PP(tmp)) {
+ RETURN_FALSE;
+ }
+ filename = estrndup(&Z_STRVAL_PP(tmp)[1], Z_STRLEN_PP(tmp) - 2);
+diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
+index ec0d52a18..bdc8b3f19 100644
+--- a/ext/openssl/openssl.c
++++ b/ext/openssl/openssl.c
+@@ -1218,6 +1218,7 @@ PHP_FUNCTION(openssl_x509_parse)
+ bio_out = BIO_new(BIO_s_mem());
+ if (nid == NID_subject_alt_name) {
+ if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
++ BIO_get_mem_ptr(bio_out, &bio_buf);
+ add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
+ } else {
+ zval_dtor(return_value);
+@@ -3846,15 +3847,15 @@ PHP_FUNCTION(openssl_seal)
+ /* allocate one byte extra to make room for \0 */
+ buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(ctx));
+
+- if (!EVP_SealInit(ctx, EVP_rc4(), eks, eksl, NULL, pkeys, nkeys) || !EVP_SealUpdate(ctx, buf, &len1, (unsigned char *)data, data_len)) {
++ if (EVP_SealInit(ctx, EVP_rc4(), eks, eksl, NULL, pkeys, nkeys) <= 0 ||
++ !EVP_SealUpdate(ctx, buf, &len1, (unsigned char *)data, data_len) ||
++ !EVP_SealFinal(ctx, buf + len1, &len2)) {
+ RETVAL_FALSE;
+ efree(buf);
+ EVP_CIPHER_CTX_free(ctx);
+ goto clean_exit;
+ }
+
+- EVP_SealFinal(ctx, buf + len1, &len2);
+-
+ if (len1 + len2 > 0) {
+ zval_dtor(sealdata);
+ buf[len1 + len2] = '\0';
+diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
+index 2aa0e9afc..981188f1c 100755
+--- a/ext/pcntl/pcntl.c
++++ b/ext/pcntl/pcntl.c
+@@ -442,7 +442,7 @@ PHP_FUNCTION(pcntl_exec)
+ int path_len;
+ long key_num;
+
+- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|aa", &path, &path_len, &args, &envs) == FAILURE) {
++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|aa", &path, &path_len, &args, &envs) == FAILURE) {
+ return;
+ }
+
+diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
+index ac6491445..5d8784d1a 100644
+--- a/ext/pcre/php_pcre.c
++++ b/ext/pcre/php_pcre.c
+@@ -970,8 +970,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
+ char **subpat_names; /* Array for named subpatterns */
+ int num_subpats; /* Number of captured subpatterns */
+ int size_offsets; /* Size of the offsets array */
+- int new_len; /* Length of needed storage */
+- int alloc_len; /* Actual allocated length */
++ size_t new_len; /* Length of needed storage */
++ size_t alloc_len; /* Actual allocated length */
+ int eval_result_len=0; /* Length of the eval'ed or
+ function-returned string */
+ int match_len; /* Length of the current match */
+@@ -1031,21 +1031,21 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
+ }
+
+ offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0);
+-
+- alloc_len = 2 * subject_len + 1;
+- result = safe_emalloc(alloc_len, sizeof(char), 0);
++
++ result = safe_emalloc(subject_len, 2*sizeof(char), 1);
++ alloc_len = 2 * (size_t)subject_len + 1;
+
+ /* Initialize */
+ match = NULL;
+ *result_len = 0;
+ start_offset = 0;
+ PCRE_G(error_code) = PHP_PCRE_NO_ERROR;
+-
++
+ while (1) {
+ /* Execute the regular expression. */
+ count = pcre_exec(pce->re, extra, subject, subject_len, start_offset,
+ exoptions|g_notempty, offsets, size_offsets);
+-
++
+ /* the string was already proved to be valid UTF-8 */
+ exoptions |= PCRE_NO_UTF8_CHECK;
+
+@@ -1098,8 +1098,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
+ }
+
+ if (new_len + 1 > alloc_len) {
+- alloc_len = 1 + alloc_len + 2 * new_len;
+- new_buf = emalloc(alloc_len);
++ new_buf = safe_emalloc(2, new_len + 1, alloc_len);
++ alloc_len = 1 + alloc_len + 2 * (size_t)new_len;
+ memcpy(new_buf, result, *result_len);
+ efree(result);
+ result = new_buf;
+@@ -1160,8 +1160,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
+ } else {
+ new_len = *result_len + subject_len - start_offset;
+ if (new_len + 1 > alloc_len) {
+- alloc_len = new_len + 1; /* now we know exactly how long it is */
+- new_buf = safe_emalloc(alloc_len, sizeof(char), 0);
++ new_buf = safe_emalloc(new_len, sizeof(char), 1);
++ alloc_len = (size_t)new_len + 1; /* now we know exactly how long it is */
+ memcpy(new_buf, result, *result_len);
+ efree(result);
+ result = new_buf;
+@@ -1192,6 +1192,12 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
+ efree(offsets);
+ efree(subpat_names);
+
++ if(result && (size_t)(*result_len) > INT_MAX) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, max is %d", INT_MAX);
++ efree(result);
++ result = NULL;
++ }
++
+ return result;
+ }
+ /* }}} */
+diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
+index febe9c01b..de8f94e36 100644
+--- a/ext/pdo_dblib/dblib_driver.c
++++ b/ext/pdo_dblib/dblib_driver.c
+@@ -23,6 +23,7 @@
+ # include "config.h"
+ #endif
+
++#include <limits.h>
+ #include "php.h"
+ #include "php_ini.h"
+ #include "ext/standard/info.h"
+@@ -142,7 +143,14 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
+ {
+ pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
+ char *q;
+- int l = 1;
++ size_t l = 1, extralen = 0;
++ int max_len = INT_MAX - 1;
++
++ if (unquotedlen == INT_MAX) {
++ *quoted = NULL;
++ *quotedlen = 0;
++ return 0;
++ }
+
+ *quoted = q = safe_emalloc(2, unquotedlen, 3);
+ *q++ = '\'';
+@@ -151,7 +159,8 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
+ if (*unquoted == '\'') {
+ *q++ = '\'';
+ *q++ = '\'';
+- l += 2;
++ ++l;
++ ++extralen;
+ } else {
+ *q++ = *unquoted;
+ ++l;
+@@ -159,6 +168,15 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
+ unquoted++;
+ }
+
++ if (l > (size_t)max_len - extralen) {
++ efree(*quoted);
++ *quoted = NULL;
++ *quotedlen = 0;
++ return 0;
++ }
++
++ l += extralen;
++
+ *q++ = '\'';
+ *q++ = '\0';
+ *quotedlen = l+1;
+diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c
+index 25a78b233..6787a223b 100644
+--- a/ext/pdo_firebird/firebird_driver.c
++++ b/ext/pdo_firebird/firebird_driver.c
+@@ -24,6 +24,7 @@
+
+ #define _GNU_SOURCE
+
++#include <limits.h>
+ #include "php.h"
+ #ifdef ZEND_ENGINE_2
+ # include "zend_exceptions.h"
+@@ -231,21 +232,32 @@ static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len T
+ /* 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) {
+ 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);
+ }
+@@ -258,6 +270,12 @@ static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len T
+ RECORD_ERROR(dbh);
+ }
+
++free_statement:
++
++ if (isc_dsql_free_statement(H->isc_status, &stmt, DSQL_drop)) {
++ RECORD_ERROR(dbh);
++ }
++
+ return ret;
+ }
+ /* }}} */
+@@ -266,11 +284,15 @@ static long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len T
+ static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, /* {{{ */
+ char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
+ {
+- int qcount = 0;
++ size_t qcount = 0;
+ char const *c;
+
+ /* Firebird only requires single quotes to be doubled if string lengths are used */
+
++ if (unquotedlen == INT_MAX) {
++ return 0;
++ }
++
+ /* count the number of ' characters */
+ for (c = unquoted; (c = strchr(c,'\'')); qcount++, c++);
+
+@@ -279,6 +301,11 @@ static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unqu
+ } else {
+ char const *l, *r;
+ char *c;
++ int max_len = INT_MAX - 1;
++
++ if (unquotedlen > (size_t)max_len - qcount) {
++ return 0;
++ }
+
+ *quotedlen = unquotedlen + qcount;
+ *quoted = c = emalloc(*quotedlen+1);
+@@ -489,15 +516,16 @@ static int firebird_handle_set_attribute(pdo_dbh_t *dbh, long attr, zval *val TS
+ return 0;
+ }
+ /* }}} */
++#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);
+ }
+ }
+ /* }}} */
+@@ -508,7 +536,7 @@ static int firebird_handle_get_attribute(pdo_dbh_t const *dbh, long attr, zval *
+ 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);
+diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
+index c7ba6365c..81da71f13 100644
+--- a/ext/pdo_firebird/firebird_statement.c
++++ b/ext/pdo_firebird/firebird_statement.c
+@@ -264,6 +264,12 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ *
+ unsigned short seg_len;
+ ISC_STATUS stat;
+
++ /* prevent overflow */
++ if (*len == ULONG_MAX) {
++ result = 0;
++ goto fetch_blob_end;
++ }
++
+ *ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1);
+
+ for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) {
+diff --git a/ext/pdo_odbc/pdo_odbc.c b/ext/pdo_odbc/pdo_odbc.c
+index 65fbe2e19..99de8dfe0 100755
+--- a/ext/pdo_odbc/pdo_odbc.c
++++ b/ext/pdo_odbc/pdo_odbc.c
+@@ -98,6 +98,9 @@ PHP_MINIT_FUNCTION(pdo_odbc)
+ char *instance = INI_STR("pdo_odbc.db2_instance_name");
+ if (instance) {
+ char *env = malloc(sizeof("DB2INSTANCE=") + strlen(instance));
++ if (!env) {
++ return FAILURE;
++ }
+ strcpy(env, "DB2INSTANCE=");
+ strcat(env, instance);
+ putenv(env);
+diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
+index a24501e77..00c9de8bf 100644
+--- a/ext/pdo_pgsql/pgsql_driver.c
++++ b/ext/pdo_pgsql/pgsql_driver.c
+@@ -310,6 +310,7 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
+ unsigned char *escaped;
+ pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
+ size_t tmp_len;
++ int err = 0;
+
+ switch (paramtype) {
+ case PDO_PARAM_LOB:
+@@ -319,6 +320,9 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
+ #else
+ escaped = PQescapeBytea(unquoted, unquotedlen, &tmp_len);
+ #endif
++ if (escaped == NULL) {
++ return 0;
++ }
+ *quotedlen = (int)tmp_len + 1;
+ *quoted = emalloc(*quotedlen + 1);
+ memcpy((*quoted)+1, escaped, *quotedlen-2);
+@@ -333,8 +337,13 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
+ #ifndef HAVE_PQESCAPE_CONN
+ *quotedlen = PQescapeString(*quoted + 1, unquoted, unquotedlen);
+ #else
+- *quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, unquotedlen, NULL);
++ *quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, unquotedlen, &err);
+ #endif
++ if (err) {
++ efree(*quoted);
++ *quoted = NULL;
++ return 0;
++ }
+ (*quoted)[*quotedlen + 1] = '\'';
+ (*quoted)[*quotedlen + 2] = '\0';
+ *quotedlen += 2;
+diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c
+index 9ab24f098..e3877dae6 100644
+--- a/ext/pdo_sqlite/sqlite_driver.c
++++ b/ext/pdo_sqlite/sqlite_driver.c
+@@ -211,6 +211,9 @@ static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigne
+ /* NB: doesn't handle binary strings... use prepared stmts for that */
+ static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
+ {
++ if (unquotedlen > (INT_MAX - 3) / 2) {
++ return 0;
++ }
+ *quoted = safe_emalloc(2, unquotedlen, 3);
+ sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
+ *quotedlen = strlen(*quoted);
+diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
+index 07631f080..9711e51c6 100644
+--- a/ext/pgsql/pgsql.c
++++ b/ext/pgsql/pgsql.c
+@@ -1278,7 +1278,7 @@ PHP_FUNCTION(pg_query_params)
+ for(i = 0; i < num_params; i++) {
+ if (zend_hash_get_current_data(Z_ARRVAL_PP(pv_param_arr), (void **) &tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+
+@@ -1291,7 +1291,7 @@ PHP_FUNCTION(pg_query_params)
+ if (Z_TYPE(tmp_val) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
+ zval_dtor(&tmp_val);
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+ params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
+@@ -1502,7 +1502,7 @@ PHP_FUNCTION(pg_execute)
+ for(i = 0; i < num_params; i++) {
+ if (zend_hash_get_current_data(Z_ARRVAL_PP(pv_param_arr), (void **) &tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+
+@@ -1515,7 +1515,7 @@ PHP_FUNCTION(pg_execute)
+ if (Z_TYPE(tmp_val) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
+ zval_dtor(&tmp_val);
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+ params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
+@@ -2468,11 +2468,15 @@ PHP_FUNCTION(pg_trace)
+ }
+ if (pgsql_link == NULL && id == -1) {
+ RETURN_FALSE;
+- }
++ }
+
+ ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
+ convert_to_string_ex(z_filename);
+
++ if (strlen(Z_STRVAL_PP(z_filename)) != Z_STRLEN_PP(z_filename)) {
++ RETURN_FALSE;
++ }
++
+ stream = php_stream_open_wrapper(Z_STRVAL_PP(z_filename), mode, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
+
+ if (!stream) {
+@@ -3609,8 +3613,15 @@ PHP_FUNCTION(pg_escape_string)
+
+ #ifdef HAVE_PQESCAPE_CONN
+ if (pgsql_link != NULL || id != -1) {
++ int err = 0;
++
+ ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink);
+- to_len = (int) PQescapeStringConn(pgsql, to, from, (size_t)from_len, NULL);
++ to_len = (int) PQescapeStringConn(pgsql, to, from, (size_t)from_len, &err);
++ if (err) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Escaping string failed");
++ efree(to);
++ RETURN_FALSE;
++ }
+ } else
+ #endif
+ to_len = (int) PQescapeString(to, from, (size_t)from_len);
+@@ -3655,6 +3666,10 @@ PHP_FUNCTION(pg_escape_bytea)
+ #endif
+ to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len);
+
++ if (to == NULL) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Escape failure");
++ RETURN_FALSE;
++ }
+ RETVAL_STRINGL(to, to_len-1, 1); /* to_len includes addtional '\0' */
+ PQfreemem(to);
+ }
+@@ -4110,7 +4125,7 @@ PHP_FUNCTION(pg_send_query_params)
+ for(i = 0; i < num_params; i++) {
+ if (zend_hash_get_current_data(Z_ARRVAL_PP(pv_param_arr), (void **) &tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+
+@@ -4123,7 +4138,7 @@ PHP_FUNCTION(pg_send_query_params)
+ if (Z_TYPE(tmp_val) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
+ zval_dtor(&tmp_val);
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+ params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
+@@ -4253,7 +4268,7 @@ PHP_FUNCTION(pg_send_execute)
+ for(i = 0; i < num_params; i++) {
+ if (zend_hash_get_current_data(Z_ARRVAL_PP(pv_param_arr), (void **) &tmp) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter");
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+
+@@ -4266,7 +4281,7 @@ PHP_FUNCTION(pg_send_execute)
+ if (Z_TYPE(tmp_val) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
+ zval_dtor(&tmp_val);
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+ params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
+@@ -4707,7 +4722,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
+ uint field_len = -1;
+ ulong num_idx = -1;
+ zval *meta, **def, **type, **not_null, **has_default, **val, *new_val;
+- int new_len, key_type, err = 0, skip_field;
++ int new_len, key_type, err = 0, escape_err = 0, skip_field;
+
+ assert(pg_link != NULL);
+ assert(Z_TYPE_P(values) == IS_ARRAY);
+@@ -4922,8 +4937,18 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
+ {
+ char *tmp;
+ tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1);
++#ifdef HAVE_PQESCAPE_CONN
++ /* PQescapeString() escapes for the encoding of whichever connection was opened last */
++ Z_STRLEN_P(new_val) = (int)PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), &escape_err);
++#else
+ Z_STRLEN_P(new_val) = (int)PQescapeString(tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val));
++#endif
+ Z_STRVAL_P(new_val) = tmp;
++ if (escape_err) {
++ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "String value escaping failed for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field);
++ err = escape_err = 1;
++ break;
++ }
+ }
+ #else
+ Z_STRVAL_P(new_val) = php_addslashes(Z_STRVAL_PP(val), Z_STRLEN_PP(val), &Z_STRLEN_P(new_val), 0 TSRMLS_CC);
+@@ -4950,7 +4975,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
+ err = 1;
+ }
+ PGSQL_CONV_CHECK_IGNORE();
+- if (err) {
++ if (err && !escape_err) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field);
+ }
+ break;
+@@ -5217,6 +5242,11 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
+ #else
+ tmp = PQescapeBytea(Z_STRVAL_PP(val), Z_STRLEN_PP(val), &to_len);
+ #endif
++ if (tmp == NULL) {
++ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Escaping value failed for %s field (%s)", Z_STRVAL_PP(type), field);
++ err = escape_err = 1;
++ break;
++ }
+ Z_TYPE_P(new_val) = IS_STRING;
+ Z_STRLEN_P(new_val) = to_len-1; /* PQescapeBytea's to_len includes additional '\0' */
+ Z_STRVAL_P(new_val) = emalloc(to_len);
+@@ -5245,7 +5275,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
+ err = 1;
+ }
+ PGSQL_CONV_CHECK_IGNORE();
+- if (err) {
++ if (err && !escape_err) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field);
+ }
+ break;
+diff --git a/ext/readline/readline.c b/ext/readline/readline.c
+index f673737d4..5a26d2586 100644
+--- a/ext/readline/readline.c
++++ b/ext/readline/readline.c
+@@ -432,6 +432,9 @@ static char **_readline_completion_cb(const char *text, int start, int end)
+ matches = rl_completion_matches(text,_readline_command_generator);
+ } else {
+ matches = malloc(sizeof(char *) * 2);
++ if (!matches) {
++ return NULL;
++ }
+ matches[0] = strdup("");
+ matches[1] = '\0';
+ }
+@@ -472,7 +475,6 @@ PHP_FUNCTION(readline_completion_function)
+ zval_copy_ctor(_readline_completion);
+
+ rl_attempted_completion_function = _readline_completion_cb;
+-
+ RETURN_TRUE;
+ }
+
+diff --git a/ext/session/session.c b/ext/session/session.c
+index 9a8b22a99..db0a37590 100644
+--- a/ext/session/session.c
++++ b/ext/session/session.c
+@@ -275,16 +275,18 @@ static char *php_session_encode(int *newlen TSRMLS_DC) /* {{{ */
+ }
+ /* }}} */
+
+-static void php_session_decode(const char *val, int vallen TSRMLS_DC) /* {{{ */
++static int php_session_decode(const char *val, int vallen TSRMLS_DC) /* {{{ */
+ {
+ if (!PS(serializer)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown session.serialize_handler. Failed to decode session object");
+- return;
++ return FAILURE;
+ }
+ if (PS(serializer)->decode(val, vallen TSRMLS_CC) == FAILURE) {
+ php_session_destroy(TSRMLS_C);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to decode session object. Session has been destroyed");
++ return FAILURE;
+ }
++ return SUCCESS;
+ }
+ /* }}} */
+
+@@ -759,14 +761,17 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
+ int namelen;
+ int has_value;
+ php_unserialize_data_t var_hash;
++ int skip = 0;
+
+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
+
+ for (p = val; p < endptr; ) {
+ zval **tmp;
++ skip = 0;
+ namelen = ((unsigned char)(*p)) & (~PS_BIN_UNDEF);
+
+ if (namelen < 0 || namelen > PS_BIN_MAX || (p + namelen) >= endptr) {
++ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+ return FAILURE;
+ }
+
+@@ -778,19 +783,27 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
+
+ if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
+ if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) {
+- efree(name);
+- continue;
++ skip = 1;
+ }
+ }
+
+ if (has_value) {
+ ALLOC_INIT_ZVAL(current);
+ if (php_var_unserialize(¤t, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
+- php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);
++ if (!skip) {
++ php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);
++ }
++ } else {
++ var_push_dtor_no_addref(&var_hash, ¤t);
++ efree(name);
++ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
++ return FAILURE;
+ }
+- zval_ptr_dtor(¤t);
++ var_push_dtor_no_addref(&var_hash, ¤t);
++ }
++ if (!skip) {
++ PS_ADD_VARL(name, namelen);
+ }
+- PS_ADD_VARL(name, namelen);
+ efree(name);
+ }
+
+@@ -847,6 +860,7 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
+ int namelen;
+ int has_value;
+ php_unserialize_data_t var_hash;
++ int skip = 0;
+
+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
+
+@@ -854,6 +868,7 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
+
+ while (p < endptr) {
+ zval **tmp;
++ skip = 0;
+ q = p;
+ while (*q != PS_DELIMITER) {
+ if (++q >= endptr) goto break_outer_loop;
+@@ -871,18 +886,27 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
+
+ if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) {
+ if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) {
+- goto skip;
++ skip = 1;
+ }
+ }
+
+ if (has_value) {
+ ALLOC_INIT_ZVAL(current);
+ if (php_var_unserialize(¤t, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
+- php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);
++ if (!skip) {
++ php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);
++ }
++ } else {
++ var_push_dtor_no_addref(&var_hash, ¤t);
++ efree(name);
++ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
++ return FAILURE;
+ }
+- zval_ptr_dtor(¤t);
++ var_push_dtor_no_addref(&var_hash, ¤t);
++ }
++ if (!skip) {
++ PS_ADD_VARL(name, namelen);
+ }
+- PS_ADD_VARL(name, namelen);
+ skip:
+ efree(name);
+
+@@ -1785,9 +1809,7 @@ static PHP_FUNCTION(session_decode)
+
+ convert_to_string_ex(str);
+
+- php_session_decode(Z_STRVAL_PP(str), Z_STRLEN_PP(str) TSRMLS_CC);
+-
+- RETURN_TRUE;
++ RETVAL_BOOL(php_session_decode(Z_STRVAL_PP(str), Z_STRLEN_PP(str) TSRMLS_CC) == SUCCESS);
+ }
+ /* }}} */
+
+diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
+index 72e7604e3..b96109daf 100644
+--- a/ext/simplexml/simplexml.c
++++ b/ext/simplexml/simplexml.c
+@@ -1331,9 +1331,15 @@ SXE_METHOD(asXML)
+ if (node) {
+ if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) {
+ xmlDocDumpMemoryEnc((xmlDocPtr) sxe->document->ptr, &strval, &strval_len, ((xmlDocPtr) sxe->document->ptr)->encoding);
+- RETVAL_STRINGL((char *)strval, strval_len, 1);
++ if (!strval) {
++ RETVAL_FALSE;
++ } else {
++ RETVAL_STRINGL((char *)strval, strval_len, 1);
++ }
+ xmlFree(strval);
+ } else {
++ char *return_content;
++ size_t return_len;
+ /* Should we be passing encoding information instead of NULL? */
+ outbuf = xmlAllocOutputBuffer(NULL);
+
+@@ -1344,11 +1350,20 @@ SXE_METHOD(asXML)
+ xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, ((xmlDocPtr) sxe->document->ptr)->encoding);
+ xmlOutputBufferFlush(outbuf);
+ #ifdef LIBXML2_NEW_BUFFER
+- RETVAL_STRINGL((char *)xmlOutputBufferGetContent(outbuf),
+- xmlOutputBufferGetSize(outbuf), 1);
++ return_content = (char *)xmlOutputBufferGetContent(outbuf);
++ return_len = xmlOutputBufferGetSize(outbuf);
+ #else
+- RETVAL_STRINGL((char *)outbuf->buffer->content, outbuf->buffer->use, 1);
++ return_content = (char *)outbuf->buffer->content;
++ return_len = outbuf->buffer->use;
+ #endif
++ if (!return_content) {
++ RETVAL_FALSE;
++ } else if (return_len > INT_MAX) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "String too long, max is %d", INT_MAX);
++ RETVAL_FALSE;
++ } else {
++ RETVAL_STRINGL(return_content, (int)return_len, 1);
++ }
+ xmlOutputBufferClose(outbuf);
+ }
+ } else {
+@@ -2038,7 +2053,9 @@ PHP_FUNCTION(simplexml_load_file)
+ return;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(read_file);
+ docp = xmlReadFile(filename, NULL, options);
++ PHP_LIBXML_RESTORE_GLOBALS(read_file);
+
+ if (! docp) {
+ RETURN_FALSE;
+@@ -2076,7 +2093,9 @@ PHP_FUNCTION(simplexml_load_string)
+ return;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(read_memory);
+ docp = xmlReadMemory(data, data_len, NULL, NULL, options);
++ PHP_LIBXML_RESTORE_GLOBALS(read_memory);
+
+ if (! docp) {
+ RETURN_FALSE;
+@@ -2116,7 +2135,9 @@ SXE_METHOD(__construct)
+
+ php_std_error_handling();
+
++ PHP_LIBXML_SANITIZE_GLOBALS(read_file_or_memory);
+ docp = is_url ? xmlReadFile(data, NULL, options) : xmlReadMemory(data, data_len, NULL, NULL, options);
++ PHP_LIBXML_RESTORE_GLOBALS(read_file_or_memory);
+
+ if (!docp) {
+ ((php_libxml_node_object *)sxe)->document = NULL;
+diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
+index c5ae01721..8b2e44239 100644
+--- a/ext/soap/php_encoding.c
++++ b/ext/soap/php_encoding.c
+@@ -290,10 +290,16 @@ static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type)
+ return NULL;
+ }
+
++/* User code (typemap callbacks, magic methods) runs inside a pass, so a map is
++ * only ever used by the kind of pass that first filled it. */
++#define SOAP_REF_MAP_USABLE(kind) \
++ (SOAP_GLOBAL(ref_map) && \
++ (SOAP_GLOBAL(ref_map_kind) == SOAP_REF_MAP_UNUSED || SOAP_GLOBAL(ref_map_kind) == (kind)))
++
+ static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
+ xmlNodePtr *node_ptr;
+
+- if (SOAP_GLOBAL(ref_map)) {
++ if (SOAP_REF_MAP_USABLE(SOAP_REF_MAP_ENCODE)) {
+ if (Z_TYPE_P(data) == IS_OBJECT) {
+ data = (zval*)zend_objects_get_address(data TSRMLS_CC);
+ }
+@@ -351,6 +357,7 @@ static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
+ smart_str_free(&prefix);
+ return 1;
+ } else {
++ SOAP_GLOBAL(ref_map_kind) = SOAP_REF_MAP_ENCODE;
+ zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node, sizeof(xmlNodePtr), NULL);
+ }
+ }
+@@ -361,7 +368,7 @@ static zval* soap_find_xml_ref(xmlNodePtr node TSRMLS_DC)
+ {
+ zval **data_ptr;
+
+- if (SOAP_GLOBAL(ref_map) &&
++ if (SOAP_REF_MAP_USABLE(SOAP_REF_MAP_DECODE) &&
+ zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
+ (*data_ptr)->is_ref = 1;
+ (*data_ptr)->refcount++;
+@@ -374,7 +381,7 @@ static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC)
+ {
+ zval **data_ptr;
+
+- if (SOAP_GLOBAL(ref_map)) {
++ if (SOAP_REF_MAP_USABLE(SOAP_REF_MAP_DECODE)) {
+ if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
+ if (*data != *data_ptr) {
+ zval_ptr_dtor(data);
+@@ -384,6 +391,10 @@ static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC)
+ return 1;
+ }
+ } else {
++ /* the decoder may free *data (a repeated Apache Map key) while a later
++ * href still resolves to it, so the map keeps its own reference */
++ (*data)->refcount++;
++ SOAP_GLOBAL(ref_map_kind) = SOAP_REF_MAP_DECODE;
+ zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)node, (void**)data, sizeof(zval*), NULL);
+ }
+ }
+@@ -404,12 +415,15 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml
+ encodePtr enc = NULL;
+ HashTable *ht = Z_OBJPROP_P(data);
+
+- if (zend_hash_find(ht, "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
++ if (zend_hash_find(ht, "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE ||
++ Z_TYPE_PP(ztype) != IS_LONG) {
+ soap_error0(E_ERROR, "Encoding: SoapVar hasn't 'enc_type' property");
+ }
+
+- if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
+- if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
++ if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS &&
++ Z_TYPE_PP(zstype) == IS_STRING) {
++ if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS &&
++ Z_TYPE_PP(zns) == IS_STRING) {
+ enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
+ } else {
+ zns = NULL;
+@@ -445,8 +459,10 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml
+ }
+
+ if (style == SOAP_ENCODED || (SOAP_GLOBAL(sdl) && encode != enc)) {
+- if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
+- if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
++ if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS &&
++ Z_TYPE_PP(zstype) == IS_STRING) {
++ if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS &&
++ Z_TYPE_PP(zns) == IS_STRING) {
+ set_ns_and_type_ex(node, Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
+ } else {
+ set_ns_and_type_ex(node, NULL, Z_STRVAL_PP(zstype));
+@@ -454,10 +470,12 @@ static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xml
+ }
+ }
+
+- if (zend_hash_find(ht, "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) {
++ if (zend_hash_find(ht, "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS &&
++ Z_TYPE_PP(zname) == IS_STRING) {
+ xmlNodeSetName(node, BAD_CAST(Z_STRVAL_PP(zname)));
+ }
+- if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) {
++ if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS &&
++ Z_TYPE_PP(znamens) == IS_STRING) {
+ xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens));
+ xmlSetNs(node, nsp);
+ }
+@@ -579,7 +597,12 @@ static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data)
+ }
+ }
+ if (encode->to_zval) {
++ if (SOAP_GLOBAL(decode_depth) >= SOAP_MAX_DECODE_DEPTH) {
++ soap_error0(E_ERROR, "Encoding: Nesting level too deep");
++ }
++ SOAP_GLOBAL(decode_depth)++;
+ ret = encode->to_zval(&encode->details, data);
++ SOAP_GLOBAL(decode_depth)--;
+ }
+ return ret;
+ }
+@@ -2760,7 +2783,7 @@ static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data)
+ }
+
+ xmlValue = get_node(item->children, "value");
+- if (!xmlKey) {
++ if (!xmlValue) {
+ soap_error0(E_ERROR, "Encoding: Can't decode apache map, missing value");
+ }
+
+@@ -3435,16 +3458,43 @@ static void set_xsi_type(xmlNodePtr node, char *type)
+ set_ns_prop(node, XSI_NAMESPACE, "type", type);
+ }
+
++static void destroy_ref_map(TSRMLS_D)
++{
++ HashTable *ref_map = SOAP_GLOBAL(ref_map);
++ int kind = SOAP_GLOBAL(ref_map_kind);
++
++ /* releasing a zval may run a __destruct() that starts another SOAP pass */
++ SOAP_GLOBAL(ref_map) = NULL;
++ SOAP_GLOBAL(ref_map_kind) = SOAP_REF_MAP_UNUSED;
++ if (kind == SOAP_REF_MAP_DECODE) {
++ HashPosition pos;
++ zval **data;
++
++ for (zend_hash_internal_pointer_reset_ex(ref_map, &pos);
++ zend_hash_get_current_data_ex(ref_map, (void **)&data, &pos) == SUCCESS;
++ zend_hash_move_forward_ex(ref_map, &pos)) {
++ /* not zval_ptr_dtor(): it clears is_ref at one holder left and would
++ * undo the reference an href made; the map is no PHP-visible holder */
++ if (--(*data)->refcount == 0) {
++ zval_dtor(*data);
++ FREE_ZVAL(*data);
++ }
++ }
++ }
++ zend_hash_destroy(ref_map);
++ efree(ref_map);
++}
++
+ void encode_reset_ns()
+ {
+ TSRMLS_FETCH();
+ SOAP_GLOBAL(cur_uniq_ns) = 0;
+ SOAP_GLOBAL(cur_uniq_ref) = 0;
+- if (SOAP_GLOBAL(ref_map)) {
+- zend_hash_destroy(SOAP_GLOBAL(ref_map));
+- } else {
+- SOAP_GLOBAL(ref_map) = emalloc(sizeof(HashTable));
++ SOAP_GLOBAL(decode_depth) = 0;
++ while (SOAP_GLOBAL(ref_map)) {
++ destroy_ref_map(TSRMLS_C);
+ }
++ SOAP_GLOBAL(ref_map) = emalloc(sizeof(HashTable));
+ zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, NULL, 0);
+ }
+
+@@ -3453,10 +3503,9 @@ void encode_finish()
+ TSRMLS_FETCH();
+ SOAP_GLOBAL(cur_uniq_ns) = 0;
+ SOAP_GLOBAL(cur_uniq_ref) = 0;
+- if (SOAP_GLOBAL(ref_map)) {
+- zend_hash_destroy(SOAP_GLOBAL(ref_map));
+- efree(SOAP_GLOBAL(ref_map));
+- SOAP_GLOBAL(ref_map) = NULL;
++ SOAP_GLOBAL(decode_depth) = 0;
++ while (SOAP_GLOBAL(ref_map)) {
++ destroy_ref_map(TSRMLS_C);
+ }
+ }
+
+@@ -3516,18 +3565,21 @@ static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *type TS
+ Z_OBJCE_PP(tmp) == soap_var_class_entry) {
+ zval **ztype;
+
+- if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
++ if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE ||
++ Z_TYPE_PP(ztype) != IS_LONG) {
+ soap_error0(E_ERROR, "Encoding: SoapVar hasn't 'enc_type' property");
+ }
+ cur_type = Z_LVAL_PP(ztype);
+
+- if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_stype", sizeof("enc_stype"), (void **)&ztype) == SUCCESS) {
++ if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_stype", sizeof("enc_stype"), (void **)&ztype) == SUCCESS ||
++ Z_TYPE_PP(ztype) == IS_STRING) {
+ cur_stype = Z_STRVAL_PP(ztype);
+ } else {
+ cur_stype = NULL;
+ }
+
+- if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_ns", sizeof("enc_ns"), (void **)&ztype) == SUCCESS) {
++ if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_ns", sizeof("enc_ns"), (void **)&ztype) == SUCCESS ||
++ Z_TYPE_PP(ztype) == IS_STRING) {
+ cur_ns = Z_STRVAL_PP(ztype);
+ } else {
+ cur_ns = NULL;
+diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
+index 4140a57a7..53b7a6473 100644
+--- a/ext/soap/php_http.c
++++ b/ext/soap/php_http.c
+@@ -23,6 +23,7 @@
+ #include "ext/standard/base64.h"
+ #include "ext/standard/md5.h"
+ #include "ext/standard/php_rand.h"
++#include "ext/hash/php_hash.h"
+
+ static char *get_http_header_value(char *headers, char *type);
+ static int get_http_body(php_stream *socketd, int close, char *headers, char **response, int *out_size TSRMLS_DC);
+@@ -60,14 +61,16 @@ void proxy_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
+ {
+ zval **login, **password;
+
+- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login"), (void **)&login) == SUCCESS) {
++ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_login", sizeof("_proxy_login"), (void **)&login) == SUCCESS &&
++ Z_TYPE_PP(login) == IS_STRING) {
+ unsigned char* buf;
+ int len;
+ smart_str auth = {0};
+
+ smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+ smart_str_appendc(&auth, ':');
+- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_password", sizeof("_proxy_password"), (void **)&password) == SUCCESS) {
++ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_password", sizeof("_proxy_password"), (void **)&password) == SUCCESS &&
++ Z_TYPE_PP(password) == IS_STRING) {
+ smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
+ }
+ smart_str_0(&auth);
+@@ -86,14 +89,16 @@ void basic_authentication(zval* this_ptr, smart_str* soap_headers TSRMLS_DC)
+ zval **login, **password;
+
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_login", sizeof("_login"), (void **)&login) == SUCCESS &&
+- !zend_hash_exists(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"))) {
++ Z_TYPE_PP(login) == IS_STRING &&
++ !zend_hash_exists(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest"))) {
+ unsigned char* buf;
+ int len;
+ smart_str auth = {0};
+
+ smart_str_appendl(&auth, Z_STRVAL_PP(login), Z_STRLEN_PP(login));
+ smart_str_appendc(&auth, ':');
+- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS) {
++ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_password", sizeof("_password"), (void **)&password) == SUCCESS &&
++ Z_TYPE_PP(password) == IS_STRING) {
+ smart_str_appendl(&auth, Z_STRVAL_PP(password), Z_STRLEN_PP(password));
+ }
+ smart_str_0(&auth);
+@@ -499,13 +504,17 @@ try_again:
+ if (Z_TYPE_PP(digest) == IS_ARRAY) {
+ char HA1[33], HA2[33], response[33], cnonce[33], nc[9];
+ PHP_MD5_CTX md5ctx;
++ unsigned char nonce[16];
+ unsigned char hash[16];
++ int i;
+
+- PHP_MD5Init(&md5ctx);
+- snprintf(cnonce, sizeof(cnonce), "%ld", php_rand(TSRMLS_C));
+- PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce));
+- PHP_MD5Final(hash, &md5ctx);
+- make_digest(cnonce, hash);
++ for(i = 0; i < 16; i++) {
++ php_uint32 rand_val = (php_mt_rand(TSRMLS_C) >> 1);
++ nonce[i] = (unsigned char)(rand_val & 0x000000FF);
++ }
++
++ php_hash_bin2hex(cnonce, nonce, sizeof(nonce));
++ cnonce[32] = 0;
+
+ if (zend_hash_find(Z_ARRVAL_PP(digest), "nc", sizeof("nc"), (void **)&tmp) == SUCCESS &&
+ Z_TYPE_PP(tmp) == IS_LONG) {
+@@ -670,7 +679,8 @@ try_again:
+ }
+
+ /* Send cookies along with request */
+- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) {
++ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS &&
++ Z_TYPE_PP(cookies) == IS_ARRAY) {
+ zval **data;
+ char *key;
+ int i, n;
+@@ -680,18 +690,21 @@ try_again:
+ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(cookies));
+ smart_str_append_const(&soap_headers, "Cookie: ");
+ for (i = 0; i < n; i++) {
++ ulong numindx;
++ int res = zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, &numindx, FALSE);
+ zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data);
+- zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE);
+
+- if (Z_TYPE_PP(data) == IS_ARRAY) {
++ if (res == HASH_KEY_IS_STRING && Z_TYPE_PP(data) == IS_ARRAY) {
+ zval** value;
+
+ if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&value) == SUCCESS &&
+ Z_TYPE_PP(value) == IS_STRING) {
+ zval **tmp;
+ if ((zend_hash_index_find(Z_ARRVAL_PP(data), 1, (void**)&tmp) == FAILURE ||
++ Z_TYPE_PP(tmp) != IS_STRING ||
+ strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_PP(tmp),Z_STRLEN_PP(tmp)) == 0) &&
+ (zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == FAILURE ||
++ Z_TYPE_PP(tmp) != IS_STRING ||
+ in_domain(phpurl->host,Z_STRVAL_PP(tmp))) &&
+ (use_ssl || zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) {
+ smart_str_appendl(&soap_headers, key, strlen(key));
+@@ -709,7 +722,7 @@ try_again:
+ smart_str_append_const(&soap_headers, "\r\n");
+ smart_str_0(&soap_headers);
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
+- Z_LVAL_PP(trace) > 0) {
++ (Z_TYPE_PP(trace) == IS_BOOL || Z_TYPE_PP(trace) == IS_LONG) && Z_LVAL_PP(trace) != 0) {
+ add_property_stringl(this_ptr, "__last_request_headers", soap_headers.c, soap_headers.len, 1);
+ }
+ smart_str_appendl(&soap_headers, request, request_size);
+@@ -754,7 +767,7 @@ try_again:
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
+- Z_LVAL_PP(trace) > 0) {
++ (Z_TYPE_PP(trace) == IS_BOOL || Z_TYPE_PP(trace) == IS_LONG) && Z_LVAL_PP(trace) != 0) {
+ add_property_stringl(this_ptr, "__last_response_headers", http_headers, http_header_size, 1);
+ }
+
+@@ -803,7 +816,8 @@ try_again:
+ char *eqpos, *sempos;
+ zval **cookies;
+
+- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE) {
++ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == FAILURE ||
++ Z_TYPE_PP(cookies) != IS_ARRAY) {
+ zval *tmp_cookies;
+ MAKE_STD_ZVAL(tmp_cookies);
+ array_init(tmp_cookies);
+@@ -1261,8 +1275,10 @@ static int get_http_body(php_stream *stream, int close, char *headers, char **r
+ if (buf_size > 0) {
+ int len_size = 0;
+
+- if (http_buf_size + buf_size + 1 < 0) {
+- efree(http_buf);
++ if (buf_size >= INT_MAX - http_buf_size) {
++ if (http_buf) {
++ efree(http_buf);
++ }
+ return FALSE;
+ }
+ http_buf = erealloc(http_buf, http_buf_size + buf_size + 1);
+@@ -1321,7 +1337,7 @@ static int get_http_body(php_stream *stream, int close, char *headers, char **r
+ }
+
+ } else if (header_length) {
+- if (header_length < 0) {
++ if (header_length < 0 || header_length >= INT_MAX) {
+ return FALSE;
+ }
+ http_buf = emalloc(header_length + 1);
+@@ -1335,6 +1351,12 @@ static int get_http_body(php_stream *stream, int close, char *headers, char **r
+ } else if (header_close) {
+ do {
+ int len_read;
++ if (http_buf_size >= INT_MAX - 4096) {
++ if (http_buf) {
++ efree(http_buf);
++ }
++ return FALSE;
++ }
+ http_buf = erealloc(http_buf, http_buf_size + 4096 + 1);
+ len_read = php_stream_read(stream, http_buf + http_buf_size, 4096);
+ if (len_read > 0) {
+diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
+index a197a9e57..5b2f799c9 100644
+--- a/ext/soap/php_sdl.c
++++ b/ext/soap/php_sdl.c
+@@ -284,6 +284,8 @@ void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC)
+ ctx->context = NULL;
+ }
+
++#define SAFE_STR(a) ((a)?((const char *)a):"")
++
+ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC)
+ {
+ sdlPtr tmpsdl = ctx->sdl;
+@@ -344,7 +346,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
+ 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;
+ }
+@@ -405,7 +407,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
+ soap_error0(E_ERROR, "Parsing WSDL: <service> hasn't 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;
+ }
+@@ -515,7 +517,7 @@ static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xml
+ }
+ 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;
+ }
+@@ -620,7 +622,7 @@ static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap
+ }
+ 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;
+ }
+@@ -652,14 +654,14 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
+ 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);
<Skipped 4748 lines>
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/php.git/commitdiff/24c44f02abb01ce95ff4864624427e17afb6d12d
More information about the pld-cvs-commit
mailing list