[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(&current, (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, &current);
++				efree(name);
++				PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
++				return FAILURE;
+ 			}
+-			zval_ptr_dtor(&current);
++			var_push_dtor_no_addref(&var_hash, &current);
++		}
++		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(&current, (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, &current);
++				efree(name);
++				PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
++				return FAILURE;
+ 			}
+-			zval_ptr_dtor(&current);
++			var_push_dtor_no_addref(&var_hash, &current);
++		}
++		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