[packages/php4] Rel 83; backport 105 security fixes from php-src and RHEL4 php-4.3.9 (exif, gd, unserialize/session,

arekm arekm at pld-linux.org
Thu Oct 22 09:39:50 CEST 2026


commit 9ddb8abcef5a39d5c04e485b3c20a7917da02cb4
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Thu Oct 22 09:39:07 2026 +0200

    Rel 83; backport 105 security fixes from php-src and RHEL4 php-4.3.9
    (exif, gd, unserialize/session, rfc1867, cgi/libfcgi, xmlrpc, openssl, imap, ...)

 php4-CVE-2007-0907.patch            |  16 ++
 php4-CVE-2007-4782.patch            |  41 ++++
 php4-CVE-2007-5898.patch            | 164 ++++++++++++++++
 php4-CVE-2008-2051.patch            |  99 ++++++++++
 php4-CVE-2008-2107.patch            |  16 ++
 php4-CVE-2008-3660.patch            |  56 ++++++
 php4-CVE-2008-5498.patch            |  25 +++
 php4-CVE-2008-5557.patch            |  43 +++++
 php4-CVE-2009-2687.patch            |  18 ++
 php4-CVE-2009-3291.patch            |  37 ++++
 php4-CVE-2009-3292.patch            |  71 +++++++
 php4-CVE-2009-3546.patch            |  17 ++
 php4-CVE-2009-4017.patch            |  61 ++++++
 php4-CVE-2009-4142.patch            | 368 ++++++++++++++++++++++++++++++++++++
 php4-CVE-2010-0397.patch            |  56 ++++++
 php4-CVE-2010-1128.patch            |  28 +++
 php4-CVE-2010-1917.patch            |  18 ++
 php4-CVE-2010-2531.patch            | 218 +++++++++++++++++++++
 php4-CVE-2010-3065.patch            |  16 ++
 php4-CVE-2010-3870.patch            | 153 +++++++++++++++
 php4-CVE-2010-4150.patch            |  20 ++
 php4-CVE-2011-0708.patch            |  56 ++++++
 php4-CVE-2011-1092.patch            |  21 ++
 php4-CVE-2011-1466.patch            | 174 +++++++++++++++++
 php4-CVE-2011-2202.patch            |  25 +++
 php4-CVE-2011-4566.patch            |  23 +++
 php4-CVE-2011-4885.patch            |  87 +++++++++
 php4-CVE-2012-1172.patch            |  18 ++
 php4-CVE-2013-4113.patch            | 160 ++++++++++++++++
 php4-CVE-2013-6420.patch            |  41 ++++
 php4-CVE-2014-3670.patch            |  21 ++
 php4-CVE-2014-4721.patch            |  28 +++
 php4-CVE-2014-5120.patch            |  55 ++++++
 php4-CVE-2014-8626.patch            |  86 +++++++++
 php4-CVE-2014-9709.patch            |  37 ++++
 php4-CVE-2015-0232.patch            |  15 ++
 php4-CVE-2015-2305.patch            |  24 +++
 php4-CVE-2015-2348.patch            |  18 ++
 php4-CVE-2015-2787.patch            |  59 ++++++
 php4-CVE-2015-4022.patch            |  45 +++++
 php4-CVE-2015-4024.patch            |  88 +++++++++
 php4-CVE-2015-4598.patch            |  16 ++
 php4-CVE-2015-6834.patch            | 157 +++++++++++++++
 php4-CVE-2015-6835.patch            |  85 +++++++++
 php4-CVE-2015-8874.patch            |  21 ++
 php4-CVE-2015-8935.patch            |  39 ++++
 php4-CVE-2016-10158.patch           |  16 ++
 php4-CVE-2016-10161.patch           | 137 ++++++++++++++
 php4-CVE-2016-10167.patch           |  26 +++
 php4-CVE-2016-10168.patch           |  26 +++
 php4-CVE-2016-10397.patch           |  30 +++
 php4-CVE-2016-3074.patch            |  17 ++
 php4-CVE-2016-4542.patch            |  54 ++++++
 php4-CVE-2016-5399.patch            |  24 +++
 php4-CVE-2016-5766.patch            |  26 +++
 php4-CVE-2016-5769.patch            |  29 +++
 php4-CVE-2016-6161.patch            |  47 +++++
 php4-CVE-2016-6291.patch            |  55 ++++++
 php4-CVE-2016-6296.patch            |  63 ++++++
 php4-CVE-2016-7125.patch            |  91 +++++++++
 php4-CVE-2016-7126.patch            |  18 ++
 php4-CVE-2016-7127.patch            |  19 ++
 php4-CVE-2016-7128.patch            |  33 ++++
 php4-CVE-2016-8670.patch            |  16 ++
 php4-CVE-2016-9933.patch            |  16 ++
 php4-CVE-2017-11144.patch           |  29 +++
 php4-CVE-2017-12933.patch           |  49 +++++
 php4-CVE-2017-7890.patch            |  17 ++
 php4-CVE-2018-10548.patch           |  20 ++
 php4-CVE-2018-14851.patch           |  44 +++++
 php4-CVE-2018-14883.patch           |  19 ++
 php4-CVE-2018-17082.patch           |  15 ++
 php4-CVE-2018-19518.patch           |  18 ++
 php4-CVE-2018-5711.patch            |  38 ++++
 php4-CVE-2018-7584.patch            |  20 ++
 php4-CVE-2019-11034.patch           |  18 ++
 php4-CVE-2019-11035.patch           | 137 ++++++++++++++
 php4-CVE-2019-11036.patch           |  16 ++
 php4-CVE-2019-11038.patch           |  20 ++
 php4-CVE-2019-11040.patch           |  17 ++
 php4-CVE-2019-11041.patch           |  16 ++
 php4-CVE-2019-11047.patch           |  17 ++
 php4-CVE-2019-6977.patch            |  18 ++
 php4-CVE-2019-9020.patch            |  17 ++
 php4-CVE-2019-9024.patch            |  25 +++
 php4-CVE-2019-9638.patch            |  16 ++
 php4-CVE-2019-9640.patch            |  38 ++++
 php4-CVE-2019-9641.patch            |  44 +++++
 php4-CVE-2020-7059.patch            |  43 +++++
 php4-CVE-2020-7064.patch            |  28 +++
 php4-CVE-2023-0568.patch            |  18 ++
 php4-CVE-2023-0662.patch            |  48 +++++
 php4-CVE-2024-8925.patch            |  21 ++
 php4-CVE-2024-8927.patch            |  36 ++++
 php4-CVE-2025-23016.patch           |  29 +++
 php4-bcmath-scale-overflow.patch    |  88 +++++++++
 php4-cgi-shebang-eof.patch          |  29 +++
 php4-curl-handler-free.patch        |  60 ++++++
 php4-exif-APP12-SOFn-infoleak.patch |  27 +++
 php4-exif-bug65873.patch            |  21 ++
 php4-exif-bug70385.patch            |  36 ++++
 php4-exif-zero-components.patch     |  87 +++++++++
 php4-gd-transparent-index.patch     |  21 ++
 php4-getimagesize-short-read.patch  |  25 +++
 php4-open-basedir-empty-path.patch  |  24 +++
 php4.spec                           | 214 ++++++++++++++++++++-
 106 files changed, 5205 insertions(+), 1 deletion(-)
---
diff --git a/php4.spec b/php4.spec
index c27936a..2f96783 100644
--- a/php4.spec
+++ b/php4.spec
@@ -73,7 +73,7 @@
 %undefine	with_msession
 %endif
 
-%define		rel 82
+%define		rel 83
 Summary:	PHP: Hypertext Preprocessor
 Summary(fr.UTF-8):	Le langage de script embarque-HTML PHP
 Summary(pl.UTF-8):	Język skryptowy PHP
@@ -158,6 +158,111 @@ Patch61:	configure.patch
 Patch62:	bison.patch
 Patch63:	includes.patch
 Patch64:	types.patch
+Patch65:	%{name}-CVE-2007-0907.patch
+Patch66:	%{name}-CVE-2007-4782.patch
+Patch67:	%{name}-CVE-2010-1917.patch
+Patch68:	%{name}-CVE-2007-5898.patch
+Patch69:	%{name}-CVE-2008-2107.patch
+Patch70:	%{name}-CVE-2008-3660.patch
+Patch71:	%{name}-CVE-2008-5498.patch
+Patch72:	%{name}-CVE-2009-2687.patch
+Patch73:	%{name}-CVE-2009-3291.patch
+Patch74:	%{name}-CVE-2009-3292.patch
+Patch75:	%{name}-CVE-2009-3546.patch
+Patch76:	%{name}-CVE-2009-4017.patch
+Patch77:	%{name}-CVE-2010-0397.patch
+Patch78:	%{name}-CVE-2010-1128.patch
+Patch79:	%{name}-CVE-2010-3870.patch
+Patch80:	%{name}-CVE-2011-0708.patch
+Patch81:	%{name}-CVE-2011-1466.patch
+Patch82:	%{name}-CVE-2013-4113.patch
+Patch83:	%{name}-CVE-2008-2051.patch
+Patch84:	%{name}-CVE-2008-5557.patch
+Patch85:	%{name}-CVE-2009-4142.patch
+Patch86:	%{name}-CVE-2010-2531.patch
+Patch87:	%{name}-CVE-2010-3065.patch
+Patch88:	%{name}-CVE-2011-2202.patch
+Patch89:	%{name}-CVE-2011-4566.patch
+Patch90:	%{name}-CVE-2011-4885.patch
+Patch91:	%{name}-gd-transparent-index.patch
+Patch92:	%{name}-curl-handler-free.patch
+Patch93:	%{name}-CVE-2014-3670.patch
+Patch94:	%{name}-CVE-2016-10158.patch
+Patch95:	%{name}-CVE-2019-11041.patch
+Patch96:	%{name}-CVE-2019-11047.patch
+Patch97:	%{name}-CVE-2020-7064.patch
+Patch98:	%{name}-exif-APP12-SOFn-infoleak.patch
+Patch99:	%{name}-CVE-2014-9709.patch
+Patch100:	%{name}-CVE-2017-7890.patch
+Patch101:	%{name}-CVE-2018-5711.patch
+Patch102:	%{name}-CVE-2016-3074.patch
+Patch103:	%{name}-CVE-2016-5766.patch
+Patch104:	%{name}-CVE-2016-10168.patch
+Patch105:	%{name}-CVE-2016-10167.patch
+Patch106:	%{name}-CVE-2016-8670.patch
+Patch107:	%{name}-CVE-2016-6161.patch
+Patch108:	%{name}-CVE-2019-11038.patch
+Patch109:	%{name}-CVE-2016-9933.patch
+Patch110:	%{name}-CVE-2015-8874.patch
+Patch111:	%{name}-CVE-2019-6977.patch
+Patch112:	%{name}-CVE-2025-23016.patch
+Patch113:	%{name}-CVE-2018-17082.patch
+Patch114:	%{name}-CVE-2015-2305.patch
+Patch115:	%{name}-CVE-2016-6296.patch
+Patch116:	%{name}-CVE-2014-8626.patch
+Patch117:	%{name}-CVE-2013-6420.patch
+Patch118:	%{name}-CVE-2010-4150.patch
+Patch119:	%{name}-CVE-2018-19518.patch
+Patch120:	%{name}-CVE-2019-9024.patch
+Patch121:	%{name}-CVE-2019-9020.patch
+Patch122:	%{name}-CVE-2016-5769.patch
+Patch123:	%{name}-CVE-2017-11144.patch
+Patch124:	%{name}-CVE-2018-10548.patch
+Patch125:	%{name}-bcmath-scale-overflow.patch
+Patch126:	%{name}-CVE-2016-4542.patch
+Patch127:	%{name}-exif-bug70385.patch
+Patch128:	%{name}-CVE-2016-7128.patch
+Patch129:	%{name}-CVE-2018-14883.patch
+Patch130:	%{name}-exif-bug65873.patch
+Patch131:	%{name}-CVE-2019-11036.patch
+Patch132:	%{name}-CVE-2016-6291.patch
+Patch133:	%{name}-CVE-2018-14851.patch
+Patch134:	%{name}-CVE-2019-9638.patch
+Patch135:	%{name}-CVE-2019-11034.patch
+Patch136:	%{name}-CVE-2019-9640.patch
+Patch137:	%{name}-CVE-2019-11040.patch
+Patch138:	%{name}-CVE-2019-9641.patch
+Patch139:	%{name}-CVE-2019-11035.patch
+Patch140:	%{name}-getimagesize-short-read.patch
+Patch141:	%{name}-CVE-2016-7126.patch
+Patch142:	%{name}-CVE-2016-7127.patch
+Patch143:	%{name}-CVE-2014-5120.patch
+Patch144:	%{name}-CVE-2015-4598.patch
+Patch145:	%{name}-CVE-2015-6834.patch
+Patch146:	%{name}-CVE-2015-2787.patch
+Patch147:	%{name}-CVE-2016-10161.patch
+Patch148:	%{name}-CVE-2017-12933.patch
+Patch149:	%{name}-CVE-2024-8927.patch
+Patch150:	%{name}-cgi-shebang-eof.patch
+Patch151:	%{name}-CVE-2015-8935.patch
+Patch152:	%{name}-CVE-2015-4024.patch
+Patch153:	%{name}-CVE-2023-0662.patch
+Patch154:	%{name}-CVE-2012-1172.patch
+Patch155:	%{name}-CVE-2024-8925.patch
+Patch156:	%{name}-CVE-2016-7125.patch
+Patch157:	%{name}-CVE-2015-6835.patch
+Patch158:	%{name}-CVE-2018-7584.patch
+Patch159:	%{name}-CVE-2014-4721.patch
+Patch160:	%{name}-CVE-2015-2348.patch
+Patch161:	%{name}-CVE-2023-0568.patch
+Patch162:	%{name}-open-basedir-empty-path.patch
+Patch163:	%{name}-CVE-2015-4022.patch
+Patch164:	%{name}-CVE-2016-5399.patch
+Patch165:	%{name}-CVE-2016-10397.patch
+Patch166:	%{name}-CVE-2020-7059.patch
+Patch167:	%{name}-CVE-2011-1092.patch
+Patch168:	%{name}-CVE-2015-0232.patch
+Patch169:	%{name}-exif-zero-components.patch
 URL:		http://www.php.net/
 %{?with_interbase:%{!?with_interbase_inst:BuildRequires:	Firebird-devel >= 1.0.2.908-2}}
 %{?with_pspell:BuildRequires:	aspell-devel >= 2:0.50.0}
@@ -1664,6 +1769,111 @@ cp php.ini-dist php.ini
 %patch -P62 -p1
 %patch -P63 -p1
 %patch -P64 -p1
+%patch -P65 -p1
+%patch -P66 -p1
+%patch -P67 -p1
+%patch -P68 -p1
+%patch -P69 -p1
+%patch -P70 -p1
+%patch -P71 -p1
+%patch -P72 -p1
+%patch -P73 -p1
+%patch -P74 -p1
+%patch -P75 -p1
+%patch -P76 -p1
+%patch -P77 -p1
+%patch -P78 -p1
+%patch -P79 -p1
+%patch -P80 -p1
+%patch -P81 -p1
+%patch -P82 -p1
+%patch -P83 -p1
+%patch -P84 -p1
+%patch -P85 -p1
+%patch -P86 -p1
+%patch -P87 -p1
+%patch -P88 -p1
+%patch -P89 -p1
+%patch -P90 -p1
+%patch -P91 -p1
+%patch -P92 -p1
+%patch -P93 -p1
+%patch -P94 -p1
+%patch -P95 -p1
+%patch -P96 -p1
+%patch -P97 -p1
+%patch -P98 -p1
+%patch -P99 -p1
+%patch -P100 -p1
+%patch -P101 -p1
+%patch -P102 -p1
+%patch -P103 -p1
+%patch -P104 -p1
+%patch -P105 -p1
+%patch -P106 -p1
+%patch -P107 -p1
+%patch -P108 -p1
+%patch -P109 -p1
+%patch -P110 -p1
+%patch -P111 -p1
+%patch -P112 -p1
+%patch -P113 -p1
+%patch -P114 -p1
+%patch -P115 -p1
+%patch -P116 -p1
+%patch -P117 -p1
+%patch -P118 -p1
+%patch -P119 -p1
+%patch -P120 -p1
+%patch -P121 -p1
+%patch -P122 -p1
+%patch -P123 -p1
+%patch -P124 -p1
+%patch -P125 -p1
+%patch -P126 -p1
+%patch -P127 -p1
+%patch -P128 -p1
+%patch -P129 -p1
+%patch -P130 -p1
+%patch -P131 -p1
+%patch -P132 -p1
+%patch -P133 -p1
+%patch -P134 -p1
+%patch -P135 -p1
+%patch -P136 -p1
+%patch -P137 -p1
+%patch -P138 -p1
+%patch -P139 -p1
+%patch -P140 -p1
+%patch -P141 -p1
+%patch -P142 -p1
+%patch -P143 -p1
+%patch -P144 -p1
+%patch -P145 -p1
+%patch -P146 -p1
+%patch -P147 -p1
+%patch -P148 -p1
+%patch -P149 -p1
+%patch -P150 -p1
+%patch -P151 -p1
+%patch -P152 -p1
+%patch -P153 -p1
+%patch -P154 -p1
+%patch -P155 -p1
+%patch -P156 -p1
+%patch -P157 -p1
+%patch -P158 -p1
+%patch -P159 -p1
+%patch -P160 -p1
+%patch -P161 -p1
+%patch -P162 -p1
+%patch -P163 -p1
+%patch -P164 -p1
+%patch -P165 -p1
+%patch -P166 -p1
+%patch -P167 -p1
+%patch -P168 -p1
+%patch -P169 -p1
 
 %if %{with hardening}
 zcat %{SOURCE8} | patch -p1
@@ -1675,6 +1885,8 @@ cp -f Zend/LICENSE{,.Zend}
 %{__sed} -i -e 's/^char \*yytext/static &/' Zend/zend_{ini,language}_scanner.c
 
 touch ext/standard/parsedate.y
+# patches fix var_unserializer.re and the generated .c alike; keep re2c from regenerating it
+touch ext/standard/var_unserializer.c
 
 %build
 API=$(awk '/#define PHP_API_VERSION/{print $3}' main/php.h)
diff --git a/php4-CVE-2007-0907.patch b/php4-CVE-2007-0907.patch
new file mode 100644
index 0000000..a806e31
--- /dev/null
+++ b/php4-CVE-2007-0907.patch
@@ -0,0 +1,16 @@
+CVE-2007-0907: sapi_header_op() reads before the buffer for a header made only of whitespace.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/main/SAPI.c b/main/SAPI.c
+index 44dda8a..421560e 100644
+--- a/main/SAPI.c
++++ b/main/SAPI.c
+@@ -543,7 +543,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
+ 	header_line = estrndup(header_line, header_line_len);
+ 
+ 	/* cut of trailing spaces, linefeeds and carriage-returns */
+-	while(isspace(header_line[header_line_len-1])) 
++	while(header_line_len && isspace(header_line[header_line_len-1])) 
+ 		  header_line[--header_line_len]='\0';
+ 	
+ 	/* new line safety check */
diff --git a/php4-CVE-2007-4782.patch b/php4-CVE-2007-4782.patch
new file mode 100644
index 0000000..9ada9fb
--- /dev/null
+++ b/php4-CVE-2007-4782.patch
@@ -0,0 +1,41 @@
+CVE-2007-4782: fnmatch() and glob() overflow the libc stack on an overlong filename or pattern.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm); glob() check from upstream PHP 5.2.5
+
+diff --git a/ext/standard/dir.c b/ext/standard/dir.c
+index 10592f0..7165c6e 100644
+--- a/ext/standard/dir.c
++++ b/ext/standard/dir.c
+@@ -362,10 +362,15 @@ PHP_FUNCTION(glob)
+ 	glob_t globbuf;
+ 	int n, ret;
+ 
+-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &pattern, &pattern_len, &flags) == FAILURE) 
++	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &pattern, &pattern_len, &flags) == FAILURE)
+ 		return;
+ 
+-#ifdef ZTS 
++	if (pattern_len >= MAXPATHLEN) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
++		RETURN_FALSE;
++	}
++
++#ifdef ZTS
+ 	if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
+ 		result = VCWD_GETCWD(cwd, MAXPATHLEN);	
+ 		if (!result) {
+diff --git a/ext/standard/file.c b/ext/standard/file.c
+index 89b9738..287d024 100644
+--- a/ext/standard/file.c
++++ b/ext/standard/file.c
+@@ -2680,6 +2680,11 @@ PHP_FUNCTION(fnmatch)
+ 		== FAILURE)
+ 		return;
+ 
++	if (filename_len >= MAXPATHLEN) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename exceeds the maximum allowed length of %d characters", MAXPATHLEN);
++		RETURN_FALSE;
++	}
++
+ 	RETURN_BOOL( ! fnmatch( pattern, filename, flags ));
+ }
+ /* }}} */
diff --git a/php4-CVE-2007-5898.patch b/php4-CVE-2007-5898.patch
new file mode 100644
index 0000000..78e0868
--- /dev/null
+++ b/php4-CVE-2007-5898.patch
@@ -0,0 +1,164 @@
+CVE-2007-5898: htmlentities() and htmlspecialchars() read past the end of a partial multibyte sequence.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/standard/html.c b/ext/standard/html.c
+index 42d00a3..6bc8ad1 100644
+--- a/ext/standard/html.c
++++ b/ext/standard/html.c
+@@ -439,18 +439,29 @@ static const struct {
+ 			}                        \
+ 			mbseq[mbpos++] = (mbchar); }
+ 
++#define CHECK_LEN(pos, chars_need)			\
++	if((str_len - (pos)) < chars_need) {	\
++		*status = FAILURE;					\
++		return 0;							\
++	}
++
+ /* {{{ get_next_char
+  */
+ inline static unsigned short get_next_char(enum entity_charset charset,
+ 		unsigned char * str,
++		int str_len,
+ 		int * newpos,
+ 		unsigned char * mbseq,
+-		int * mbseqlen)
++		int * mbseqlen, 
++		int *status)
+ {
+ 	int pos = *newpos;
+ 	int mbpos = 0;
+ 	int mbspace = *mbseqlen;
+ 	unsigned short this_char = str[pos++];
++	unsigned char next_char;
++
++	*status = SUCCESS;
+ 	
+ 	if (mbspace <= 0) {
+ 		*mbseqlen = 0;
+@@ -472,6 +483,10 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 				do {
+ 					if (this_char < 0x80) {
+ 						more = 0;
++						if(stat) {
++							/* we didn't finish the UTF sequence correctly */
++							*status = FAILURE;
++						}
+ 						break;
+ 					} else if (this_char < 0xc0) {
+ 						switch (stat) {
+@@ -510,6 +525,7 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 								break;
+ 							default:
+ 								/* invalid */
++								*status = FAILURE;
+ 								more = 0;
+ 						}
+ 					}
+@@ -517,21 +533,27 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 					else if (this_char < 0xe0) {
+ 						stat = 0x10;	/* 2 byte */
+ 						utf = (this_char & 0x1f) << 6;
++						CHECK_LEN(pos, 1);
+ 					} else if (this_char < 0xf0) {
+ 						stat = 0x20;	/* 3 byte */
+ 						utf = (this_char & 0xf) << 12;
++						CHECK_LEN(pos, 2);
+ 					} else if (this_char < 0xf8) {
+ 						stat = 0x30;	/* 4 byte */
+ 						utf = (this_char & 0x7) << 18;
++						CHECK_LEN(pos, 3);
+ 					} else if (this_char < 0xfc) {
+ 						stat = 0x40;	/* 5 byte */
+ 						utf = (this_char & 0x3) << 24;
++						CHECK_LEN(pos, 4);
+ 					} else if (this_char < 0xfe) {
+ 						stat = 0x50;	/* 6 byte */
+ 						utf = (this_char & 0x1) << 30;
++						CHECK_LEN(pos, 5);
+ 					} else {
+ 						/* invalid; bail */
+ 						more = 0;
++						*status = FAILURE;
+ 						break;
+ 					}
+ 
+@@ -549,7 +571,8 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 				/* check if this is the first of a 2-byte sequence */
+ 				if (this_char >= 0xa1 && this_char <= 0xfe) {
+ 					/* peek at the next char */
+-					unsigned char next_char = str[pos];
++					CHECK_LEN(pos, 1);
++					next_char = str[pos];
+ 					if ((next_char >= 0x40 && next_char <= 0x7e) ||
+ 							(next_char >= 0xa1 && next_char <= 0xfe)) {
+ 						/* yes, this a wide char */
+@@ -569,7 +592,8 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 					 (this_char >= 0xe0 && this_char <= 0xef)
+ 					) {
+ 					/* peek at the next char */
+-					unsigned char next_char = str[pos];
++					CHECK_LEN(pos, 1);
++					next_char = str[pos];
+ 					if ((next_char >= 0x40 && next_char <= 0x7e) ||
+ 						(next_char >= 0x80 && next_char <= 0xfc))
+ 					{
+@@ -588,7 +612,8 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 				/* check if this is the first of a multi-byte sequence */
+ 				if (this_char >= 0xa1 && this_char <= 0xfe) {
+ 					/* peek at the next char */
+-					unsigned char next_char = str[pos];
++					CHECK_LEN(pos, 1);
++					next_char = str[pos];
+ 					if (next_char >= 0xa1 && next_char <= 0xfe) {
+ 						/* yes, this a jis kanji char */
+ 						this_char <<= 8;
+@@ -599,7 +624,8 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 					
+ 				} else if (this_char == 0x8e) {
+ 					/* peek at the next char */
+-					unsigned char next_char = str[pos];
++					CHECK_LEN(pos, 1);
++					next_char = str[pos];
+ 					if (next_char >= 0xa1 && next_char <= 0xdf) {
+ 						/* JIS X 0201 kana */
+ 						this_char <<= 8;
+@@ -610,8 +636,10 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 					
+ 				} else if (this_char == 0x8f) {
+ 					/* peek at the next two char */
+-					unsigned char next_char = str[pos];
+-					unsigned char next2_char = str[pos+1];
++					unsigned char next2_char;
++					CHECK_LEN(pos, 2);
++					next_char = str[pos];
++					next2_char = str[pos+1];
+ 					if ((next_char >= 0xa1 && next_char <= 0xfe) &&
+ 						(next2_char >= 0xa1 && next2_char <= 0xfe)) {
+ 						/* JIS X 0212 hojo-kanji */
+@@ -869,13 +897,22 @@ PHPAPI char *php_escape_html_entities(unsigned char *old, int oldlen, int *newle
+ 		maxlen = 128;
+ 	replaced = emalloc (maxlen);
+ 	len = 0;
+-
+ 	i = 0;
+ 	while (i < oldlen) {
+ 		unsigned char mbsequence[16];	/* allow up to 15 characters in a multibyte sequence */
+ 		int mbseqlen = sizeof(mbsequence);
+-		unsigned short this_char = get_next_char(charset, old, &i, mbsequence, &mbseqlen);
+-
++		int status = SUCCESS;
++		unsigned short this_char = get_next_char(charset, old, oldlen, &i, mbsequence, &mbseqlen, &status);
++
++		if(status == FAILURE) {
++			/* invalid MB sequence */
++			efree(replaced);
++			if(!PG(display_errors)) {
++				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid multibyte sequence in argument");
++			}
++			*newlen = 0;
++			return estrndup("", 0);
++		}
+ 		matches_map = 0;
+ 
+ 		if (len + 16 > maxlen)
diff --git a/php4-CVE-2008-2051.patch b/php4-CVE-2008-2051.patch
new file mode 100644
index 0000000..b947004
--- /dev/null
+++ b/php4-CVE-2008-2051.patch
@@ -0,0 +1,99 @@
+CVE-2008-2051: escapeshellcmd()/escapeshellarg() split multibyte characters, so an inserted backslash can be eaten by a lead byte. Characters with an ASCII trail byte are dropped by escapeshellcmd(), because PLD /bin/sh (mksh) parses bytes.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm), upstream PHP 5.2.6
+
+diff --git a/ext/standard/exec.c b/ext/standard/exec.c
+index c27092c..560ced2 100644
+--- a/ext/standard/exec.c
++++ b/ext/standard/exec.c
+@@ -24,6 +24,7 @@
+ #include "safe_mode.h"
+ #include "ext/standard/head.h"
+ #include "ext/standard/file.h"
++#include "basic_functions.h"
+ #include "exec.h"
+ #include "php_globals.h"
+ #include "SAPI.h"
+@@ -45,6 +46,8 @@
+ #include <fcntl.h>
+ #endif
+ 
++#include <wchar.h>
++
+ /* {{{ php_make_safe_mode_command */
+ static int php_make_safe_mode_command(char *cmd, char **safecmd TSRMLS_DC)
+ {
+@@ -402,11 +405,41 @@ PHPAPI char *php_escape_shell_cmd(char *str) {
+ 	register int x, y, l;
+ 	char *cmd;
+ 	char *p = NULL;
++	mbstate_t state;
+ 
+ 	l = strlen(str);
+ 	cmd = emalloc(2 * l + 1);
++
++	/* Initial conversion state. */
++	memset(&state, 0, sizeof state);
+ 	
+ 	for (x = 0, y = 0; x < l; x++) {
++		int mb_len = mbrlen(str + x, (l - x), &state);
++
++		/* skip non-valid multibyte characters */
++		if (mb_len < 0) {
++			/* Conversion state now invalid. */
++			memset(&state, 0, sizeof state);
++			continue;
++		} else if (mb_len > 1) {
++			int i;
++
++			/* An ASCII trail byte (0x5c in GBK, SJIS, Big5) is a metacharacter
++			 * to a byte-oriented /bin/sh and a part of the character to a
++			 * locale-aware one, so neither copying nor escaping it is safe. */
++			for (i = 1; i < mb_len; i++) {
++				if ((unsigned char) str[x + i] < 0x80) {
++					break;
++				}
++			}
++			if (i == mb_len) {
++				memcpy(cmd + y, str + x, mb_len);
++				y += mb_len;
++			}
++			x += mb_len - 1;
++			continue;
++		}
++
+ 		switch (str[x]) {
+ 			case '"':
+ 			case '\'':
+@@ -465,6 +498,7 @@ PHPAPI char *php_escape_shell_cmd(char *str) {
+ PHPAPI char *php_escape_shell_arg(char *str) {
+ 	int x, y, l;
+ 	char *cmd;
++	mbstate_t state;
+ 
+ 	y = 0;
+ 	l = strlen(str);
+@@ -476,7 +510,24 @@ PHPAPI char *php_escape_shell_arg(char *str) {
+ 	cmd[y++] = '\'';
+ #endif
+ 	
++	/* Initial conversion state. */
++	memset(&state, 0, sizeof state);
++	
+ 	for (x = 0; x < l; x++) {
++		int mb_len = mbrlen(str + x, (l - x), &state);
++
++		/* skip non-valid multibyte characters */
++		if (mb_len < 0) {
++			/* Conversion state now invalid. */
++			memset(&state, 0, sizeof state);
++			continue;
++		} else if (mb_len > 1) {
++			memcpy(cmd + y, str + x, mb_len);
++			y += mb_len;
++			x += mb_len - 1;
++			continue;
++		}
++
+ 		switch (str[x]) {
+ #ifdef PHP_WIN32
+ 		case '"':
diff --git a/php4-CVE-2008-2107.patch b/php4-CVE-2008-2107.patch
new file mode 100644
index 0000000..d2604be
--- /dev/null
+++ b/php4-CVE-2008-2107.patch
@@ -0,0 +1,16 @@
+CVE-2008-2107/CVE-2008-2108: GENERATE_SEED() loses most of its entropy (CVE-2008-2107, CVE-2008-2108), weakening rand() and mt_rand() seeds.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/standard/php_rand.h b/ext/standard/php_rand.h
+index 2900d99..eb8e8ed 100644
+--- a/ext/standard/php_rand.h
++++ b/ext/standard/php_rand.h
+@@ -49,7 +49,7 @@
+ #ifdef PHP_WIN32
+ #define GENERATE_SEED() ((long) (time(0) * GetCurrentProcessId() * 1000000 * php_combined_lcg(TSRMLS_C)))
+ #else
+-#define GENERATE_SEED() ((long) (time(0) * getpid() * 1000000 * php_combined_lcg(TSRMLS_C)))
++#define GENERATE_SEED() (((long) (time(0) * getpid())) ^ ((long) (1000000.0 * php_combined_lcg(TSRMLS_C))))
+ #endif
+ 
+ PHPAPI void php_srand(long seed TSRMLS_DC);
diff --git a/php4-CVE-2008-3660.patch b/php4-CVE-2008-3660.patch
new file mode 100644
index 0000000..682db63
--- /dev/null
+++ b/php4-CVE-2008-3660.patch
@@ -0,0 +1,56 @@
+CVE-2008-3660: cgi/fastcgi rejects a valid script path containing '..' (foo..php) and crashes; only '..' path components are refused now.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm), upstream cgi_main.c 1.267.2.15.2.58
+
+diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
+index 9b149e9..0e4b0cb 100644
+--- a/sapi/cgi/cgi_main.c
++++ b/sapi/cgi/cgi_main.c
+@@ -617,6 +617,39 @@ static void php_cgi_usage(char *argv0)
+ }
+ /* }}} */
+ 
++/* {{{ is_valid_path
++ *
++ * some server configurations allow '..' to slip through in the
++ * translated path.   We'll just refuse to handle such a path.
++ */
++static int is_valid_path(const char *path)
++{
++	const char *p;
++
++	if (!path) {
++		return 0;
++	}
++	p = strstr(path, "..");
++	if (p) {
++		if ((p == path || IS_SLASH(*(p-1))) &&
++		    (*(p+2) == 0 || IS_SLASH(*(p+2)))) {
++			return 0;
++		}
++		while (1) {
++			p = strstr(p+1, "..");
++			if (!p) {
++				break;
++			}
++			if (IS_SLASH(*(p-1)) &&
++			    (*(p+2) == 0 || IS_SLASH(*(p+2)))) {
++					return 0;
++			}
++		}
++	}
++	return 1;
++}
++/* }}} */
++
+ /* {{{ init_request_info
+ 
+   initializes request_info structure
+@@ -890,7 +923,7 @@ static void init_request_info(TSRMLS_D)
+ 		SG(request_info).query_string = sapi_cgibin_getenv("QUERY_STRING",0 TSRMLS_CC);
+ 		/* some server configurations allow '..' to slip through in the
+ 		   translated path.   We'll just refuse to handle such a path. */
+-		if (script_path_translated && !strstr(script_path_translated, "..")) {
++		if (is_valid_path(script_path_translated)) {
+ 			SG(request_info).path_translated = estrdup(script_path_translated);
+ 		}
+ 		SG(request_info).content_type = (content_type ? content_type : "" );
diff --git a/php4-CVE-2008-5498.patch b/php4-CVE-2008-5498.patch
new file mode 100644
index 0000000..23b1f51
--- /dev/null
+++ b/php4-CVE-2008-5498.patch
@@ -0,0 +1,25 @@
+CVE-2008-5498: imagerotate() reads outside the palette for a negative background colour, and at index -1 with ignore_transparent on a palette image without a transparent colour (the latter is PLD-only).
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
+index 8f80fa0..0e595fc 100644
+--- a/ext/gd/libgd/gd.c
++++ b/ext/gd/libgd/gd.c
+@@ -3025,7 +3025,7 @@ gdImagePtr gdImageRotate45 (gdImagePtr src, double dAngle, int clrBack, int igno
+ 	if (ignoretransparent) {
+ 		if (gdImageTrueColor(src)) {
+ 			dst1->transparent = src->transparent;
+-		} else {
++		} else if (src->transparent != -1) {
+ 
+ 			dst1->transparent = gdTrueColorAlpha(gdImageRed(src, src->transparent), gdImageBlue(src, src->transparent), gdImageGreen(src, src->transparent), 127);
+ 		}
+@@ -3135,7 +3135,7 @@ gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignore
+ 		return NULL;
+ 	}
+ 
+-	if (!gdImageTrueColor(src) && clrBack>=gdImageColorsTotal(src)) {
++	if (!gdImageTrueColor(src) && (clrBack < 0 || clrBack>=gdImageColorsTotal(src))) {
+ 		return NULL;
+ 	}
+ 
diff --git a/php4-CVE-2008-5557.patch b/php4-CVE-2008-5557.patch
new file mode 100644
index 0000000..ae608ba
--- /dev/null
+++ b/php4-CVE-2008-5557.patch
@@ -0,0 +1,43 @@
+CVE-2008-5557: mbstring: heap overflow in the HTML entity decoder when output fails while flushing.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm), upstream mbfilter_htmlent.c 1.8
+
+diff --git a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c
+index 40c24c3..6c6654a 100644
+--- a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c
++++ b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c
+@@ -232,8 +232,7 @@ int mbfl_filt_conv_html_dec(int c, mbfl_convert_filter *filter)
+ 				mbfl_filt_conv_html_dec_flush(filter);
+ 				if (c=='&')
+ 				{
+-					filter->status = 1;
+-					buffer[0] = '&';
++					buffer[filter->status++] = '&';
+ 				}
+ 			}
+ 		}
+@@ -244,17 +243,19 @@ int mbfl_filt_conv_html_dec(int c, mbfl_convert_filter *filter)
+ int mbfl_filt_conv_html_dec_flush(mbfl_convert_filter *filter)
+ {
+ 	int status, pos = 0;
+-	char *buffer;
++	unsigned char *buffer;
++	int err = 0;
+ 
+-	buffer = (char*)filter->opaque;
++	buffer = (unsigned char*)filter->opaque;
+ 	status = filter->status;
++	filter->status = 0;
+ 	/* flush fragments */
+ 	while (status--) {
+-		CK((*filter->output_function)(buffer[pos++], filter->data));
++		int e = (*filter->output_function)(buffer[pos++], filter->data);
++		if (e != 0)
++			err = e;
+ 	}
+-	filter->status = 0;
+-	/*filter->buffer = 0; of cause NOT*/
+-	return 0;
++	return err;
+ }
+ 
+ 
diff --git a/php4-CVE-2009-2687.patch b/php4-CVE-2009-2687.patch
new file mode 100644
index 0000000..7fe6818
--- /dev/null
+++ b/php4-CVE-2009-2687.patch
@@ -0,0 +1,18 @@
+CVE-2009-2687: exif_read_data() reads out of bounds on a JPEG whose IFD starts past the section end.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index cbb7fe9..bde44b7 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -3079,6 +3079,10 @@ static void exif_process_TIFF_in_JPEG(image_info_type *ImageInfo, char *CharBuf,
+ 		exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_WARNING, "invalid TIFF start (1)");
+ 		return;
+ 	}
++	if (offset_of_ifd > length) {
++		exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_WARNING, "Invalid IFD start");
++		return;
++	}
+ 
+ 	ImageInfo->sections_found |= FOUND_IFD0;
+ 	/* First directory starts at offset 8. Offsets starts at 0. */
diff --git a/php4-CVE-2009-3291.patch b/php4-CVE-2009-3291.patch
new file mode 100644
index 0000000..8f8459b
--- /dev/null
+++ b/php4-CVE-2009-3291.patch
@@ -0,0 +1,37 @@
+CVE-2009-3291: openssl CN_match accepts a peer certificate whose CN carries an embedded NUL byte.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
+index 373ebc4..0ac5643 100644
+--- a/ext/openssl/openssl.c
++++ b/ext/openssl/openssl.c
+@@ -3158,8 +3158,15 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
+ 	GET_VER_OPT_STRING("CN_match", cnmatch);
+ 	if (cnmatch) {
+ 		int match = 0;
+-		
+-		X509_NAME_get_text_by_NID(name, NID_commonName, buf, sizeof(buf));
++ 		int name_len = X509_NAME_get_text_by_NID(name, NID_commonName, buf, sizeof(buf));
++ 
++ 		if (name_len == -1) {
++ 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN");
++ 			return FAILURE;
++ 		} else if (name_len != strlen(buf)) {
++ 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", name_len, buf);
++ 			return FAILURE;
++ 		}
+ 
+ 		match = strcmp(cnmatch, buf) == 0;
+ 
+@@ -3175,10 +3182,7 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
+ 
+ 		if (!match) {
+ 			/* didn't match */
+-			php_error_docref(NULL TSRMLS_CC, E_WARNING,
+-					"Peer certificate CN=`%s' did not match expected CN=`%s'",
+-					buf, cnmatch);
+-
++			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", name_len, buf, cnmatch);
+ 			return FAILURE;
+ 		}
+ 	}
diff --git a/php4-CVE-2009-3292.patch b/php4-CVE-2009-3292.patch
new file mode 100644
index 0000000..5edc03c
--- /dev/null
+++ b/php4-CVE-2009-3292.patch
@@ -0,0 +1,71 @@
+CVE-2009-3292: exif: no EOF check while reading JPEG section lengths, unbounded TIFF IFD recursion.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index bde44b7..496ef9c 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -3107,7 +3107,7 @@ static void exif_process_APP1(image_info_type *ImageInfo, char *CharBuf, size_t
+ {
+ 	/* Check the APP1 for Exif Identifier Code */
+ 	static const uchar ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
+-	if (memcmp(CharBuf+2, ExifHeader, 6)) {
++	if (length <= 8 || memcmp(CharBuf+2, ExifHeader, 6)) {
+ 		exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_WARNING, "incorrect APP1 Exif Identifier Code");
+ 		return;
+ 	}
+@@ -3190,8 +3190,14 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo TSRMLS_DC)
+ 		}
+ 
+ 		/* Read the length of the section. */
+-		lh = php_stream_getc(ImageInfo->infile);
+-		ll = php_stream_getc(ImageInfo->infile);
++		if ((lh = php_stream_getc(ImageInfo->infile)) == EOF) {
++			EXIF_ERRLOG_CORRUPT
++			return FALSE;
++		}
++		if ((ll = php_stream_getc(ImageInfo->infile)) == EOF) {
++			EXIF_ERRLOG_CORRUPT
++			return FALSE;
++		}
+ 
+ 		itemlen = (lh << 8) | ll;
+ 
+@@ -3387,6 +3393,10 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
+ 	int entry_tag , entry_type;
+ 	tag_table_type tag_table = exif_get_tag_table(section_index);
+ 
++	if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) {
++                return FALSE;
++        }
++
+ 	if (ImageInfo->FileSize >= dir_offset+2) {
+ 		sn = exif_file_sections_add(ImageInfo, M_PSEUDO, 2, NULL);
+ #ifdef EXIF_DEBUG
+@@ -3530,6 +3540,7 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
+ #ifdef EXIF_DEBUG
+ 						exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_NOTICE, "next IFD: %s @x%04X", exif_get_sectionname(sub_section_index), entry_offset);
+ #endif
++						ImageInfo->ifd_nesting_level++;
+ 						exif_process_IFD_in_TIFF(ImageInfo, entry_offset, sub_section_index TSRMLS_CC);
+ 						if (section_index!=SECTION_THUMBNAIL && entry_tag==TAG_SUB_IFD) {
+ 							if (ImageInfo->Thumbnail.filetype != IMAGE_FILETYPE_UNKNOWN
+@@ -3569,6 +3580,7 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
+ #ifdef EXIF_DEBUG
+ 					exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_NOTICE, "read next IFD (THUMBNAIL) at x%04X", next_offset);
+ #endif
++					ImageInfo->ifd_nesting_level++;
+ 					exif_process_IFD_in_TIFF(ImageInfo, next_offset, SECTION_THUMBNAIL TSRMLS_CC);
+ #ifdef EXIF_DEBUG
+ 					exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_NOTICE, "%s THUMBNAIL @0x%04X + 0x%04X", ImageInfo->Thumbnail.data ? "ignore" : "read", ImageInfo->Thumbnail.offset, ImageInfo->Thumbnail.size);
+@@ -3637,9 +3649,7 @@ static int exif_scan_FILE_header(image_info_type *ImageInfo TSRMLS_DC)
+ 				} else {
+ 					exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_WARNING, "invalid TIFF file");
+ 				}
+-			}
+-			else
+-			if (!memcmp(file_header, "MM\x00\x2a", 4)) {
++			} else if (!memcmp(file_header, "MM\x00\x2a", 4)) {
+ 				ImageInfo->FileType = IMAGE_FILETYPE_TIFF_MM;
+ 				ImageInfo->motorola_intel = 1;
+ #ifdef EXIF_DEBUG
diff --git a/php4-CVE-2009-3546.patch b/php4-CVE-2009-3546.patch
new file mode 100644
index 0000000..50624f4
--- /dev/null
+++ b/php4-CVE-2009-3546.patch
@@ -0,0 +1,17 @@
+CVE-2009-3546: gd: _gdGetColors() overflows the palette for a GD file with more than gdMaxColors colours.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/gd/libgd/gd_gd.c b/ext/gd/libgd/gd_gd.c
+index 55587d4..81a957d 100644
+--- a/ext/gd/libgd/gd_gd.c
++++ b/ext/gd/libgd/gd_gd.c
+@@ -39,6 +39,9 @@ int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag)
+ 			if (!gdGetWord(&im->colorsTotal, in)) {
+ 				goto fail1;
+ 			}
++			if (im->colorsTotal > gdMaxColors) {
++				goto fail1;
++			}
+ 		}
+ 		/* Int to accommodate truecolor single-color transparency */
+ 		if (!gdGetInt(&im->transparent, in)) {
diff --git a/php4-CVE-2009-4017.patch b/php4-CVE-2009-4017.patch
new file mode 100644
index 0000000..186e9fd
--- /dev/null
+++ b/php4-CVE-2009-4017.patch
@@ -0,0 +1,61 @@
+CVE-2009-4017: unlimited number of uploaded files per request fills the temp dir; adds max_file_uploads (default 20).
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/main/main.c b/main/main.c
+index c061b00..d5ebd0e 100644
+--- a/main/main.c
++++ b/main/main.c
+@@ -357,6 +357,7 @@ PHP_INI_BEGIN()
+ 	PHP_INI_ENTRY("sendmail_path",	DEFAULT_SENDMAIL_PATH,	PHP_INI_SYSTEM,		NULL)
+ 	PHP_INI_ENTRY("disable_functions",			"",			PHP_INI_SYSTEM,		NULL)
+ 	PHP_INI_ENTRY("disable_classes",			"",			PHP_INI_SYSTEM,		NULL)
++	PHP_INI_ENTRY("max_file_uploads",			"20",			PHP_INI_SYSTEM,		NULL)
+ 
+ 	STD_PHP_INI_BOOLEAN("allow_url_fopen",		"1",		PHP_INI_SYSTEM,		OnUpdateBool,			allow_url_fopen,			php_core_globals,	core_globals)
+ 	STD_PHP_INI_BOOLEAN("always_populate_raw_post_data",		"0",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateBool,			always_populate_raw_post_data,			php_core_globals,	core_globals)
+diff --git a/main/rfc1867.c b/main/rfc1867.c
+index 61620ec..81b1353 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -31,6 +31,7 @@
+ #include "php_globals.h"
+ #include "php_variables.h"
+ #include "rfc1867.h"
++#include "php_ini.h"
+ 
+ #undef DEBUG_FILE_UPLOAD
+ 
+@@ -787,6 +788,12 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
+ 	zval *array_ptr = (zval *) arg;
+ 	int fd=-1;
+ 	zend_llist header;
++ 	char *max_uploads = INI_STR("max_file_uploads");
++ 	int upload_cnt = 20;
++ 
++ 	if (max_uploads && *max_uploads) {
++ 		upload_cnt = atoi(max_uploads);
++ 	}
+ 
+ 	if (SG(request_info).content_length > SG(post_max_size)) {
+ 		sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size));
+@@ -931,7 +938,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
+ 					efree(param);
+ 				}
+ 				continue;
+-			}
++ 			} else if (upload_cnt <= 0) {
++ 				skip_upload = 1;
++ 				sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded");
++  			}
++            
+ 
+ 			/* Return with an error if the posted data is garbled */
+ 			if (!param) {
+@@ -970,6 +981,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
+ 			if (!skip_upload) {
+ 				/* Handle file */
+ 				fd = php_open_temporary_fd(PG(upload_tmp_dir), "php", &temp_filename TSRMLS_CC);
++				upload_cnt--;
+ 				if (fd==-1) {
+ 					sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file");
+ 					cancel_upload = UPLOAD_ERROR_E;
diff --git a/php4-CVE-2009-4142.patch b/php4-CVE-2009-4142.patch
new file mode 100644
index 0000000..5b65b94
--- /dev/null
+++ b/php4-CVE-2009-4142.patch
@@ -0,0 +1,368 @@
+CVE-2009-4142: htmlspecialchars() lets invalid multibyte sequences through, XSS.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/standard/html.c b/ext/standard/html.c
+index 6bc8ad1..fb11c2e 100644
+--- a/ext/standard/html.c
++++ b/ext/standard/html.c
+@@ -439,15 +439,31 @@ static const struct {
+ 			}                        \
+ 			mbseq[mbpos++] = (mbchar); }
+ 
++/* skip one byte and return */
++#define MB_FAILURE(pos) do { \
++	*newpos = pos + 1; \
++	*status = FAILURE; \
++	return 0; \
++} while (0)
++
+ #define CHECK_LEN(pos, chars_need)			\
+-	if((str_len - (pos)) < chars_need) {	\
+-		*status = FAILURE;					\
+-		return 0;							\
++	if (chars_need < 1) {						\
++		if((str_len - (pos)) < chars_need) {	\
++			*newpos = pos;						\
++			*status = FAILURE;					\
++			return 0;							\
++		}										\
++	} else {									\
++		if((str_len - (pos)) < chars_need) {	\
++			*newpos = pos + 1;					\
++			*status = FAILURE;					\
++			return 0;							\
++		}										\
+ 	}
+ 
+ /* {{{ get_next_char
+  */
+-inline static unsigned short get_next_char(enum entity_charset charset,
++inline static unsigned int get_next_char(enum entity_charset charset,
+ 		unsigned char * str,
+ 		int str_len,
+ 		int * newpos,
+@@ -458,205 +474,191 @@ inline static unsigned short get_next_char(enum entity_charset charset,
+ 	int pos = *newpos;
+ 	int mbpos = 0;
+ 	int mbspace = *mbseqlen;
+-	unsigned short this_char = str[pos++];
++	unsigned int this_char = 0;
+ 	unsigned char next_char;
+ 
+ 	*status = SUCCESS;
+-	
++
+ 	if (mbspace <= 0) {
+ 		*mbseqlen = 0;
+-		return this_char;
++		CHECK_LEN(pos, 1);
++		*newpos = pos + 1;
++		return str[pos];
+ 	}
+-	
+-	MB_WRITE((unsigned char)this_char);
+-	
++
+ 	switch (charset) {
+ 		case cs_utf_8:
+ 			{
+-				unsigned long utf = 0;
+-				int stat = 0;
+-				int more = 1;
+-
+-				/* unpack utf-8 encoding into a wide char.
+-				 * Code stolen from the mbstring extension */
+-
+-				do {
++				unsigned char c;
++				CHECK_LEN(pos, 1);
++				c = str[pos];
++				if (c < 0x80) {
++					MB_WRITE(c);
++					this_char = c;
++					pos++;
++				} else if (c < 0xc0) {
++					MB_FAILURE(pos);
++				} else if (c < 0xe0) {
++					CHECK_LEN(pos, 2);
++					if (str[pos + 1] < 0x80 || str[pos + 1] > 0xbf) {
++						MB_FAILURE(pos);
++					}
++					this_char = ((c & 0x1f) << 6) | (str[pos + 1] & 0x3f);
+ 					if (this_char < 0x80) {
+-						more = 0;
+-						if(stat) {
+-							/* we didn't finish the UTF sequence correctly */
+-							*status = FAILURE;
+-						}
+-						break;
+-					} else if (this_char < 0xc0) {
+-						switch (stat) {
+-							case 0x10:	/* 2, 2nd */
+-							case 0x21:	/* 3, 3rd */
+-							case 0x32:	/* 4, 4th */
+-							case 0x43:	/* 5, 5th */
+-							case 0x54:	/* 6, 6th */
+-								/* last byte in sequence */
+-								more = 0;
+-								utf |= (this_char & 0x3f);
+-								this_char = (unsigned short)utf;
+-								break;
+-							case 0x20:	/* 3, 2nd */
+-							case 0x31:	/* 4, 3rd */
+-							case 0x42:	/* 5, 4th */
+-							case 0x53:	/* 6, 5th */
+-								/* penultimate char */
+-								utf |= ((this_char & 0x3f) << 6);
+-								stat++;
+-								break;
+-							case 0x30:	/* 4, 2nd */
+-							case 0x41:	/* 5, 3rd */
+-							case 0x52:	/* 6, 4th */
+-								utf |= ((this_char & 0x3f) << 12);
+-								stat++;
+-								break;
+-							case 0x40:	/* 5, 2nd */
+-							case 0x51:
+-								utf |= ((this_char & 0x3f) << 18);
+-								stat++;
+-								break;
+-							case 0x50:	/* 6, 2nd */
+-								utf |= ((this_char & 0x3f) << 24);
+-								stat++;
+-								break;
+-							default:
+-								/* invalid */
+-								*status = FAILURE;
+-								more = 0;
+-						}
++						MB_FAILURE(pos);
+ 					}
+-					/* lead byte */
+-					else if (this_char < 0xe0) {
+-						stat = 0x10;	/* 2 byte */
+-						utf = (this_char & 0x1f) << 6;
+-						CHECK_LEN(pos, 1);
+-					} else if (this_char < 0xf0) {
+-						stat = 0x20;	/* 3 byte */
+-						utf = (this_char & 0xf) << 12;
+-						CHECK_LEN(pos, 2);
+-					} else if (this_char < 0xf8) {
+-						stat = 0x30;	/* 4 byte */
+-						utf = (this_char & 0x7) << 18;
+-						CHECK_LEN(pos, 3);
+-					} else if (this_char < 0xfc) {
+-						stat = 0x40;	/* 5 byte */
+-						utf = (this_char & 0x3) << 24;
+-						CHECK_LEN(pos, 4);
+-					} else if (this_char < 0xfe) {
+-						stat = 0x50;	/* 6 byte */
+-						utf = (this_char & 0x1) << 30;
+-						CHECK_LEN(pos, 5);
+-					} else {
+-						/* invalid; bail */
+-						more = 0;
+-						*status = FAILURE;
+-						break;
++					MB_WRITE((unsigned char)c);
++					MB_WRITE((unsigned char)str[pos + 1]);
++					pos += 2;
++				} else if (c < 0xf0) {
++					CHECK_LEN(pos, 3);
++					if (str[pos + 1] < 0x80 || str[pos + 1] > 0xbf) {
++						MB_FAILURE(pos);
+ 					}
+-
+-					if (more) {
+-						this_char = str[pos++];
+-						MB_WRITE((unsigned char)this_char);
++					if (str[pos + 2] < 0x80 || str[pos + 2] > 0xbf) {
++						MB_FAILURE(pos);
++					}
++					this_char = ((c & 0x0f) << 12) | ((str[pos + 1] & 0x3f) << 6) | (str[pos + 2] & 0x3f);
++					if (this_char < 0x800) {
++						MB_FAILURE(pos);
++					} else if (this_char >= 0xd800 && this_char <= 0xdfff) {
++						MB_FAILURE(pos);
++					}
++					MB_WRITE((unsigned char)c);
++					MB_WRITE((unsigned char)str[pos + 1]);
++					MB_WRITE((unsigned char)str[pos + 2]);
++					pos += 3;
++				} else if (c < 0xf8) {
++					CHECK_LEN(pos, 4);
++					if (str[pos + 1] < 0x80 || str[pos + 1] > 0xbf) {
++						MB_FAILURE(pos);
+ 					}
+-				} while (more);
++					if (str[pos + 2] < 0x80 || str[pos + 2] > 0xbf) {
++						MB_FAILURE(pos);
++					}
++					if (str[pos + 3] < 0x80 || str[pos + 3] > 0xbf) {
++						MB_FAILURE(pos);
++					}
++					this_char = ((c & 0x07) << 18) | ((str[pos + 1] & 0x3f) << 12) | ((str[pos + 2] & 0x3f) << 6) | (str[pos + 3] & 0x3f);
++					if (this_char < 0x10000) {
++						MB_FAILURE(pos);
++					}
++					MB_WRITE((unsigned char)c);
++					MB_WRITE((unsigned char)str[pos + 1]);
++					MB_WRITE((unsigned char)str[pos + 2]);
++					MB_WRITE((unsigned char)str[pos + 3]);
++					pos += 4;
++				} else {
++					MB_FAILURE(pos);
++				}
+ 			}
+ 			break;
+ 		case cs_big5:
+ 		case cs_gb2312:
+ 		case cs_big5hkscs:
+ 			{
++				CHECK_LEN(pos, 1);
++				this_char = str[pos++];
+ 				/* check if this is the first of a 2-byte sequence */
+-				if (this_char >= 0xa1 && this_char <= 0xfe) {
++				if (this_char >= 0x81 && this_char <= 0xfe) {
+ 					/* peek at the next char */
+ 					CHECK_LEN(pos, 1);
+-					next_char = str[pos];
++					next_char = str[pos++];
+ 					if ((next_char >= 0x40 && next_char <= 0x7e) ||
+ 							(next_char >= 0xa1 && next_char <= 0xfe)) {
+ 						/* yes, this a wide char */
+-						this_char <<= 8;
++						MB_WRITE(this_char);
+ 						MB_WRITE(next_char);
+-						this_char |= next_char;
+-						pos++;
++						this_char = (this_char << 8) | next_char;
++					} else {
++						MB_FAILURE(pos);
+ 					}
+-					
++				} else {
++					MB_WRITE(this_char);
+ 				}
+-				break;
+ 			}
++			break;
+ 		case cs_sjis:
+ 			{
++				CHECK_LEN(pos, 1);
++				this_char = str[pos++];
+ 				/* check if this is the first of a 2-byte sequence */
+-				if ( (this_char >= 0x81 && this_char <= 0x9f) ||
+-					 (this_char >= 0xe0 && this_char <= 0xef)
+-					) {
++				if ((this_char >= 0x81 && this_char <= 0x9f) ||
++					(this_char >= 0xe0 && this_char <= 0xfc)) {
+ 					/* peek at the next char */
+ 					CHECK_LEN(pos, 1);
+-					next_char = str[pos];
++					next_char = str[pos++];
+ 					if ((next_char >= 0x40 && next_char <= 0x7e) ||
+ 						(next_char >= 0x80 && next_char <= 0xfc))
+ 					{
+ 						/* yes, this a wide char */
+-						this_char <<= 8;
++						MB_WRITE(this_char);
+ 						MB_WRITE(next_char);
+-						this_char |= next_char;
+-						pos++;
++						this_char = (this_char << 8) | next_char;
++					} else {
++						MB_FAILURE(pos);
+ 					}
+-					
++				} else {
++					MB_WRITE(this_char);
+ 				}
+ 				break;
+ 			}
+ 		case cs_eucjp:
+ 			{
++				CHECK_LEN(pos, 1);
++				this_char = str[pos++];
+ 				/* check if this is the first of a multi-byte sequence */
+ 				if (this_char >= 0xa1 && this_char <= 0xfe) {
+ 					/* peek at the next char */
+ 					CHECK_LEN(pos, 1);
+-					next_char = str[pos];
++					next_char = str[pos++];
+ 					if (next_char >= 0xa1 && next_char <= 0xfe) {
+ 						/* yes, this a jis kanji char */
+-						this_char <<= 8;
++						MB_WRITE(this_char);
+ 						MB_WRITE(next_char);
+-						this_char |= next_char;
+-						pos++;
++						this_char = (this_char << 8) | next_char;
++					} else {
++						MB_FAILURE(pos);
+ 					}
+-					
+ 				} else if (this_char == 0x8e) {
+ 					/* peek at the next char */
+ 					CHECK_LEN(pos, 1);
+-					next_char = str[pos];
++					next_char = str[pos++];
+ 					if (next_char >= 0xa1 && next_char <= 0xdf) {
+ 						/* JIS X 0201 kana */
+-						this_char <<= 8;
++						MB_WRITE(this_char);
+ 						MB_WRITE(next_char);
+-						this_char |= next_char;
+-						pos++;
++						this_char = (this_char << 8) | next_char;
++					} else {
++						MB_FAILURE(pos);
+ 					}
+-					
+ 				} else if (this_char == 0x8f) {
+ 					/* peek at the next two char */
+ 					unsigned char next2_char;
+ 					CHECK_LEN(pos, 2);
+ 					next_char = str[pos];
+-					next2_char = str[pos+1];
++					next2_char = str[pos + 1];
++					pos += 2;
+ 					if ((next_char >= 0xa1 && next_char <= 0xfe) &&
+ 						(next2_char >= 0xa1 && next2_char <= 0xfe)) {
+ 						/* JIS X 0212 hojo-kanji */
+-						this_char <<= 8;
++						MB_WRITE(this_char);
+ 						MB_WRITE(next_char);
+-						this_char |= next_char;
+-						pos++;
+-						this_char <<= 8;
+ 						MB_WRITE(next2_char);
+-						this_char |= next2_char;
+-						pos++;
++						this_char = (this_char << 16) | (next_char << 8) | next2_char;
++					} else {
++						MB_FAILURE(pos);
+ 					}
+-					
++				} else {
++					MB_WRITE(this_char);
+ 				}
+ 				break;
+ 			}
+ 		default:
++			/* single-byte charsets */
++			CHECK_LEN(pos, 1);
++			this_char = str[pos++];
++			MB_WRITE(this_char);
+ 			break;
+ 	}
+ 	MB_RETURN;
+@@ -902,7 +904,7 @@ PHPAPI char *php_escape_html_entities(unsigned char *old, int oldlen, int *newle
+ 		unsigned char mbsequence[16];	/* allow up to 15 characters in a multibyte sequence */
+ 		int mbseqlen = sizeof(mbsequence);
+ 		int status = SUCCESS;
+-		unsigned short this_char = get_next_char(charset, old, oldlen, &i, mbsequence, &mbseqlen, &status);
++		unsigned int this_char = get_next_char(charset, old, oldlen, &i, mbsequence, &mbseqlen, &status);
+ 
+ 		if(status == FAILURE) {
+ 			/* invalid MB sequence */
diff --git a/php4-CVE-2010-0397.patch b/php4-CVE-2010-0397.patch
new file mode 100644
index 0000000..30bcae3
--- /dev/null
+++ b/php4-CVE-2010-0397.patch
@@ -0,0 +1,56 @@
+CVE-2010-0397: xmlrpc_decode_request() dereferences NULL for a request without methodName.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/xmlrpc/tests/bug51288.phpt b/ext/xmlrpc/tests/bug51288.phpt
+new file mode 100644
+index 0000000..d9bdef8
+--- /dev/null
++++ b/ext/xmlrpc/tests/bug51288.phpt
+@@ -0,0 +1,14 @@
++--TEST--
++Bug #51288 (CVE-2010-0397, NULL pointer deref when no <methodName> in request)
++--FILE--
++<?php
++$method = NULL;
++$req = '<?xml version="1.0"?><methodCall></methodCall>';
++var_dump(xmlrpc_decode_request($req, $method));
++var_dump($method);
++echo "Done\n";
++?>
++--EXPECT--
++NULL
++NULL
++Done
+diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c
+index 981a1ec..318be98 100644
+--- a/ext/xmlrpc/xmlrpc-epi-php.c
++++ b/ext/xmlrpc/xmlrpc-epi-php.c
+@@ -733,6 +733,7 @@ zval* decode_request_worker (zval* xml_in, zval* encoding_in, zval* method_name_
+    XMLRPC_REQUEST response;
+    STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS opts = {{0}};
+    opts.xml_elem_opts.encoding = encoding_in ? utf8_get_encoding_id_from_string(Z_STRVAL_P(encoding_in)) : ENCODING_DEFAULT;
++   const char *method_name;
+ 
+    /* generate XMLRPC_REQUEST from raw xml */
+    response = XMLRPC_REQUEST_FromXML(Z_STRVAL_P(xml_in), Z_STRLEN_P(xml_in), &opts);
+@@ -742,10 +743,16 @@ zval* decode_request_worker (zval* xml_in, zval* encoding_in, zval* method_name_
+ 
+       if(XMLRPC_RequestGetRequestType(response) == xmlrpc_request_call) {
+          if(method_name_out) {
+-            convert_to_string(method_name_out);
+-            Z_TYPE_P(method_name_out) = IS_STRING;
+-            Z_STRVAL_P(method_name_out) = estrdup(XMLRPC_RequestGetMethodName(response));
+-            Z_STRLEN_P(method_name_out) = strlen(Z_STRVAL_P(method_name_out));
++	     method_name = XMLRPC_RequestGetMethodName(response);
++	     if (method_name) {
++                zval_dtor(method_name_out);
++                Z_TYPE_P(method_name_out) = IS_STRING;
++                Z_STRVAL_P(method_name_out) = estrdup(method_name);
++                Z_STRLEN_P(method_name_out) = strlen(Z_STRVAL_P(method_name_out));
++            } else if (retval) {
++                zval_ptr_dtor(&retval);
++                retval = NULL;
++            }
+          }
+       }
+ 
diff --git a/php4-CVE-2010-1128.patch b/php4-CVE-2010-1128.patch
new file mode 100644
index 0000000..fb3f16f
--- /dev/null
+++ b/php4-CVE-2010-1128.patch
@@ -0,0 +1,28 @@
+CVE-2010-1128: LCG seed uses too little entropy, session ids are predictable.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/standard/lcg.c b/ext/standard/lcg.c
+index ec39ab2..e80e8c5 100644
+--- a/ext/standard/lcg.c
++++ b/ext/standard/lcg.c
+@@ -78,7 +78,7 @@ static void lcg_seed(TSRMLS_D)
+ 	struct timeval tv;
+ 
+ 	if (gettimeofday(&tv, NULL) == 0) {
+-		LCG(s1) = tv.tv_sec ^ (~tv.tv_usec);
++		LCG(s1) = tv.tv_sec ^ (tv.tv_usec<<11);
+ 	} else {
+ 		LCG(s1) = 1;
+ 	}
+@@ -88,6 +88,11 @@ static void lcg_seed(TSRMLS_D)
+ 	LCG(s2) = (long) getpid();
+ #endif
+ 
++	/* Add entropy to s2 by calling gettimeofday() again */
++	if (gettimeofday(&tv, NULL) == 0) {
++		LCG(s2) ^= (tv.tv_usec<<11);
++	}
++
+ 	LCG(seeded) = 1;
+ }
+ 
diff --git a/php4-CVE-2010-1917.patch b/php4-CVE-2010-1917.patch
new file mode 100644
index 0000000..f2a1789
--- /dev/null
+++ b/php4-CVE-2010-1917.patch
@@ -0,0 +1,18 @@
+CVE-2010-1917: fnmatch() exhausts the stack on an overlong pattern.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm), upstream http://svn.php.net/viewvc?view=revision&revision=298881
+
+diff --git a/ext/standard/file.c b/ext/standard/file.c
+index 287d024..37e5a24 100644
+--- a/ext/standard/file.c
++++ b/ext/standard/file.c
+@@ -2684,6 +2684,10 @@ PHP_FUNCTION(fnmatch)
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename exceeds the maximum allowed length of %d characters", MAXPATHLEN);
+ 		RETURN_FALSE;
+ 	}
++	if (pattern_len >= MAXPATHLEN) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
++		RETURN_FALSE;
++	}
+ 
+ 	RETURN_BOOL( ! fnmatch( pattern, filename, flags ));
+ }
diff --git a/php4-CVE-2010-2531.patch b/php4-CVE-2010-2531.patch
new file mode 100644
index 0000000..7d60fd6
--- /dev/null
+++ b/php4-CVE-2010-2531.patch
@@ -0,0 +1,218 @@
+CVE-2010-2531: var_export() with return=true uses output buffering, a fatal error inside it flushes the partial dump to the client. NUL byte formatting is left unchanged.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h
+index 6d67611..659856f 100644
+--- a/ext/standard/php_var.h
++++ b/ext/standard/php_var.h
+@@ -34,6 +34,7 @@ PHP_FUNCTION(memory_get_usage);
+ 
+ PHPAPI void php_var_dump(zval **struc, int level TSRMLS_DC);
+ PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC);
++PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC);
+ PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC);
+ 
+ /* typdef HashTable php_serialize_data_t; */
+diff --git a/ext/standard/var.c b/ext/standard/var.c
+index 529c0f5..1730755 100644
+--- a/ext/standard/var.c
++++ b/ext/standard/var.c
+@@ -256,46 +256,64 @@ PHP_FUNCTION(debug_zval_dump)
+ 
+ 
+ /* {{{ php_var_export */
++#define buffer_append_spaces(buf, num_spaces) \
++	do { \
++		char *tmp_spaces; \
++		int tmp_spaces_len; \
++		tmp_spaces_len = spprintf(&tmp_spaces, 0,"%*c", num_spaces, ' '); \
++		smart_str_appendl(buf, tmp_spaces, tmp_spaces_len); \
++		efree(tmp_spaces); \
++	} while(0);
+ 
+ static int php_array_element_export(zval **zv, int num_args, va_list args, zend_hash_key *hash_key)
+ {
+ 	int level;
++	smart_str *buf;
+ 	TSRMLS_FETCH();
+ 
+ 	level = va_arg(args, int);
++	buf = va_arg(args, smart_str *);
+ 
+ 	if (hash_key->nKeyLength==0) { /* numeric key */
+-		php_printf("%*c%ld => ", level + 1, ' ', hash_key->h);
++		buffer_append_spaces(buf, level + 1);
++		smart_str_append_long(buf, hash_key->h);
++		smart_str_appendl(buf, " => ", 4);
+ 	} else { /* string key */
+ 		char *key;
+ 		int key_len;
+ 		key = php_addcslashes(hash_key->arKey, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC);
+-		php_printf("%*c'", level + 1, ' ');
+-		PHPWRITE(key, key_len);
+-		php_printf("' => ");
++		buffer_append_spaces(buf, level + 1);
++		smart_str_appendc(buf, '\'');
++		smart_str_appendl(buf, key, key_len);
++		smart_str_appendl(buf, "' => ", 5);
+ 		efree(key);
+ 	}
+-	php_var_export(zv, level + 2 TSRMLS_CC);
+-	PUTS (",\n");
++	php_var_export_ex(zv, level + 2, buf TSRMLS_CC);
++	smart_str_appendl(buf, ",\n", 2);
+ 	return 0;
+ }
+ 
+ static int php_object_element_export(zval **zv, int num_args, va_list args, zend_hash_key *hash_key)
+ {
+ 	int level;
++	smart_str *buf;
+ 	TSRMLS_FETCH();
+ 
+ 	level = va_arg(args, int);
++	buf = va_arg(args, smart_str *);
+ 
+ 	if (hash_key->nKeyLength != 0) {
+-		php_printf("%*cvar $%s = ", level + 1, ' ', hash_key->arKey);
+-		php_var_export(zv, level + 2 TSRMLS_CC);
+-		PUTS (";\n");
++		buffer_append_spaces(buf, level + 1);
++		smart_str_appendl(buf, "var $", 5);
++		smart_str_appends(buf, hash_key->arKey);
++		smart_str_appendl(buf, " = ", 3);
++		php_var_export_ex(zv, level + 2, buf TSRMLS_CC);
++		smart_str_appendl(buf, ";\n", 2);
+ 	}
+ 	return 0;
+ }
+ 
+-PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC)
++PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC)
+ {
+ 	HashTable *myht;
+ 	char*     tmp_str;
+@@ -303,56 +321,76 @@ PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC)
+ 
+ 	switch (Z_TYPE_PP(struc)) {
+ 	case IS_BOOL:
+-		php_printf("%s", Z_LVAL_PP(struc) ? "true" : "false");
++		if (Z_LVAL_PP(struc)) {
++			smart_str_appendl(buf, "true", 4);
++		} else {
++			smart_str_appendl(buf, "false", 5);
++		}
+ 		break;
+ 	case IS_NULL:
+-		php_printf("NULL");
++		smart_str_appendl(buf, "NULL", 4);
+ 		break;
+ 	case IS_LONG:
+-		php_printf("%ld", Z_LVAL_PP(struc));
++		smart_str_append_long(buf, Z_LVAL_PP(struc));
+ 		break;
+ 	case IS_DOUBLE:
+-		php_printf("%.*G", (int) EG(precision), Z_DVAL_PP(struc));
++		tmp_len = spprintf(&tmp_str, 0, "%.*G", (int) EG(precision), Z_DVAL_PP(struc));
++		smart_str_appendl(buf, tmp_str, tmp_len);
++		efree(tmp_str);
+ 		break;
+ 	case IS_STRING:
+ 		tmp_str = php_addcslashes(Z_STRVAL_PP(struc), Z_STRLEN_PP(struc), &tmp_len, 0, "'\\", 2 TSRMLS_CC);
+-		PUTS ("'");
+-		PHPWRITE(tmp_str, tmp_len);
+-		PUTS ("'");
++		smart_str_appendc(buf, '\'');
++		smart_str_appendl(buf, tmp_str, tmp_len);
++		smart_str_appendc(buf, '\'');
+ 		efree (tmp_str);
+ 		break;
+ 	case IS_ARRAY:
+ 		myht = Z_ARRVAL_PP(struc);
+ 		if (level > 1) {
+-			php_printf("\n%*c", level - 1, ' ');
++			smart_str_appendc(buf, '\n');
++			buffer_append_spaces(buf, level - 1);
+ 		}
+-		PUTS ("array (\n");
+-		zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_array_element_export, 1, level);
++		smart_str_appendl(buf, "array (\n", 8);
++		zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_array_element_export, 2, level, buf);
+ 		if (level > 1) {
+-			php_printf("%*c", level - 1, ' ');
++			buffer_append_spaces(buf, level - 1);
+ 		}
+-		PUTS(")");
++		smart_str_appendc(buf, ')');
+ 		break;
+ 	case IS_OBJECT:
+ 		myht = Z_OBJPROP_PP(struc);
+ 		if (level > 1) {
+-			php_printf("\n%*c", level - 1, ' ');
++			smart_str_appendc(buf, '\n');
++			buffer_append_spaces(buf, level - 1);
+ 		}
+-		php_printf ("class %s {\n", Z_OBJCE_PP(struc)->name);
++		smart_str_appendl(buf, "class ", 6);
++		smart_str_appends(buf, Z_OBJCE_PP(struc)->name);
++		smart_str_appendl(buf, " {\n", 3);
+ 		if (myht) {
+-			zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_object_element_export, 1, level);
++			zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_object_element_export, 2, level, buf);
+ 		}
+ 		if (level > 1) {
+-			php_printf("%*c", level - 1, ' ');
++			buffer_append_spaces(buf, level - 1);
+ 		}
+-		PUTS("}");
++		smart_str_appendc(buf, '}');
+ 		break;
+ 	default:
+-		PUTS ("NULL");
++		smart_str_appendl(buf, "NULL", 4);
+ 		break;
+ 	}
+ }
+ 
++PHPAPI void php_var_export(zval **struc, int level TSRMLS_DC)
++{
++	smart_str buf = {0};
++
++	php_var_export_ex(struc, level, &buf TSRMLS_CC);
++	smart_str_0(&buf);
++	PHPWRITE(buf.c, buf.len);
++	smart_str_free(&buf);
++}
++
+ /* }}} */
+ 
+ 
+@@ -362,21 +400,21 @@ PHP_FUNCTION(var_export)
+ {
+ 	zval *var;
+ 	zend_bool return_output = 0;
++	smart_str buf = {0};
+ 	
+ 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &var, &return_output) == FAILURE) {
+ 		return;
+ 	}
+ 	
+-	if (return_output) {
+-		php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC);
+-	}
+-	
+-	php_var_export(&var, 1 TSRMLS_CC);
++	php_var_export_ex(&var, 1, &buf TSRMLS_CC);
++	smart_str_0(&buf);
+ 
+ 	if (return_output) {
+-		php_ob_get_buffer (return_value TSRMLS_CC);
+-		php_end_ob_buffer (0, 0 TSRMLS_CC);
++		RETVAL_STRINGL(buf.c, buf.len, 1);
++	} else {
++		PHPWRITE(buf.c, buf.len);
+ 	}
++	smart_str_free(&buf);
+ }
+ /* }}} */
+ 
diff --git a/php4-CVE-2010-3065.patch b/php4-CVE-2010-3065.patch
new file mode 100644
index 0000000..e8833fa
--- /dev/null
+++ b/php4-CVE-2010-3065.patch
@@ -0,0 +1,16 @@
+CVE-2010-3065: session php serializer accepts '!' in variable names, allowing injection of arbitrary session data.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm), upstream http://svn.php.net/viewvc?view=revision&revision=298608
+
+diff --git a/ext/session/session.c b/ext/session/session.c
+index 29f3e63..bc68727 100644
+--- a/ext/session/session.c
++++ b/ext/session/session.c
+@@ -503,7 +503,7 @@ PS_SERIALIZER_ENCODE_FUNC(php)
+ 
+ 	PS_ENCODE_LOOP(
+ 			smart_str_appendl(&buf, key, key_length);
+-			if (memchr(key, PS_DELIMITER, key_length)) {
++			if (memchr(key, PS_DELIMITER, key_length) || memchr(key, PS_UNDEF_MARKER, key_length)) {
+ 				PHP_VAR_SERIALIZE_DESTROY(var_hash);
+ 				smart_str_free(&buf);				
+ 				return FAILURE;
diff --git a/php4-CVE-2010-3870.patch b/php4-CVE-2010-3870.patch
new file mode 100644
index 0000000..2a04611
--- /dev/null
+++ b/php4-CVE-2010-3870.patch
@@ -0,0 +1,153 @@
+CVE-2010-3870: utf8_decode() swallows bytes after an invalid UTF-8 lead byte, which defeats XSS filtering.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm), upstream http://svn.php.net/viewvc?view=revision&revision=305055
+
+diff --git a/ext/xml/xml.c b/ext/xml/xml.c
+index feb588f..ca0d0f2 100644
+--- a/ext/xml/xml.c
++++ b/ext/xml/xml.c
+@@ -505,10 +505,111 @@ static XML_Char *xml_utf8_encode(const char *s, int len, int *newlen, const XML_
+ }
+ /* }}} */
+ 
++/* copied from trunk's implementation of get_next_char in ext/standard/html.c */
++#define MB_FAILURE(pos, advance) do { \
++	*cursor = pos + (advance); \
++	*status = FAILURE; \
++	return 0; \
++} while (0)
++
++#define CHECK_LEN(pos, chars_need) ((str_len - (pos)) >= (chars_need))
++#define utf8_lead(c)  ((c) < 0x80 || ((c) >= 0xC2 && (c) <= 0xF4))
++#define utf8_trail(c) ((c) >= 0x80 && (c) <= 0xBF)
++
++/* {{{ php_next_utf8_char
++ */
++static inline unsigned int php_next_utf8_char(
++		const unsigned char *str,
++		size_t str_len,
++		size_t *cursor,
++		int *status)
++{
++	size_t pos = *cursor;
++	unsigned int this_char = 0;
++	unsigned char c;
++
++	*status = SUCCESS;
++
++	if (!CHECK_LEN(pos, 1))
++		MB_FAILURE(pos, 1);
++
++	/* We'll follow strategy 2. from section 3.6.1 of UTR #36:
++		* "In a reported illegal byte sequence, do not include any
++		*  non-initial byte that encodes a valid character or is a leading
++		*  byte for a valid sequence. */
++	c = str[pos];
++	if (c < 0x80) {
++		this_char = c;
++		pos++;
++	} else if (c < 0xc2) {
++		MB_FAILURE(pos, 1);
++	} else if (c < 0xe0) {
++		if (!CHECK_LEN(pos, 2))
++			MB_FAILURE(pos, 1);
++
++		if (!utf8_trail(str[pos + 1])) {
++			MB_FAILURE(pos, utf8_lead(str[pos + 1]) ? 1 : 2);
++		}
++		this_char = ((c & 0x1f) << 6) | (str[pos + 1] & 0x3f);
++		if (this_char < 0x80) { /* non-shortest form */
++			MB_FAILURE(pos, 2);
++		}
++		pos += 2;
++	} else if (c < 0xf0) {
++		size_t avail = str_len - pos;
++
++		if (avail < 3 ||
++				!utf8_trail(str[pos + 1]) || !utf8_trail(str[pos + 2])) {
++			if (avail < 2 || utf8_lead(str[pos + 1]))
++				MB_FAILURE(pos, 1);
++			else if (avail < 3 || utf8_lead(str[pos + 2]))
++				MB_FAILURE(pos, 2);
++			else
++				MB_FAILURE(pos, 3);
++		}
++
++		this_char = ((c & 0x0f) << 12) | ((str[pos + 1] & 0x3f) << 6) | (str[pos + 2] & 0x3f);
++		if (this_char < 0x800) { /* non-shortest form */
++			MB_FAILURE(pos, 3);
++		} else if (this_char >= 0xd800 && this_char <= 0xdfff) { /* surrogate */
++			MB_FAILURE(pos, 3);
++		}
++		pos += 3;
++	} else if (c < 0xf5) {
++		size_t avail = str_len - pos;
++
++		if (avail < 4 ||
++				!utf8_trail(str[pos + 1]) || !utf8_trail(str[pos + 2]) ||
++				!utf8_trail(str[pos + 3])) {
++			if (avail < 2 || utf8_lead(str[pos + 1]))
++				MB_FAILURE(pos, 1);
++			else if (avail < 3 || utf8_lead(str[pos + 2]))
++				MB_FAILURE(pos, 2);
++			else if (avail < 4 || utf8_lead(str[pos + 3]))
++				MB_FAILURE(pos, 3);
++			else
++				MB_FAILURE(pos, 4);
++		}
++
++		this_char = ((c & 0x07) << 18) | ((str[pos + 1] & 0x3f) << 12) | ((str[pos + 2] & 0x3f) << 6) | (str[pos + 3] & 0x3f);
++		if (this_char < 0x10000 || this_char > 0x10FFFF) { /* non-shortest form or outside range */
++			MB_FAILURE(pos, 4);
++		}
++		pos += 4;
++	} else {
++		MB_FAILURE(pos, 1);
++	}
++
++	*cursor = pos;
++	return this_char;
++}
++/* }}} */
++
++
+ /* {{{ xml_utf8_decode */
+ PHPAPI char *xml_utf8_decode(const XML_Char *s, int len, int *newlen, const XML_Char *encoding)
+ {
+-	int pos = len;
++	size_t pos = 0;
+ 	char *newbuf = emalloc(len + 1);
+ 	unsigned short c;
+ 	char (*decoder)(unsigned short) = NULL;
+@@ -527,24 +628,14 @@ PHPAPI char *xml_utf8_decode(const XML_Char *s, int len, int *newlen, const XML_
+ 		newbuf[*newlen] = '\0';
+ 		return newbuf;
+ 	}
+-	while (pos > 0) {
+-		c = (unsigned char)(*s);
+-		if (c >= 0xf0) { /* four bytes encoded, 21 bits */
+-			c = ((s[0]&7)<<18) | ((s[1]&63)<<12) | ((s[2]&63)<<6) | (s[3]&63);
+-			s += 4;
+-			pos -= 4;
+-		} else if (c >= 0xe0) { /* three bytes encoded, 16 bits */
+-			c = ((s[0]&63)<<12) | ((s[1]&63)<<6) | (s[2]&63);
+-			s += 3;
+-			pos -= 3;
+-		} else if (c >= 0xc0) { /* two bytes encoded, 11 bits */
+-			c = ((s[0]&63)<<6) | (s[1]&63);
+-			s += 2;
+-			pos -= 2;
+-		} else {
+-			s++;
+-			pos--;
+-		}
++
++	while (pos < (size_t)len) {
++		int status = FAILURE;
++		c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status);
++
++		if (status == FAILURE || c > 0xFFU) {
++			c = '?';
++ 		}
+ 		newbuf[*newlen] = decoder ? decoder(c) : c;
+ 		++*newlen;
+ 	}
diff --git a/php4-CVE-2010-4150.patch b/php4-CVE-2010-4150.patch
new file mode 100644
index 0000000..ba35e58
--- /dev/null
+++ b/php4-CVE-2010-4150.patch
@@ -0,0 +1,20 @@
+CVE-2010-4150: imap: imap_open() double free of the stored user and password.
+Upstream https://github.com/php/php-src/commit/2bbcc005c751
+
+diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c
+index 7868167..4885b96 100644
+--- a/ext/imap/php_imap.c
++++ b/ext/imap/php_imap.c
+@@ -732,10 +732,12 @@ static void php_imap_do_open(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+ 
+ 	if (IMAPG(imap_user)) { 
+ 		efree(IMAPG(imap_user));
++		IMAPG(imap_user) = 0;
+ 	}
+ 
+ 	if (IMAPG(imap_password)) { 
+ 		efree(IMAPG(imap_password));
++		IMAPG(imap_password) = 0;
+ 	}
+ 
+ 	/* local filename, need to perform open_basedir and safe_mode checks */
diff --git a/php4-CVE-2011-0708.patch b/php4-CVE-2011-0708.patch
new file mode 100644
index 0000000..627cac6
--- /dev/null
+++ b/php4-CVE-2011-0708.patch
@@ -0,0 +1,56 @@
+CVE-2011-0708: exif: integer overflow in a tag byte count on 32-bit hosts, out of bounds read.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 496ef9c..c31887f 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -40,6 +40,8 @@
+ #include "php.h"
+ #include "ext/standard/file.h"
+ 
++# include <stdint.h>
++
+ #if HAVE_EXIF
+ 
+ /* When EXIF_DEBUG is defined the module generates a lot of debug messages
+@@ -2697,6 +2699,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
+ 	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;
+ 	xp_field_type *tmp_xp;
+ 
+ 	/* Protect against corrupt headers */
+@@ -2717,13 +2720,20 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
+ 		/*return TRUE;*/
+ 	}
+ 
+-	byte_count = components * php_tiff_bytes_per_format[format];
++	if (components < 0) {
++		exif_error_docref("exif_read_data#error_ifd" TSRMLS_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal components(%ld)", tag, exif_get_tagname(tag, tagname, -12, tag_table TSRMLS_CC), components);
++		return FALSE;
++	}
++
++	byte_count_signed = (int64_t)components * php_tiff_bytes_per_format[format];
+ 
+-	if ((ssize_t)byte_count < 0) {
+-		exif_error_docref("exif_read_data#error_ifd" TSRMLS_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal byte_count(%ld)", tag, exif_get_tagname(tag, tagname, -12, tag_table TSRMLS_CC), byte_count);
++	if (byte_count_signed < 0 || (byte_count_signed > INT32_MAX)) {
++		exif_error_docref("exif_read_data#error_ifd" TSRMLS_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal byte_count", tag, exif_get_tagname(tag, tagname, -12, tag_table TSRMLS_CC));
+ 		return FALSE;
+ 	}
+ 
++	byte_count = (size_t)byte_count_signed;
++
+ 	if (byte_count > 4) {
+ 		offset_val = php_ifd_get32u(dir_entry+8, ImageInfo->motorola_intel);
+ 		/* If its bigger than 4 bytes, the dir entry contains an offset. */
+@@ -2787,6 +2797,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
+ #ifdef EXIF_DEBUG
+ 	exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_NOTICE, "process tag(x%04X=%s, at x%04X + x%04X(=%d)): %s%s", tag, exif_get_tagname(tag, tagname, -12, tag_table TSRMLS_CC), offset_val+displacement, byte_count, byte_count, (components>1)&&format!=TAG_FMT_UNDEFINED&&format!=TAG_FMT_STRING?"ARRAY OF ":"", format==TAG_FMT_STRING?(value_ptr?value_ptr:"<no data>"):exif_get_tagformat(format));
+ #endif
++
+ 	if (section_index==SECTION_THUMBNAIL) {
+ 		if (!ImageInfo->Thumbnail.data) {
+ 			switch(tag) {
diff --git a/php4-CVE-2011-1092.patch b/php4-CVE-2011-1092.patch
new file mode 100644
index 0000000..943607c
--- /dev/null
+++ b/php4-CVE-2011-1092.patch
@@ -0,0 +1,21 @@
+CVE-2011-1092: shmop_read(): integer overflow in the start + count check.
+Upstream https://github.com/php/php-src/commit/06e475e53715
+
+diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c
+index 8d200a4..bca9fc2 100644
+--- a/ext/shmop/shmop.c
++++ b/ext/shmop/shmop.c
+@@ -227,12 +227,7 @@ PHP_FUNCTION(shmop_read)
+ 		RETURN_FALSE;
+ 	}
+ 
+-	if (start + count > shmop->size) {
+-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "count is out of range");
+-		RETURN_FALSE;
+-	}
+-
+-	if (count < 0 ){
++	if (count < 0 || count > shmop->size - start) {
+ 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "count is out of range");
+ 		RETURN_FALSE;
+ 	}
diff --git a/php4-CVE-2011-1466.patch b/php4-CVE-2011-1466.patch
new file mode 100644
index 0000000..9f9e1ce
--- /dev/null
+++ b/php4-CVE-2011-1466.patch
@@ -0,0 +1,174 @@
+CVE-2011-1466: calendar: SdnToJulian()/SdnToGregorian()/SdnToJewish() integer overflows, and the result is sprintf()ed into a 16 byte buffer.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm); snprintf() from upstream PHP 5.6 calendar.c, century bound added for 64-bit long
+
+diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c
+index 3d3d11e..72db6e2 100644
+--- a/ext/calendar/calendar.c
++++ b/ext/calendar/calendar.c
+@@ -304,7 +304,7 @@ PHP_FUNCTION(cal_from_jd)
+ 
+ 	calendar->from_jd(jd, &year, &month, &day);
+ 
+-	sprintf(date, "%i/%i/%i", month, day, year);
++	snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
+ 	add_assoc_string(return_value, "date", date, 1);
+ 
+ 	add_assoc_long(return_value, "month", month);
+@@ -335,7 +335,7 @@ PHP_FUNCTION(jdtogregorian)
+ 	}
+ 
+ 	SdnToGregorian(julday, &year, &month, &day);
+-	sprintf(date, "%i/%i/%i", month, day, year);
++	snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
+ 
+ 	RETURN_STRING(date, 1);
+ }
+@@ -368,7 +368,7 @@ PHP_FUNCTION(jdtojulian)
+ 	}
+ 
+ 	SdnToJulian(julday, &year, &month, &day);
+-	sprintf(date, "%i/%i/%i", month, day, year);
++	snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
+ 
+ 	RETURN_STRING(date, 1);
+ }
+@@ -499,7 +499,7 @@ PHP_FUNCTION(jdtojewish)
+ 
+ 	SdnToJewish(julday, &year, &month, &day);
+ 	if (!heb) {
+-		sprintf(date, "%i/%i/%i", month, day, year);
++		snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
+ 		RETURN_STRING(date, 1);
+ 	} else {
+ 		if (year <= 0 || year > 9999) {
+@@ -549,7 +549,7 @@ PHP_FUNCTION(jdtofrench)
+ 	}
+ 
+ 	SdnToFrench(julday, &year, &month, &day);
+-	sprintf(date, "%i/%i/%i", month, day, year);
++	snprintf(date, sizeof(date), "%i/%i/%i", month, day, year);
+ 
+ 	RETURN_STRING(date, 1);
+ }
+diff --git a/ext/calendar/gregor.c b/ext/calendar/gregor.c
+index f489509..8da286f 100644
+--- a/ext/calendar/gregor.c
++++ b/ext/calendar/gregor.c
+@@ -127,6 +127,7 @@
+  **************************************************************************/
+ 
+ #include "sdncal.h"
++#include <limits.h>
+ 
+ #define GREGOR_SDN_OFFSET         32045
+ #define DAYS_PER_5_MONTHS  153
+@@ -146,15 +147,16 @@ void SdnToGregorian(
+ 	long int temp;
+ 	int dayOfYear;
+ 
+-	if (sdn <= 0) {
+-		*pYear = 0;
+-		*pMonth = 0;
+-		*pDay = 0;
+-		return;
++	if (sdn <= 0 ||
++		sdn > (LONG_MAX - 4 * GREGOR_SDN_OFFSET) / 4) {
++		goto fail;
+ 	}
+ 	temp = (sdn + GREGOR_SDN_OFFSET) * 4 - 1;
+ 
+ 	/* Calculate the century (year/100). */
++	if (temp / DAYS_PER_400_YEARS > INT_MAX / 100 - 1) {
++		goto fail;
++	}
+ 	century = temp / DAYS_PER_400_YEARS;
+ 
+ 	/* Calculate the year and day of year (1 <= dayOfYear <= 366). */
+@@ -183,6 +185,12 @@ void SdnToGregorian(
+ 	*pYear = year;
+ 	*pMonth = month;
+ 	*pDay = day;
++	return;
++
++fail:
++	*pYear = 0;
++	*pMonth = 0;
++	*pDay = 0;
+ }
+ 
+ long int GregorianToSdn(
+diff --git a/ext/calendar/jewish.c b/ext/calendar/jewish.c
+index f4dc7c3..1e7a06c 100644
+--- a/ext/calendar/jewish.c
++++ b/ext/calendar/jewish.c
+@@ -272,6 +272,7 @@
+ #define HALAKIM_PER_METONIC_CYCLE (HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7))
+ 
+ #define JEWISH_SDN_OFFSET 347997
++#define JEWISH_SDN_MAX 38245310 /* year 103759, 100000 A.D. */
+ #define NEW_MOON_OF_CREATION 31524
+ 
+ #define SUNDAY    0
+@@ -519,7 +520,7 @@ void SdnToJewish(
+ 	int tishri1After;
+ 	int yearLength;
+ 
+-	if (sdn <= JEWISH_SDN_OFFSET) {
++	if (sdn <= JEWISH_SDN_OFFSET || sdn > JEWISH_SDN_MAX) {
+ 		*pYear = 0;
+ 		*pMonth = 0;
+ 		*pDay = 0;
+diff --git a/ext/calendar/julian.c b/ext/calendar/julian.c
+index 39bcbc7..17e7bcb 100644
+--- a/ext/calendar/julian.c
++++ b/ext/calendar/julian.c
+@@ -146,6 +146,7 @@
+  **************************************************************************/
+ 
+ #include "sdncal.h"
++#include <limits.h>
+ 
+ #define JULIAN_SDN_OFFSET         32083
+ #define DAYS_PER_5_MONTHS  153
+@@ -164,15 +165,22 @@ void SdnToJulian(
+ 	int dayOfYear;
+ 
+ 	if (sdn <= 0) {
+-		*pYear = 0;
+-		*pMonth = 0;
+-		*pDay = 0;
+-		return;
++		goto fail;
+ 	}
+-	temp = (sdn + JULIAN_SDN_OFFSET) * 4 - 1;
++	/* Check for overflow */
++	if (sdn > (LONG_MAX - JULIAN_SDN_OFFSET * 4 + 1) / 4 || sdn < LONG_MIN / 4) {
++		goto fail;
++	}
++	temp = sdn * 4 + (JULIAN_SDN_OFFSET * 4 - 1);
+ 
+ 	/* Calculate the year and day of year (1 <= dayOfYear <= 366). */
+-	year = temp / DAYS_PER_4_YEARS;
++	{
++		long yearl = temp / DAYS_PER_4_YEARS;
++		if (yearl > INT_MAX || yearl < INT_MIN) {
++			goto fail;
++		}
++		year = (int) yearl;
++	}
+ 	dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1;
+ 
+ 	/* Calculate the month and day of month. */
+@@ -196,6 +204,12 @@ void SdnToJulian(
+ 	*pYear = year;
+ 	*pMonth = month;
+ 	*pDay = day;
++	return;
++
++fail:
++	*pYear = 0;
++	*pMonth = 0;
++	*pDay = 0;
+ }
+ 
+ long int JulianToSdn(
diff --git a/php4-CVE-2011-2202.patch b/php4-CVE-2011-2202.patch
new file mode 100644
index 0000000..2cb9bd0
--- /dev/null
+++ b/php4-CVE-2011-2202.patch
@@ -0,0 +1,25 @@
+CVE-2011-2202: rfc1867: an upload filename starting with a (back)slash keeps the path in $_FILES[...]['name'].
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/main/rfc1867.c b/main/rfc1867.c
+index 81b1353..069ce8a 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -1116,7 +1116,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
+ #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
+ filedone:
+ #endif
+-			if (s && s > filename) {
++			if (s && s >= filename) {
+ 				safe_php_register_variable(lbuf, s+1, strlen(s+1), NULL, 0 TSRMLS_CC);
+ 			} else {
+ 				safe_php_register_variable(lbuf, filename, strlen(filename), NULL, 0 TSRMLS_CC);
+@@ -1128,7 +1128,7 @@ filedone:
+ 			} else {
+ 				sprintf(lbuf, "%s[name]", param);
+ 			}
+-			if (s && s > filename) {
++			if (s && s >= filename) {
+ 				register_http_post_files_variable(lbuf, s+1, http_post_files, 0 TSRMLS_CC);
+ 			} else {
+ 				register_http_post_files_variable(lbuf, filename, http_post_files, 0 TSRMLS_CC);
diff --git a/php4-CVE-2011-4566.patch b/php4-CVE-2011-4566.patch
new file mode 100644
index 0000000..db63d54
--- /dev/null
+++ b/php4-CVE-2011-4566.patch
@@ -0,0 +1,23 @@
+CVE-2011-4566: exif: integer overflow in the IFD value offset check on 32-bit hosts.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm)
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index c31887f..53718be 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -2738,13 +2738,13 @@ 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 (offset_val+byte_count > IFDlength || value_ptr < dir_entry) {
++		if (byte_count > IFDlength || offset_val > IFDlength-byte_count || value_ptr < dir_entry) {
+ 			/*
+ 			// 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.
+ 			*/
+-			if (offset_val+byte_count>ImageInfo->FileSize || (ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_II && ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_MM && ImageInfo->FileType!=IMAGE_FILETYPE_JPEG)) {
++			if (byte_count > ImageInfo->FileSize || offset_val>ImageInfo->FileSize-byte_count || (ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_II && ImageInfo->FileType!=IMAGE_FILETYPE_TIFF_MM && ImageInfo->FileType!=IMAGE_FILETYPE_JPEG)) {
+ 				if (value_ptr < dir_entry) {
+ 					/* we can read this if offset_val > 0 */
+ 					/* some files have their values in other parts of the file */
diff --git a/php4-CVE-2011-4885.patch b/php4-CVE-2011-4885.patch
new file mode 100644
index 0000000..635dcf8
--- /dev/null
+++ b/php4-CVE-2011-4885.patch
@@ -0,0 +1,87 @@
+CVE-2011-4885: hash collision DoS via many request variables; adds max_input_vars (default 1000). Includes the CVE-2012-0830 fix for the code execution the first upstream version introduced.
+Port of upstream PHP 5.3.10 main/php_variables.c; RHEL 4 php-4.3.9-CVE-2011-4885 and -CVE-2012-0830 for reference
+
+diff --git a/main/main.c b/main/main.c
+index d5ebd0e..c8f5275 100644
+--- a/main/main.c
++++ b/main/main.c
+@@ -339,6 +339,7 @@ PHP_INI_BEGIN()
+ 	STD_PHP_INI_ENTRY("post_max_size",			"8M",		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateInt,			post_max_size,			sapi_globals_struct,sapi_globals)
+ 	STD_PHP_INI_ENTRY("upload_tmp_dir",			NULL,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	upload_tmp_dir,			php_core_globals,	core_globals)
+ 	STD_PHP_INI_ENTRY("max_input_nesting_level", "500",      PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLongGEZero, max_input_nesting_level,            php_core_globals,   core_globals)
++	STD_PHP_INI_ENTRY("max_input_vars",          "1000",     PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLongGEZero, max_input_vars,                     php_core_globals,   core_globals)
+ 
+ 	STD_PHP_INI_ENTRY("user_dir",				NULL,		PHP_INI_SYSTEM,		OnUpdateString,			user_dir,				php_core_globals,	core_globals)
+ 	STD_PHP_INI_ENTRY("variables_order",		NULL,		PHP_INI_ALL,		OnUpdateStringUnempty,	variables_order,		php_core_globals,	core_globals)
+diff --git a/main/php_globals.h b/main/php_globals.h
+index 9d3b215..501c872 100644
+--- a/main/php_globals.h
++++ b/main/php_globals.h
+@@ -142,6 +142,7 @@ struct _php_core_globals {
+ 	
+ 	long serialize_precision;
+ 	long max_input_nesting_level;
++	long max_input_vars;
+ };
+ 
+ 
+diff --git a/main/php_variables.c b/main/php_variables.c
+index 3f2959f..3c5fcc8 100644
+--- a/main/php_variables.c
++++ b/main/php_variables.c
+@@ -184,9 +184,20 @@ PHPAPI void php_register_variable_ex(char *var, zval *val, pval *track_vars_arra
+ 				}
+ 				if (zend_hash_find(symtable1, escaped_index, index_len+1, (void **) &gpc_element_p)==FAILURE
+ 					|| Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
+-					MAKE_STD_ZVAL(gpc_element);
+-					array_init(gpc_element);
+-					zend_hash_update(symtable1, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
++					if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
++						if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
++							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
++						}
++						MAKE_STD_ZVAL(gpc_element);
++						array_init(gpc_element);
++						zend_hash_update(symtable1, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
++					} else {
++						if (index != escaped_index) {
++							efree(escaped_index);
++						}
++						zval_dtor(val);
++						return;
++					}
+ 				}
+ 				if (index!=escaped_index) {
+ 					efree(escaped_index);
+@@ -224,7 +235,14 @@ plain_var:
+ 						break;
+ 					}
+ 					
+-					zend_hash_update(symtable1, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
++					if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
++						if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
++							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
++						}
++						zend_hash_update(symtable1, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
++					} else {
++						zval_ptr_dtor(&gpc_element);
++					}
+ 					efree(escaped_index);
+ 				} else {
+ 					if (PG(http_globals)[TRACK_VARS_COOKIE] && symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) && 
+@@ -233,7 +251,14 @@ plain_var:
+ 						break;
+ 					}
+ 				
+-					zend_hash_update(symtable1, index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
++					if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
++						if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
++							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
++						}
++						zend_hash_update(symtable1, index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
++					} else {
++						zval_ptr_dtor(&gpc_element);
++					}
+ 				}
+ 			}
+ 			break;
diff --git a/php4-CVE-2012-1172.patch b/php4-CVE-2012-1172.patch
new file mode 100644
index 0000000..e593d01
--- /dev/null
+++ b/php4-CVE-2012-1172.patch
@@ -0,0 +1,18 @@
+CVE-2012-1172: rfc1867: an upload field name with an unclosed '[' is accepted.
+Upstream https://github.com/php/php-src/commit/7c3177e5ab41
+
+diff --git a/main/rfc1867.c b/main/rfc1867.c
+index cd848a5..0f2bd85 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -989,6 +989,10 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
+ 					}
+ 					tmp++;				
+ 				}
++				/* Brackets should always be closed */
++				if (c != 0) {
++					skip_upload = 1;
++				}
+ 			}
+ 
+ 			total_bytes = cancel_upload = 0;
diff --git a/php4-CVE-2013-4113.patch b/php4-CVE-2013-4113.patch
new file mode 100644
index 0000000..7614ed7
--- /dev/null
+++ b/php4-CVE-2013-4113.patch
@@ -0,0 +1,160 @@
+CVE-2013-4113: xml_parse_into_struct() corrupts the heap for documents nested deeper than XML_MAXLEVEL.
+Backport by Red Hat from RHEL 4 php-4.3.9-3.37 (Oracle Linux 4 php-4.3.9-3.37.0.1.el4.src.rpm), upstream https://github.com/php/php-src/commit/7d163e8a0880ae8af2dd869071393e5dc07ef271
+
+diff --git a/ext/xml/tests/bug65236.phpt b/ext/xml/tests/bug65236.phpt
+new file mode 100644
+index 0000000..67b26d6
+--- /dev/null
++++ b/ext/xml/tests/bug65236.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++Bug #65236 (heap corruption in xml parser)
++--SKIPIF--
++<?php
++require_once("skipif.inc");
++?>
++--FILE--
++<?php
++xml_parse_into_struct(xml_parser_create_ns(), str_repeat("<blah>", 1000), $a);
++
++echo "Done\n";
++?>
++--EXPECTF--
++Warning: xml_parse_into_struct(): Maximum depth exceeded - Results truncated in %s on line %d
++Done
+diff --git a/ext/xml/xml.c b/ext/xml/xml.c
+index ca0d0f2..2650554 100644
+--- a/ext/xml/xml.c
++++ b/ext/xml/xml.c
+@@ -298,7 +298,7 @@ static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+ 	}
+ 	if (parser->ltags) {
+ 		int inx;
+-		for (inx = 0; inx < parser->level; inx++)
++		for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)
+ 			efree(parser->ltags[ inx ]);
+ 		efree(parser->ltags);
+ 	}
+@@ -756,46 +756,51 @@ void _xml_startElementHandler(void *userData, const char *name, const char **att
+ 		} 
+ 
+ 		if (parser->data) {
+-			zval *tag, *atr;
+-			int atcnt = 0;
++			if (parser->level <= XML_MAXLEVEL)  {
++				zval *tag, *atr;
++				int atcnt = 0;
+ 
+-			MAKE_STD_ZVAL(tag);
+-			MAKE_STD_ZVAL(atr);
++				MAKE_STD_ZVAL(tag);
++				MAKE_STD_ZVAL(atr);
+ 
+-			array_init(tag);
+-			array_init(atr);
++				array_init(tag);
++				array_init(atr);
+ 
+-			_xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
++				_xml_add_to_info(parser,((char *) tag_name) + parser->toffset);
+ 
+-			add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
+-			add_assoc_string(tag,"type","open",1);
+-			add_assoc_long(tag,"level",parser->level);
++				add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */
++				add_assoc_string(tag,"type","open",1);
++				add_assoc_long(tag,"level",parser->level);
+ 
+-			parser->ltags[parser->level-1] = estrdup(tag_name);
+-			parser->lastwasopen = 1;
++				parser->ltags[parser->level-1] = estrdup(tag_name);
++				parser->lastwasopen = 1;
+ 
+-			attributes = attrs;
++				attributes = attrs;
+ 
+-			while (attributes && *attributes) {
+-				att = _xml_decode_tag(parser, attributes[0]);
+-				val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
++				while (attributes && *attributes) {
++					att = _xml_decode_tag(parser, attributes[0]);
++					val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding);
+ 				
+-				add_assoc_stringl(atr,att,val,val_len,0);
++					add_assoc_stringl(atr,att,val,val_len,0);
+ 
+-				atcnt++;
+-				attributes += 2;
++					atcnt++;
++					attributes += 2;
+ 
+-				efree(att);
+-			}
++					efree(att);
++				}
+ 
+-			if (atcnt) {
+-				zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL);
+-			} else {
+-				zval_dtor(atr);
+-				FREE_ZVAL(atr);
+-			}
++				if (atcnt) {
++					zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL);
++				} else {
++					zval_dtor(atr);
++					FREE_ZVAL(atr);
++				}
+ 
+-			zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag);
++				zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag);
++			} else if (parser->level == (XML_MAXLEVEL + 1)) {
++				TSRMLS_FETCH();
++				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated");
++			}
+ 		}
+ 
+ 		efree(tag_name);
+@@ -848,7 +853,7 @@ void _xml_endElementHandler(void *userData, const char *name)
+ 
+ 		efree(tag_name);
+ 
+-		if (parser->ltags) {
++		if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) {
+ 			efree(parser->ltags[parser->level-1]);
+ 		}
+ 
+@@ -914,18 +919,23 @@ void _xml_characterDataHandler(void *userData, const XML_Char *s, int len)
+ 				} else {
+ 					zval *tag;
+ 
+-					MAKE_STD_ZVAL(tag);
+-					
+-					array_init(tag);
+-					
+-					_xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
++					if (parser->level <= XML_MAXLEVEL) {
++						MAKE_STD_ZVAL(tag);
++
++						array_init(tag);
+ 
+-					add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1);
+-					add_assoc_string(tag,"value",decoded_value,0);
+-					add_assoc_string(tag,"type","cdata",1);
+-					add_assoc_long(tag,"level",parser->level);
++						_xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset);
+ 
+-					zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
++						add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1);
++						add_assoc_string(tag,"value",decoded_value,0);
++						add_assoc_string(tag,"type","cdata",1);
++						add_assoc_long(tag,"level",parser->level);
++
++						zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL);
++					} else if (parser->level == (XML_MAXLEVEL + 1)) {
++						TSRMLS_FETCH();
++						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated");
++					}
+ 				}
+ 			} else {
+ 				efree(decoded_value);
diff --git a/php4-CVE-2013-6420.patch b/php4-CVE-2013-6420.patch
new file mode 100644
index 0000000..465fe30
--- /dev/null
+++ b/php4-CVE-2013-6420.patch
@@ -0,0 +1,41 @@
+CVE-2013-6420: openssl: openssl_x509_parse() corrupts memory on a crafted certificate time string.
+Upstream https://github.com/php/php-src/commit/c1224573c773
+
+diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
+index 0ac5643..384b053 100644
+--- a/ext/openssl/openssl.c
++++ b/ext/openssl/openssl.c
+@@ -294,19 +294,29 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC)
+ 	char * thestr;
+ 	long gmadjust = 0;
+ 
+-	if (timestr->length < 13) {
+-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "extension author too lazy to parse %s correctly", timestr->data);
++	if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal ASN1 data type for timestamp");
+ 		return (time_t)-1;
+ 	}
+ 
+-	strbuf = estrdup(timestr->data);
++	if (ASN1_STRING_length(timestr) != strlen((char *)timestr->data)) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal length in timestamp");
++		return (time_t)-1;
++	}
++
++	if (ASN1_STRING_length(timestr) < 13) {
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data);
++		return (time_t)-1;
++	}
++
++	strbuf = estrdup((char *)timestr->data);
+ 
+ 
+ 	memset(&thetime, 0, sizeof(thetime));
+ 
+ 	/* we work backwards so that we can use atoi more easily */
+ 
+-	thestr = strbuf + timestr->length - 3;
++	thestr = strbuf + ASN1_STRING_length(timestr) - 3;
+ 
+ 	thetime.tm_sec = atoi(thestr);
+ 	*thestr = '\0';
diff --git a/php4-CVE-2014-3670.patch b/php4-CVE-2014-3670.patch
new file mode 100644
index 0000000..f675beb
--- /dev/null
+++ b/php4-CVE-2014-3670.patch
@@ -0,0 +1,21 @@
+CVE-2014-3670: exif: heap overflow in exif_thumbnail_extract() when a TIFF tag of type float/double is an array.
+Upstream https://github.com/php/php-src/commit/287c91c1f060
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 53718be..511ebba 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -2314,11 +2314,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;
+ 			}
diff --git a/php4-CVE-2014-4721.patch b/php4-CVE-2014-4721.patch
new file mode 100644
index 0000000..090c3be
--- /dev/null
+++ b/php4-CVE-2014-4721.patch
@@ -0,0 +1,28 @@
+CVE-2014-4721: phpinfo() prints a non-string PHP_SELF/PHP_AUTH_* as a string, information leak.
+Upstream https://github.com/php/php-src/commit/3804c0d00fa6
+
+diff --git a/ext/standard/info.c b/ext/standard/info.c
+index dcce62e..5a5f0c6 100644
+--- a/ext/standard/info.c
++++ b/ext/standard/info.c
+@@ -637,16 +637,16 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
+ 
+ 		php_info_print_table_start();
+ 		php_info_print_table_header(2, "Variable", "Value");
+-		if (zend_hash_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void **) &data) != FAILURE) {
++		if (zend_hash_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) {
+ 			php_info_print_table_row(2, "PHP_SELF", Z_STRVAL_PP(data));
+ 		}
+-		if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE"), (void **) &data) != FAILURE) {
++		if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) {
+ 			php_info_print_table_row(2, "PHP_AUTH_TYPE", Z_STRVAL_PP(data));
+ 		}
+-		if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &data) != FAILURE) {
++		if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) {
+ 			php_info_print_table_row(2, "PHP_AUTH_USER", Z_STRVAL_PP(data));
+ 		}
+-		if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW"), (void **) &data) != FAILURE) {
++		if (zend_hash_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW"), (void **) &data) != FAILURE && Z_TYPE_PP(data) == IS_STRING) {
+ 			php_info_print_table_row(2, "PHP_AUTH_PW", Z_STRVAL_PP(data));
+ 		}
+ 		php_print_gpcse_array("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC);
diff --git a/php4-CVE-2014-5120.patch b/php4-CVE-2014-5120.patch
new file mode 100644
index 0000000..ef5dd13
--- /dev/null
+++ b/php4-CVE-2014-5120.patch
@@ -0,0 +1,55 @@
+CVE-2014-5120: gd: NUL byte in an output or image2wbmp filename truncates the path.
+Upstream https://github.com/php/php-src/commit/706aefb78112
+
+diff --git a/ext/gd/gd.c b/ext/gd/gd.c
+index ab0c5a9..7ed930f 100644
+--- a/ext/gd/gd.c
++++ b/ext/gd/gd.c
+@@ -2015,6 +2015,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
+ 	}
+ 
+ 	if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) {
++		PHP_GD_CHECK_NULL_PATH(file, "Invalid 2nd parameter, filename must not contain null bytes");
+ 		PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
+ 
+ 		fp = VCWD_FOPEN(fn, "wb");
+@@ -4146,6 +4147,9 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
+ 		RETURN_FALSE;
+ 	}
+ 
++	PHP_GD_CHECK_NULL_PATH(f_org, "Invalid origin filename, must not contain null bytes");
++	PHP_GD_CHECK_NULL_PATH(f_dest, "Invalid destination filename, must not contain null bytes");
++
+ 	/* Check origin file */
+ 	PHP_GD_CHECK_OPEN_BASEDIR(fn_org, "Invalid origin filename");
+ 
+diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c
+index 6b41976..1f1bfea 100644
+--- a/ext/gd/gd_ctx.c
++++ b/ext/gd/gd_ctx.c
+@@ -91,6 +91,7 @@ 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_NULL_PATH(file, "Invalid 2nd parameter, filename must not contain null bytes");
+ 		PHP_GD_CHECK_OPEN_BASEDIR(fn, "Invalid filename");
+ 
+ 		fp = VCWD_FOPEN(fn, "wb");
+diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h
+index 89bd5d5..6775675 100644
+--- a/ext/gd/php_gd.h
++++ b/ext/gd/php_gd.h
+@@ -39,6 +39,13 @@
+ 		RETURN_FALSE;                                                                   \
+ 	}
+ 
++/* a NUL inside the name would make the C library open a shorter path */
++#define PHP_GD_CHECK_NULL_PATH(zfile, errormsg)                                         \
++	if (strlen(Z_STRVAL_PP(zfile)) != (size_t) Z_STRLEN_PP(zfile)) {                    \
++		php_error_docref(NULL TSRMLS_CC, E_WARNING, errormsg);                          \
++		RETURN_FALSE;                                                                   \
++	}
++
+ #define PHP_GDIMG_TYPE_GIF      1
+ #define PHP_GDIMG_TYPE_PNG      2
+ #define PHP_GDIMG_TYPE_JPG      3
diff --git a/php4-CVE-2014-8626.patch b/php4-CVE-2014-8626.patch
new file mode 100644
index 0000000..fc6e85c
--- /dev/null
+++ b/php4-CVE-2014-8626.patch
@@ -0,0 +1,86 @@
+CVE-2014-8626: xmlrpc: stack overflow in date_from_ISO8601() on a long date with '-'.
+Upstream https://github.com/php/php-src/commit/c818d0d01341; bounded copy and digit/month checks only, mktime() is kept
+
+diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc.c b/ext/xmlrpc/libxmlrpc/xmlrpc.c
+index 34b41db..0af43ab 100644
+--- a/ext/xmlrpc/libxmlrpc/xmlrpc.c
++++ b/ext/xmlrpc/libxmlrpc/xmlrpc.c
+@@ -153,7 +153,7 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
+    struct tm tm;
+    int n;
+    int i;
+-	char buf[18];
++	char buf[30];
+ 
+ 	if (strchr (text, '-')) {
+ 		char *p = (char *) text, *p2 = buf;
+@@ -161,9 +161,13 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
+ 			if (*p != '-') {
+ 				*p2 = *p;
+ 				p2++;
++				if (p2-buf >= sizeof(buf)) {
++					return -1;
++				}
+ 			}
+ 			p++;
+ 		}
++		*p2 = '\0';
+ 		text = buf;
+ 	}
+ 
+@@ -174,23 +178,31 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
+       return -1;
+    }
+ 
++#define XMLRPC_IS_NUMBER(x) if (x < '0' || x > '9') return -1;
++
+    n = 1000;
+    tm.tm_year = 0;
+    for(i = 0; i < 4; i++) {
++      XMLRPC_IS_NUMBER(text[i])
+       tm.tm_year += (text[i]-'0')*n;
+       n /= 10;
+    }
+    n = 10;
+    tm.tm_mon = 0;
+    for(i = 0; i < 2; i++) {
++      XMLRPC_IS_NUMBER(text[i+4])
+       tm.tm_mon += (text[i+4]-'0')*n;
+       n /= 10;
+    }
+    tm.tm_mon --;
++   if(tm.tm_mon < 0 || tm.tm_mon > 11) {
++      return -1;
++   }
+ 
+    n = 10;
+    tm.tm_mday = 0;
+    for(i = 0; i < 2; i++) {
++      XMLRPC_IS_NUMBER(text[i+6])
+       tm.tm_mday += (text[i+6]-'0')*n;
+       n /= 10;
+    }
+@@ -198,6 +210,7 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
+    n = 10;
+    tm.tm_hour = 0;
+    for(i = 0; i < 2; i++) {
++      XMLRPC_IS_NUMBER(text[i+9])
+       tm.tm_hour += (text[i+9]-'0')*n;
+       n /= 10;
+    }
+@@ -205,6 +218,7 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
+    n = 10;
+    tm.tm_min = 0;
+    for(i = 0; i < 2; i++) {
++      XMLRPC_IS_NUMBER(text[i+12])
+       tm.tm_min += (text[i+12]-'0')*n;
+       n /= 10;
+    }
+@@ -212,6 +226,7 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
+    n = 10;
+    tm.tm_sec = 0;
+    for(i = 0; i < 2; i++) {
++      XMLRPC_IS_NUMBER(text[i+15])
+       tm.tm_sec += (text[i+15]-'0')*n;
+       n /= 10;
+    }
diff --git a/php4-CVE-2014-9709.patch b/php4-CVE-2014-9709.patch
new file mode 100644
index 0000000..e1aa234
--- /dev/null
+++ b/php4-CVE-2014-9709.patch
@@ -0,0 +1,37 @@
+CVE-2014-9709: gd: buffer over-read in the GIF LZW decoder.
+Upstream https://github.com/php/php-src/commit/07b5896a1389 + https://github.com/php/php-src/commit/5fc2fede9c7c
+
+diff --git a/ext/gd/libgd/gd_gif_in.c b/ext/gd/libgd/gd_gif_in.c
+index ee88a2f..f41ec84 100644
+--- a/ext/gd/libgd/gd_gif_in.c
++++ b/ext/gd/libgd/gd_gif_in.c
+@@ -72,8 +72,10 @@ static struct {
+ 
+ #define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
+ 
++#define CSD_BUF_SIZE 280
++
+ typedef struct {
+-	unsigned char    buf[280];
++	unsigned char    buf[CSD_BUF_SIZE];
+ 	int              curbit, lastbit, done, last_byte;
+ } CODE_STATIC_DATA;
+ 
+@@ -398,9 +400,14 @@ GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroD
+ 		scd->lastbit = (2+count)*8 ;
+ 	}
+ 
+-	ret = 0;
+-	for (i = scd->curbit, j = 0; j < code_size; ++i, ++j)
+-		ret |= ((scd->buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
++	if ((scd->curbit + code_size - 1) >= (CSD_BUF_SIZE * 8)) {
++		ret = -1;
++	} else {
++		ret = 0;
++		for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) {
++			ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j;
++		}
++	}
+ 
+ 	scd->curbit += code_size;
+ 	return ret;
diff --git a/php4-CVE-2015-0232.patch b/php4-CVE-2015-0232.patch
new file mode 100644
index 0000000..95bfdfa
--- /dev/null
+++ b/php4-CVE-2015-0232.patch
@@ -0,0 +1,15 @@
+CVE-2015-0232: exif: a zero length XP tag leaves the value pointer uninitialised, it is later read and freed.
+Upstream https://github.com/php/php-src/commit/2fc178cf448d; PHP 4 hits it in the non-mbstring path
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 73e3017..79b0a1d 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -2607,6 +2607,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
+ static int exif_process_unicode(image_info_type *ImageInfo, xp_field_type *xp_field, int tag, char *szValuePtr, int ByteCount TSRMLS_DC)
+ {
+ 	xp_field->tag = tag;	
++	xp_field->value = NULL;
+ 
+ 	/* Copy the comment */
+ #if EXIF_USE_MBSTRING
diff --git a/php4-CVE-2015-2305.patch b/php4-CVE-2015-2305.patch
new file mode 100644
index 0000000..f44491a
--- /dev/null
+++ b/php4-CVE-2015-2305.patch
@@ -0,0 +1,24 @@
+CVE-2015-2305: regex: integer overflow in regcomp() on 32-bit hosts.
+Upstream https://github.com/php/php-src/commit/fb04dcf6dbb4
+
+diff --git a/regex/regcomp.c b/regex/regcomp.c
+index ec034d4..485d46e 100644
+--- a/regex/regcomp.c
++++ b/regex/regcomp.c
+@@ -117,7 +117,15 @@ int cflags;
+ 							(NC-1)*sizeof(cat_t));
+ 	if (g == NULL)
+ 		return(REG_ESPACE);
+-	p->ssize = len/(size_t)2*(size_t)3 + (size_t)1;	/* ugh */
++	{
++		/* Patched for CERT Vulnerability Note VU#695940, Feb 2015. */
++		size_t new_ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
++		if (new_ssize < len || new_ssize > LONG_MAX / sizeof(sop)) {
++			free((char *) g);
++			return REG_INVARG;
++		}
++		p->ssize = new_ssize;
++	}
+ 	p->strip = (sop *)malloc(p->ssize * sizeof(sop));
+ 	p->slen = 0;
+ 	if (p->strip == NULL) {
diff --git a/php4-CVE-2015-2348.patch b/php4-CVE-2015-2348.patch
new file mode 100644
index 0000000..e63c173
--- /dev/null
+++ b/php4-CVE-2015-2348.patch
@@ -0,0 +1,18 @@
+CVE-2015-2348: move_uploaded_file(): NUL byte in the destination truncates the path.
+Upstream https://github.com/php/php-src/commit/1291d6bbee93
+
+diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
+index 31191b6..55bdd17 100644
+--- a/ext/standard/basic_functions.c
++++ b/ext/standard/basic_functions.c
+@@ -2853,6 +2853,10 @@ PHP_FUNCTION(move_uploaded_file)
+ 	convert_to_string_ex(path);
+ 	convert_to_string_ex(new_path);
+ 
++	if (strlen(Z_STRVAL_PP(new_path)) != (size_t) Z_STRLEN_PP(new_path)) {
++		RETURN_FALSE;
++	}
++
+ 	if (!zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1)) {
+ 		RETURN_FALSE;
+ 	}
diff --git a/php4-CVE-2015-2787.patch b/php4-CVE-2015-2787.patch
new file mode 100644
index 0000000..51b639d
--- /dev/null
+++ b/php4-CVE-2015-2787.patch
@@ -0,0 +1,59 @@
+CVE-2015-2787: unserialize(): a property freed by __wakeup() is reached by a later R:, use after free; also a NULL dereference for arrays used as keys.
+Upstream https://github.com/php/php-src/commit/13f1c276ab72 + https://github.com/php/php-src/commit/646572d6d384
+
+diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
+index f180205..834a6f8 100644
+--- a/ext/standard/var_unserializer.c
++++ b/ext/standard/var_unserializer.c
+@@ -57,7 +57,13 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
+ 
+ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
+ {
+-	var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
++	var_entries *var_hash, *prev = NULL;
++
++	/* array keys are unserialized without var_hash */
++	if (!var_hashx) {
++		return;
++	}
++	var_hash = var_hashx->first_dtor;
+ 
+ 	while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
+ 		prev = var_hash;
+@@ -274,6 +280,8 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
+ 				zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
+ 				break;
+ 		}
++		/* __wakeup() may drop the property, keep it for later R: references */
++		var_push_dtor(var_hash, &data);
+ 		
+ 		zval_dtor(key);
+ 		FREE_ZVAL(key);
+diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
+index 501cd80..f56cff0 100644
+--- a/ext/standard/var_unserializer.re
++++ b/ext/standard/var_unserializer.re
+@@ -56,7 +56,13 @@ static inline void var_push(php_unserialize_data_t *var_hashx, zval **rval)
+ 
+ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
+ {
+-	var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
++	var_entries *var_hash, *prev = NULL;
++
++	/* array keys are unserialized without var_hash */
++	if (!var_hashx) {
++		return;
++	}
++	var_hash = var_hashx->first_dtor;
+ 
+ 	while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
+ 		prev = var_hash;
+@@ -279,6 +285,8 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
+ 				zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
+ 				break;
+ 		}
++		/* __wakeup() may drop the property, keep it for later R: references */
++		var_push_dtor(var_hash, &data);
+ 		
+ 		zval_dtor(key);
+ 		FREE_ZVAL(key);
diff --git a/php4-CVE-2015-4022.patch b/php4-CVE-2015-4022.patch
new file mode 100644
index 0000000..fce2e9c
--- /dev/null
+++ b/php4-CVE-2015-4022.patch
@@ -0,0 +1,45 @@
+CVE-2015-4022: ftp: integer overflow in ftp_genlist() on a huge listing, heap overflow (CVE-2015-4022, CVE-2015-4643).
+Upstream https://github.com/php/php-src/commit/ac2832935435 + https://github.com/php/php-src/commit/0765623d6991
+
+diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
+index 5c91872..7aae4e4 100644
+--- a/ext/ftp/ftp.c
++++ b/ext/ftp/ftp.c
+@@ -1486,8 +1486,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;
+@@ -1524,7 +1524,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 == (size_t)-1 || rcvd > ((size_t)(-1))-size)
+ 			goto bail;
+ 
+ 		php_stream_write(tmpstream, data->buf, rcvd);
+@@ -1533,8 +1533,6 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
+ 		for (ptr = data->buf; rcvd; rcvd--, ptr++) {
+ 			if (*ptr == '\n' && lastch == '\r')
+ 				lines++;
+-			else
+-				size++;
+ 			lastch = *ptr;
+ 		}
+ 	}
+@@ -1543,7 +1541,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC)
+ 
+ 	php_stream_rewind(tmpstream);
+ 
+-	ret = emalloc((lines + 1) * sizeof(char**) + size * sizeof(char*));
++	ret = safe_emalloc((lines + 1), sizeof(char*), size);
+ 
+ 	entry = ret;
+ 	text = (char*) (ret + lines + 1);
diff --git a/php4-CVE-2015-4024.patch b/php4-CVE-2015-4024.patch
new file mode 100644
index 0000000..04202e6
--- /dev/null
+++ b/php4-CVE-2015-4024.patch
@@ -0,0 +1,88 @@
+CVE-2015-4024: rfc1867: quadratic copying of multi-line part headers, CPU DoS.
+Upstream https://github.com/php/php-src/commit/4605d536d23b
+
+diff --git a/main/rfc1867.c b/main/rfc1867.c
+index 069ce8a..6b4cacf 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -32,6 +32,7 @@
+ #include "php_variables.h"
+ #include "rfc1867.h"
+ #include "php_ini.h"
++#include "ext/standard/php_smart_str.h"
+ 
+ #undef DEBUG_FILE_UPLOAD
+ 
+@@ -467,8 +468,9 @@ static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC)
+ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC)
+ {
+ 	char *line;
+-	mime_header_entry prev_entry, entry;
+-	int prev_len, cur_len;
++	mime_header_entry entry;
++	smart_str buf_value = {0};
++	char *key = NULL;
+ 	
+ 	/* didn't find boundary, abort */
+ 	if (!find_boundary(self, self->boundary TSRMLS_CC)) {
+@@ -481,7 +483,6 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T
+ 	{
+ 		/* add header to table */
+ 		
+-		char *key = line;
+ 		char *value = NULL;
+ 		
+ 		/* space in the beginning means same header */
+@@ -490,31 +491,33 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T
+ 		}
+ 
+ 		if (value) {
+-			*value = 0;
+-			do { value++; } while(isspace(*value));
+-
+-			entry.value = estrdup(value);
+-			entry.key = estrdup(key);
+-
+-		} else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */
+-
+-			prev_len = strlen(prev_entry.value);
+-			cur_len = strlen(line);
++			if (buf_value.c && key) {
++				/* new entry, add the old one to the list */
++				smart_str_0(&buf_value);
++				entry.key = key;
++				entry.value = buf_value.c;
++				zend_llist_add_element(header, &entry);
++				buf_value.c = NULL;
++				key = NULL;
++			}
+ 
+-			entry.value = emalloc(prev_len + cur_len + 1);
+-			memcpy(entry.value, prev_entry.value, prev_len);
+-			memcpy(entry.value + prev_len, line, cur_len);
+-			entry.value[cur_len + prev_len] = '\0';
++			*value = '\0';
++			do { value++; } while(isspace(*value));
+ 
+-			entry.key = estrdup(prev_entry.key);
+-			
+-			zend_llist_remove_tail(header);
++			key = estrdup(line);
++			smart_str_appends(&buf_value, value);
++		} else if (buf_value.c) { /* If no ':' on the line, add to previous line */
++			smart_str_appends(&buf_value, line);
+ 		} else {
+ 			continue;
+ 		}
+-
++	}
++	if (buf_value.c && key) {
++		/* add the last one to the list */
++		smart_str_0(&buf_value);
++		entry.key = key;
++		entry.value = buf_value.c;
+ 		zend_llist_add_element(header, &entry);
+-		prev_entry = entry;
+ 	}
+ 
+ 	return 1;
diff --git a/php4-CVE-2015-4598.patch b/php4-CVE-2015-4598.patch
new file mode 100644
index 0000000..d78aa2c
--- /dev/null
+++ b/php4-CVE-2015-4598.patch
@@ -0,0 +1,16 @@
+CVE-2015-4598: gd: NUL byte in the imagepsloadfont() filename truncates the path.
+Upstream https://github.com/php/php-src/commit/f7d7befae8bc
+
+diff --git a/ext/gd/gd.c b/ext/gd/gd.c
+index 7ed930f..14bad70 100644
+--- a/ext/gd/gd.c
++++ b/ext/gd/gd.c
+@@ -3577,6 +3577,8 @@ PHP_FUNCTION(imagepsloadfont)
+ 	}
+ #endif
+ 
++	PHP_GD_CHECK_NULL_PATH(file, "Invalid font filename, must not contain null bytes");
++
+ 	f_ind = T1_AddFont(Z_STRVAL_PP(file));
+ 
+ 	if (f_ind < 0) {
diff --git a/php4-CVE-2015-6834.patch b/php4-CVE-2015-6834.patch
new file mode 100644
index 0000000..8660351
--- /dev/null
+++ b/php4-CVE-2015-6834.patch
@@ -0,0 +1,157 @@
+CVE-2015-6834: unserialize(): r:/R: free a value still reachable through the var hash, use after free.
+Upstream https://github.com/php/php-src/commit/e8429400d40e + https://github.com/php/php-src/commit/7c3120393558
+
+diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
+index 1d36d18..f180205 100644
+--- a/ext/standard/var_unserializer.c
++++ b/ext/standard/var_unserializer.c
+@@ -79,6 +79,29 @@ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
+ 	var_hash->data[var_hash->used_slots++] = *rval;
+ }
+ 
++static inline void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval)
++{
++	var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
++
++	while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
++		prev = var_hash;
++		var_hash = var_hash->next;
++	}
++
++	if (!var_hash) {
++		var_hash = emalloc(sizeof(var_entries));
++		var_hash->used_slots = 0;
++		var_hash->next = 0;
++
++		if (!var_hashx->first_dtor)
++			var_hashx->first_dtor = var_hash;
++		else
++			prev->next = var_hash;
++	}
++
++	var_hash->data[var_hash->used_slots++] = *rval;
++}
++
+ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
+ {
+ 	long i;
+@@ -480,6 +503,8 @@ yy19:
+ 	zval **args[1];
+ 	zval *arg_func_name;
+ 	
++	if (!var_hash) return 0;
++
+ 	INIT_PZVAL(*rval);
+ 	len2 = len = parse_uiv(start + 2);
+ 	maxlen = max - YYCURSOR;
+@@ -581,6 +606,7 @@ yy26:
+ 		if(yych != '"') goto yy17;
+ 		++YYCURSOR;
+ 		{
++	if (!var_hash) return 0;
+ 
+ 	INIT_PZVAL(*rval);
+ 	
+@@ -611,6 +637,7 @@ yy33:
+ 	long elements = parse_iv(start + 2);
+ 	/* use iv() not uiv() in order to check data range */
+ 	*p = YYCURSOR;
++	if (!var_hash) return 0;
+ 
+ 	if (elements < 0) {
+ 		return 0;
+@@ -937,7 +964,7 @@ yy83:
+ 	}
+ 
+ 	if (*rval != NULL) {
+-	zval_ptr_dtor(rval);
++		var_push_dtor_no_addref(var_hash, rval);
+ 	}
+ 	*rval = *rval_ref;
+ 	(*rval)->refcount++;
+@@ -983,7 +1010,7 @@ yy89:
+ 	}
+ 
+ 	if (*rval != NULL) {
+-	zval_ptr_dtor(rval);
++		var_push_dtor_no_addref(var_hash, rval);
+ 	}
+ 	*rval = *rval_ref;
+ 	(*rval)->refcount++;
+diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
+index 3683646..501cd80 100644
+--- a/ext/standard/var_unserializer.re
++++ b/ext/standard/var_unserializer.re
+@@ -78,6 +78,29 @@ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
+ 	var_hash->data[var_hash->used_slots++] = *rval;
+ }
+ 
++static inline void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval)
++{
++	var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
++
++	while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
++		prev = var_hash;
++		var_hash = var_hash->next;
++	}
++
++	if (!var_hash) {
++		var_hash = emalloc(sizeof(var_entries));
++		var_hash->used_slots = 0;
++		var_hash->next = 0;
++
++		if (!var_hashx->first_dtor)
++			var_hashx->first_dtor = var_hash;
++		else
++			prev->next = var_hash;
++	}
++
++	var_hash->data[var_hash->used_slots++] = *rval;
++}
++
+ PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
+ {
+ 	long i;
+@@ -359,7 +382,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ 	}
+ 
+ 	if (*rval != NULL) {
+-	zval_ptr_dtor(rval);
++		var_push_dtor_no_addref(var_hash, rval);
+ 	}
+ 	*rval = *rval_ref;
+ 	(*rval)->refcount++;
+@@ -386,7 +409,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ 	}
+ 
+ 	if (*rval != NULL) {
+-	zval_ptr_dtor(rval);
++		var_push_dtor_no_addref(var_hash, rval);
+ 	}
+ 	*rval = *rval_ref;
+ 	(*rval)->refcount++;
+@@ -470,6 +493,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ 	long elements = parse_iv(start + 2);
+ 	/* use iv() not uiv() in order to check data range */
+ 	*p = YYCURSOR;
++	if (!var_hash) return 0;
+ 
+ 	if (elements < 0) {
+ 		return 0;
+@@ -493,6 +517,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ }
+ 
+ "o:" iv ":" ["] {
++	if (!var_hash) return 0;
+ 
+ 	INIT_PZVAL(*rval);
+ 	
+@@ -512,6 +537,8 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ 	zval **args[1];
+ 	zval *arg_func_name;
+ 	
++	if (!var_hash) return 0;
++
+ 	INIT_PZVAL(*rval);
+ 	len2 = len = parse_uiv(start + 2);
+ 	maxlen = max - YYCURSOR;
diff --git a/php4-CVE-2015-6835.patch b/php4-CVE-2015-6835.patch
new file mode 100644
index 0000000..19e888c
--- /dev/null
+++ b/php4-CVE-2015-6835.patch
@@ -0,0 +1,85 @@
+CVE-2015-6835: session: decoded values are freed while R: may still reach them; decoding now stops on an unserialize error.
+Upstream https://github.com/php/php-src/commit/df4bf28f9f10 + https://github.com/php/php-src/commit/fc8eff897bd7
+
+diff --git a/ext/session/session.c b/ext/session/session.c
+index bf3f089..c6eafb7 100644
+--- a/ext/session/session.c
++++ b/ext/session/session.c
+@@ -460,6 +460,7 @@ PS_SERIALIZER_DECODE_FUNC(php_binary)
+ 		namelen = *p & (~PS_BIN_UNDEF);
+ 
+ 		if (namelen > PS_BIN_MAX || (p + namelen) >= endptr) {
++			PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+ 			return FAILURE;
+ 		}
+ 
+@@ -481,8 +482,14 @@ PS_SERIALIZER_DECODE_FUNC(php_binary)
+ 				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);
++			/* later R:/r: entries may still point at it */
++			var_push_dtor_no_addref(&var_hash, &current);
+ 		}
+ 		if (!skip) {
+ 			PS_ADD_VARL(name, namelen);
+@@ -574,8 +581,14 @@ PS_SERIALIZER_DECODE_FUNC(php)
+ 				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);
++			/* later R:/r: entries may still point at it */
++			var_push_dtor_no_addref(&var_hash, &current);
+ 		}
+ 		if (!skip) {
+ 			PS_ADD_VARL(name, namelen);
+diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h
+index 659856f..7eefb93 100644
+--- a/ext/standard/php_var.h
++++ b/ext/standard/php_var.h
+@@ -62,6 +62,7 @@ PHPAPI int php_var_unserialize(zval **rval, const unsigned char **p, const unsig
+ 	var_destroy(&(var_hash))
+ 
+ PHPAPI void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval **nzval);
++PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hash, zval **val);
+ PHPAPI void var_destroy(php_unserialize_data_t *var_hash);
+ 
+ #define PHP_VAR_UNSERIALIZE_ZVAL_CHANGED(var_hash, ozval, nzval) \
+diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
+index 4ffdf83..f0e5a9a 100644
+--- a/ext/standard/var_unserializer.c
++++ b/ext/standard/var_unserializer.c
+@@ -85,7 +85,7 @@ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
+ 	var_hash->data[var_hash->used_slots++] = *rval;
+ }
+ 
+-static inline void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval)
++PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval)
+ {
+ 	var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
+ 
+diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
+index 78ccab6..c7b3660 100644
+--- a/ext/standard/var_unserializer.re
++++ b/ext/standard/var_unserializer.re
+@@ -84,7 +84,7 @@ static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
+ 	var_hash->data[var_hash->used_slots++] = *rval;
+ }
+ 
+-static inline void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval)
++PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rval)
+ {
+ 	var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
+ 
diff --git a/php4-CVE-2015-8874.patch b/php4-CVE-2015-8874.patch
new file mode 100644
index 0000000..d19bb17
--- /dev/null
+++ b/php4-CVE-2015-8874.patch
@@ -0,0 +1,21 @@
+CVE-2015-8874: gd: imagefilltoborder() recurses with negative coordinates, stack exhaustion.
+Upstream https://github.com/php/php-src/commit/f96ebb098697
+
+diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
+index 9dfb599..09b7b9f 100644
+--- a/ext/gd/libgd/gd.c
++++ b/ext/gd/libgd/gd.c
+@@ -1863,9 +1863,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/php4-CVE-2015-8935.patch b/php4-CVE-2015-8935.patch
new file mode 100644
index 0000000..6e77842
--- /dev/null
+++ b/php4-CVE-2015-8935.patch
@@ -0,0 +1,39 @@
+CVE-2015-8935: header() lets CR and LF followed by whitespace through, response splitting (CVE-2011-1398, CVE-2015-8935).
+Upstream https://github.com/php/php-src/commit/d73b1a275d30 + https://github.com/php/php-src/commit/024e1307c63c + https://github.com/php/php-src/commit/996faf964bba
+
+diff --git a/main/SAPI.c b/main/SAPI.c
+index 421560e..e201f7f 100644
+--- a/main/SAPI.c
++++ b/main/SAPI.c
+@@ -546,17 +546,22 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
+ 	while(header_line_len && isspace(header_line[header_line_len-1])) 
+ 		  header_line[--header_line_len]='\0';
+ 	
+-	/* new line safety check */
++	/* new line/NUL character safety check */
+ 	{
+-		char *s = header_line, *e = header_line + header_line_len, *p;
+-		while (s < e && (p = memchr(s, '\n', (e - s)))) {
+-			if (*(p + 1) == ' ' || *(p + 1) == '\t') {
+-				s = p + 1;
+-				continue;
++		uint i;
++		for (i = 0; i < header_line_len; i++) {
++			/* RFC 7230 ch. 3.2.4 deprecates folding support */
++			if (header_line[i] == '\n' || header_line[i] == '\r') {
++				efree(header_line);
++				sapi_module.sapi_error(E_WARNING, "Header may not contain "
++						"more than a single header, new line detected");
++				return FAILURE;
++			}
++			if (header_line[i] == '\0') {
++				efree(header_line);
++				sapi_module.sapi_error(E_WARNING, "Header may not contain NUL bytes");
++				return FAILURE;
+ 			}
+-			efree(header_line);
+-			sapi_module.sapi_error(E_WARNING, "Header may not contain more than a single header, new line detected.");
+-			return FAILURE;
+ 		}
+ 	}
+ 
diff --git a/php4-CVE-2016-10158.patch b/php4-CVE-2016-10158.patch
new file mode 100644
index 0000000..59b9e17
--- /dev/null
+++ b/php4-CVE-2016-10158.patch
@@ -0,0 +1,16 @@
+CVE-2016-10158: exif: SIGFPE on INT_MIN/-1 in exif_convert_any_to_int() for a signed rational.
+Upstream https://github.com/php/php-src/commit/1cda0d7c2ffb
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 511ebba..b860ea9 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -1189,7 +1189,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);
diff --git a/php4-CVE-2016-10161.patch b/php4-CVE-2016-10161.patch
new file mode 100644
index 0000000..977a8d6
--- /dev/null
+++ b/php4-CVE-2016-10161.patch
@@ -0,0 +1,137 @@
+CVE-2016-10161: unserialize(): out of bounds read on truncated object data.
+Upstream https://github.com/php/php-src/commit/6781229e88a0 + https://github.com/php/php-src/commit/16b3003ffc63
+
+diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
+index 834a6f8..6e99608 100644
+--- a/ext/standard/var_unserializer.c
++++ b/ext/standard/var_unserializer.c
+@@ -306,10 +306,15 @@ static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
+ 	return 0;
+ }
+ 
+-static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
++static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
+ {
+ 	long elements;
+ 
++	if (*p >= max - 2) {
++		zend_error(E_WARNING, "Bad unserialize data");
++		return -1;
++	}
++
+ 	elements = parse_iv2((*p) + 2, p);
+ 
+ 	(*p) += 2;
+@@ -357,7 +362,12 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ 	const unsigned char *cursor, *limit, *marker, *start;
+ 	zval **rval_ref;
+ 
+-	limit = cursor = *p;
++	limit = max;
++	cursor = *p;
++
++	if (YYCURSOR >= YYLIMIT) {
++		return 0;
++	}
+ 	
+ 	if (var_hash && cursor[0] != 'R') {
+ 		var_push(var_hash, rval);
+@@ -582,6 +592,11 @@ yy19:
+ 	*p = YYCURSOR;
+ 	elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
+ 
++	if (elements < 0) {
++		efree(class_name);
++		return 0;
++	}
++
+ 	if (incomplete_class) {
+ 		php_store_class_name(*rval, class_name, len2 TSRMLS_CC);
+ 	}
+@@ -614,12 +629,17 @@ yy26:
+ 		if(yych != '"') goto yy17;
+ 		++YYCURSOR;
+ 		{
++	long elements;
++
+ 	if (!var_hash) return 0;
+ 
+ 	INIT_PZVAL(*rval);
+ 	
+-	return object_common2(UNSERIALIZE_PASSTHRU,
+-			object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
++	elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
++	if (elements < 0) {
++		return 0;
++	}
++	return object_common2(UNSERIALIZE_PASSTHRU, elements);
+ }
+ yy31:
+ 		yych = *++YYCURSOR;
+diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
+index f56cff0..68aa85f 100644
+--- a/ext/standard/var_unserializer.re
++++ b/ext/standard/var_unserializer.re
+@@ -311,10 +311,15 @@ static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
+ 	return 0;
+ }
+ 
+-static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
++static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
+ {
+ 	long elements;
+ 
++	if (*p >= max - 2) {
++		zend_error(E_WARNING, "Bad unserialize data");
++		return -1;
++	}
++
+ 	elements = parse_iv2((*p) + 2, p);
+ 
+ 	(*p) += 2;
+@@ -362,7 +367,12 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ 	const unsigned char *cursor, *limit, *marker, *start;
+ 	zval **rval_ref;
+ 
+-	limit = cursor = *p;
++	limit = max;
++	cursor = *p;
++
++	if (YYCURSOR >= YYLIMIT) {
++		return 0;
++	}
+ 	
+ 	if (var_hash && cursor[0] != 'R') {
+ 		var_push(var_hash, rval);
+@@ -525,12 +535,17 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ }
+ 
+ "o:" iv ":" ["] {
++	long elements;
++
+ 	if (!var_hash) return 0;
+ 
+ 	INIT_PZVAL(*rval);
+ 	
+-	return object_common2(UNSERIALIZE_PASSTHRU,
+-			object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
++	elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
++	if (elements < 0) {
++		return 0;
++	}
++	return object_common2(UNSERIALIZE_PASSTHRU, elements);
+ }
+ 
+ "O:" uiv ":" ["]	{
+@@ -616,6 +631,11 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
+ 	*p = YYCURSOR;
+ 	elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
+ 
++	if (elements < 0) {
++		efree(class_name);
++		return 0;
++	}
++
+ 	if (incomplete_class) {
+ 		php_store_class_name(*rval, class_name, len2 TSRMLS_CC);
+ 	}
diff --git a/php4-CVE-2016-10167.patch b/php4-CVE-2016-10167.patch
new file mode 100644
index 0000000..03b4025
--- /dev/null
+++ b/php4-CVE-2016-10167.patch
@@ -0,0 +1,26 @@
+CVE-2016-10167: gd: a truncated GD2 image is filled in instead of rejected, CPU DoS.
+Upstream https://github.com/php/php-src/commit/f1b2afc9d9e7
+
+diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c
+index b42fa80..6916c12 100644
+--- a/ext/gd/libgd/gd_gd2.c
++++ b/ext/gd/libgd/gd_gd2.c
+@@ -342,12 +342,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/php4-CVE-2016-10168.patch b/php4-CVE-2016-10168.patch
new file mode 100644
index 0000000..90bad8a
--- /dev/null
+++ b/php4-CVE-2016-10168.patch
@@ -0,0 +1,26 @@
+CVE-2016-10168: gd: integer overflow in the GD2 chunk count, heap overflow.
+Upstream https://github.com/php/php-src/commit/d2274b01cbba
+
+diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c
+index 7455b19..b42fa80 100644
+--- a/ext/gd/libgd/gd_gd2.c
++++ b/ext/gd/libgd/gd_gd2.c
+@@ -15,6 +15,7 @@
+ #include <math.h>
+ #include <string.h>
+ #include <stdlib.h>
++#include <limits.h>
+ #include "gd.h"
+ #include "gdhelpers.h"
+ 
+@@ -136,6 +137,10 @@ 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(sidx, nc)) {
diff --git a/php4-CVE-2016-10397.patch b/php4-CVE-2016-10397.patch
new file mode 100644
index 0000000..048c57a
--- /dev/null
+++ b/php4-CVE-2016-10397.patch
@@ -0,0 +1,30 @@
+CVE-2016-10397: parse_url(): '@' after '?' or '#' is taken as user info, wrong host.
+Upstream https://github.com/php/php-src/commit/b061fa909de7
+
+diff --git a/ext/standard/url.c b/ext/standard/url.c
+index d0c78f2..c821c4a 100644
+--- a/ext/standard/url.c
++++ b/ext/standard/url.c
+@@ -191,17 +191,12 @@ PHPAPI php_url *php_url_parse_ex(char const *str, int length)
+ 		goto nohost;
+ 	}
+ 	
+-	e = ue;
+-	
+-	if (!(p = memchr(s, '/', (ue - s)))) {
+-		if ((p = memchr(s, '?', (ue - s)))) {
+-			e = p;
+-		} else if ((p = memchr(s, '#', (ue - s)))) {
+-			e = p;
++	/* the authority ends at the first of '/', '?' or '#' */
++	for (e = s; e < ue; e++) {
++		if (*e == '/' || *e == '?' || *e == '#') {
++			break;
+ 		}
+-	} else {
+-		e = p;
+-	}	
++	}
+ 
+ 	{
+ 		const char *t = s;
diff --git a/php4-CVE-2016-3074.patch b/php4-CVE-2016-3074.patch
new file mode 100644
index 0000000..09db191
--- /dev/null
+++ b/php4-CVE-2016-3074.patch
@@ -0,0 +1,17 @@
+CVE-2016-3074: gd: negative GD2 chunk offset or size, heap overflow.
+Upstream https://github.com/php/php-src/commit/b15f0ecc0f34
+
+diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c
+index efc6ef4..1794ca9 100644
+--- a/ext/gd/libgd/gd_gd2.c
++++ b/ext/gd/libgd/gd_gd2.c
+@@ -150,6 +150,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;
+ 	}
diff --git a/php4-CVE-2016-4542.patch b/php4-CVE-2016-4542.patch
new file mode 100644
index 0000000..88abe0d
--- /dev/null
+++ b/php4-CVE-2016-4542.patch
@@ -0,0 +1,54 @@
+CVE-2016-4542: exif: unchecked IFD sizes and offsets (CVE-2016-4542, CVE-2016-4543, CVE-2016-4544), out of bounds reads.
+Upstream https://github.com/php/php-src/commit/082aecfc3a75
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 26fad9c..db99c32 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -2846,7 +2846,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 */
+@@ -3013,6 +3013,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" TSRMLS_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)) {
+@@ -3036,6 +3041,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" TSRMLS_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 */
+@@ -3090,9 +3099,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 TSRMLS_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 TSRMLS_CC, ImageInfo, E_WARNING, "invalid TIFF start (1)");
+ 		return;
+ 	}
diff --git a/php4-CVE-2016-5399.patch b/php4-CVE-2016-5399.patch
new file mode 100644
index 0000000..4733cfd
--- /dev/null
+++ b/php4-CVE-2016-5399.patch
@@ -0,0 +1,24 @@
+CVE-2016-5399: bz2: reading continues after a libbz2 error, out of bounds write in libbz2.
+Upstream https://github.com/php/php-src/commit/f3feddb5b45b; returns 0, PHP 4 streams take (size_t)-1 as data
+
+diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
+index e58c582..94ca660 100644
+--- a/ext/bz2/bz2.c
++++ b/ext/bz2/bz2.c
+@@ -81,12 +81,14 @@ 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;
++	int ret;
+ 	
+ 	ret = BZ2_bzread(self->bz_file, buf, count);
+ 
+-	if (ret == 0) {
++	/* it is not safe to keep reading after an error, see https://bugs.php.net/72613 */
++	if (ret <= 0) {
+ 		stream->eof = 1;
++		return 0;
+ 	}
+ 
+ 	return ret;
diff --git a/php4-CVE-2016-5766.patch b/php4-CVE-2016-5766.patch
new file mode 100644
index 0000000..73a234b
--- /dev/null
+++ b/php4-CVE-2016-5766.patch
@@ -0,0 +1,26 @@
+CVE-2016-5766: gd: integer overflow in the GD2 chunk index allocation, heap overflow.
+Upstream https://github.com/php/php-src/commit/7722455726be
+
+diff --git a/ext/gd/libgd/gd_gd2.c b/ext/gd/libgd/gd_gd2.c
+index 1794ca9..7455b19 100644
+--- a/ext/gd/libgd/gd_gd2.c
++++ b/ext/gd/libgd/gd_gd2.c
+@@ -138,11 +138,18 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in
+ 	if (gd2_compressed(*fmt)) {
+ 		nc = (*ncx) * (*ncy);
+ 		GD2_DBG(php_gd_error("Reading %d chunk index entries", nc));
++		if (overflow2(sidx, nc)) {
++			goto fail1;
++		}
+ 		sidx = sizeof(t_chunk_info) * nc;
+ 		if (sidx <= 0) {
+ 			goto fail1;
+ 		}
+ 		cidx = gdCalloc(sidx, 1);
++		if (cidx == NULL) {
++			goto fail1;
++		}
<Skipped 1999 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/php4.git/commitdiff/9ddb8abcef5a39d5c04e485b3c20a7917da02cb4



More information about the pld-cvs-commit mailing list