aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Evans <grknight@gentoo.org>2019-04-05 10:43:59 -0400
committerBrian Evans <grknight@gentoo.org>2019-04-05 10:43:59 -0400
commita0735bcf953bb9e779c75e1d4882fe3ac3955790 (patch)
tree87c053484f4140e6db3be911a412d38fef52c229
parentInitial Commit (diff)
downloadphp-patches-a0735bcf953bb9e779c75e1d4882fe3ac3955790.tar.gz
php-patches-a0735bcf953bb9e779c75e1d4882fe3ac3955790.tar.bz2
php-patches-a0735bcf953bb9e779c75e1d4882fe3ac3955790.zip
Import patches and images from php 5.6.40-r1
Signed-off-by: Brian Evans <grknight@gentoo.org>
-rw-r--r--00010_no-bison-warnings.patch42
-rw-r--r--00020_mbstring-oniguruma-6.8.patch12
-rw-r--r--00030_openssl-1.1-compatibility.patch1330
-rw-r--r--00040_intl-detect-icu-via-pkg-config.patch154
-rw-r--r--00050_intl-use-icu-namespace.patch365
-rw-r--r--00060_intl-icu-memory-corruption.patch88
-rw-r--r--00070_freetype-2.9.1.patch233
-rw-r--r--00080_secbug-77396.patch50
-rw-r--r--00090_secbug-77431.patch45
-rw-r--r--00100_bug77494.patch54
-rw-r--r--00110_secbug-77509.patch47
-rw-r--r--00120_secbug-77540.patchbin0 -> 2734 bytes
-rw-r--r--00130_secbug-77563.patchbin0 -> 2371 bytes
-rw-r--r--00140_secbug-77586.patch83
-rw-r--r--00150_secbug-77630.patch89
-rw-r--r--bug77540.jpgbin0 -> 91 bytes
-rw-r--r--bug77563.jpgbin0 -> 63 bytes
17 files changed, 2592 insertions, 0 deletions
diff --git a/00010_no-bison-warnings.patch b/00010_no-bison-warnings.patch
new file mode 100644
index 0000000..1896659
--- /dev/null
+++ b/00010_no-bison-warnings.patch
@@ -0,0 +1,42 @@
+From d3466a04345b31dfc62d94fe994b40321a6418ec Mon Sep 17 00:00:00 2001
+From: Michael Orlitzky <michael@orlitzky.com>
+Date: Thu, 29 Sep 2016 15:43:06 -0400
+Subject: [PATCH 1/1] Zend/acinclude.m4: don't warn about >=bison-3.0.1
+ versions.
+
+The PHP configure script will emit a warning if it thinks your bison
+version is insufficient:
+
+ WARNING: This bison version is not supported for regeneration of
+ the Zend/PHP parsers (found: 3.0, min: 204, excluded: 3.0).
+
+However, there is an error in the test that causes it to treat all
+3.0.x versions as if they were 3.0. The result is that users get
+warned about a perfectly acceptable version of bison.
+
+This patch is meant only for Gentoo, where we can require a working
+version of bison (something newer than 3.0.1). Having done so, this
+patch removes the check and the WARNING.
+
+Gentoo-Bug: 593278
+PHP-Bug: 69055
+---
+ Zend/acinclude.m4 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Zend/acinclude.m4 b/Zend/acinclude.m4
+index 7fa8c99..9d6cb1d 100644
+--- a/Zend/acinclude.m4
++++ b/Zend/acinclude.m4
+@@ -9,7 +9,7 @@ AC_DEFUN([LIBZEND_BISON_CHECK],[
+ # non-working versions, e.g. "3.0 3.2";
+ # remove "none" when introducing the first incompatible bison version an
+ # separate any following additions by spaces
+- bison_version_exclude="3.0"
++ bison_version_exclude=""
+
+ # for standalone build of Zend Engine
+ test -z "$SED" && SED=sed
+--
+2.7.3
+
diff --git a/00020_mbstring-oniguruma-6.8.patch b/00020_mbstring-oniguruma-6.8.patch
new file mode 100644
index 0000000..642b261
--- /dev/null
+++ b/00020_mbstring-oniguruma-6.8.patch
@@ -0,0 +1,12 @@
+diff -aurN a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c
+--- a/ext/mbstring/php_mbregex.c 2018-03-28 17:28:58.000000000 -0400
++++ b/ext/mbstring/php_mbregex.c 2018-04-04 12:53:23.268296387 -0400
+@@ -454,7 +454,7 @@
+ OnigUChar err_str[ONIG_MAX_ERROR_MESSAGE_LEN];
+
+ found = zend_hash_find(&MBREX(ht_rc), (char *)pattern, patlen+1, (void **) &rc);
+- if (found == FAILURE || (*rc)->options != options || (*rc)->enc != enc || (*rc)->syntax != syntax) {
++ if (found == FAILURE || onig_get_options(*rc) != options || onig_get_encoding(*rc) != enc || onig_get_syntax(*rc) != syntax) {
+ if ((err_code = onig_new(&retval, (OnigUChar *)pattern, (OnigUChar *)(pattern + patlen), options, enc, syntax, &err_info)) != ONIG_NORMAL) {
+ onig_error_code_to_str(err_str, err_code, &err_info);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "mbregex compile err: %s", err_str);
diff --git a/00030_openssl-1.1-compatibility.patch b/00030_openssl-1.1-compatibility.patch
new file mode 100644
index 0000000..86dd5db
--- /dev/null
+++ b/00030_openssl-1.1-compatibility.patch
@@ -0,0 +1,1330 @@
+From: Debian PHP Maintainers <pkg-php-maint@lists.alioth.debian.org>
+Date: Thu, 3 Aug 2017 20:45:55 +0200
+Subject: Use-OpenSSL-1.1-compatibility-patch-when-built-with-
+
+---
+ ext/openssl/openssl.c | 683 ++++++++++++++++------
+ ext/openssl/tests/bug41033.phpt | 4 +-
+ ext/openssl/tests/bug66501.phpt | 2 +-
+ ext/openssl/tests/openssl_error_string_basic.phpt | 2 +-
+ ext/openssl/tests/sni_server.phpt | 3 +
+ ext/openssl/xp_ssl.c | 18 +-
+ ext/phar/util.c | 13 +-
+ 7 files changed, 534 insertions(+), 191 deletions(-)
+
+diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
+index a78a8fb..b53114c 100644
+--- a/ext/openssl/openssl.c
++++ b/ext/openssl/openssl.c
+@@ -42,6 +42,12 @@
+
+ /* OpenSSL includes */
+ #include <openssl/evp.h>
++#if OPENSSL_VERSION_NUMBER >= 0x10002000L
++#include <openssl/bn.h>
++#include <openssl/rsa.h>
++#include <openssl/dsa.h>
++#include <openssl/dh.h>
++#endif
+ #include <openssl/x509.h>
+ #include <openssl/x509v3.h>
+ #include <openssl/crypto.h>
+@@ -531,6 +537,133 @@ zend_module_entry openssl_module_entry = {
+ ZEND_GET_MODULE(openssl)
+ #endif
+
++/* {{{ OpenSSL compatibility functions and macros */
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
++#define EVP_PKEY_get0_RSA(_pkey) _pkey->pkey.rsa
++#define EVP_PKEY_get0_DH(_pkey) _pkey->pkey.dh
++#define EVP_PKEY_get0_DSA(_pkey) _pkey->pkey.dsa
++#define EVP_PKEY_get0_EC_KEY(_pkey) _pkey->pkey.ec
++
++static int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
++{
++ r->n = n;
++ r->e = e;
++ r->d = d;
++
++ return 1;
++}
++
++static int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
++{
++ r->p = p;
++ r->q = q;
++
++ return 1;
++}
++
++static int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
++{
++ r->dmp1 = dmp1;
++ r->dmq1 = dmq1;
++ r->iqmp = iqmp;
++
++ return 1;
++}
++
++static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
++{
++ *n = r->n;
++ *e = r->e;
++ *d = r->d;
++}
++
++static void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
++{
++ *p = r->p;
++ *q = r->q;
++}
++
++static void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
++{
++ *dmp1 = r->dmp1;
++ *dmq1 = r->dmq1;
++ *iqmp = r->iqmp;
++}
++
++static void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
++{
++ *p = dh->p;
++ *q = dh->q;
++ *g = dh->g;
++}
++
++static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
++{
++ dh->p = p;
++ dh->q = q;
++ dh->g = g;
++
++ return 1;
++}
++
++static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
++{
++ *pub_key = dh->pub_key;
++ *priv_key = dh->priv_key;
++}
++
++static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
++{
++ dh->pub_key = pub_key;
++ dh->priv_key = priv_key;
++
++ return 1;
++}
++
++static void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
++{
++ *p = d->p;
++ *q = d->q;
++ *g = d->g;
++}
++
++int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
++{
++ d->p = p;
++ d->q = q;
++ d->g = g;
++
++ return 1;
++}
++
++static void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
++{
++ *pub_key = d->pub_key;
++ *priv_key = d->priv_key;
++}
++
++int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
++{
++ d->pub_key = pub_key;
++ d->priv_key = priv_key;
++
++ return 1;
++}
++
++#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined (LIBRESSL_VERSION_NUMBER)
++#define EVP_PKEY_id(_pkey) _pkey->type
++#define EVP_PKEY_base_id(_key) EVP_PKEY_type(_key->type)
++
++static int X509_get_signature_nid(const X509 *x)
++{
++ return OBJ_obj2nid(x->sig_alg->algorithm);
++}
++
++#endif
++
++#endif
++/* }}} */
++
+ static int le_key;
+ static int le_x509;
+ static int le_csr;
+@@ -825,7 +958,7 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
+ }
+ for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+ cnf = sk_CONF_VALUE_value(sktmp, i);
+- if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
++ if (OBJ_sn2nid(cnf->name) == NID_undef && OBJ_ln2nid(cnf->name) == NID_undef && OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "problem creating object %s=%s", cnf->name, cnf->value);
+ return FAILURE;
+ }
+@@ -967,7 +1100,7 @@ static void php_openssl_dispose_config(struct php_x509_request * req TSRMLS_DC)
+ }
+ /* }}} */
+
+-#ifdef PHP_WIN32
++#if defined(PHP_WIN32) || (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
+ #define PHP_OPENSSL_RAND_ADD_TIME() ((void) 0)
+ #else
+ #define PHP_OPENSSL_RAND_ADD_TIME() php_openssl_rand_add_timeval()
+@@ -1053,9 +1186,11 @@ static EVP_MD * php_openssl_get_evp_md_from_algo(long algo) { /* {{{ */
+ mdtype = (EVP_MD *) EVP_md2();
+ break;
+ #endif
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
+ case OPENSSL_ALGO_DSS1:
+ mdtype = (EVP_MD *) EVP_dss1();
+ break;
++#endif
+ #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+ case OPENSSL_ALGO_SHA224:
+ mdtype = (EVP_MD *) EVP_sha224();
+@@ -1146,6 +1281,12 @@ PHP_MINIT_FUNCTION(openssl)
+ OpenSSL_add_all_digests();
+ OpenSSL_add_all_algorithms();
+
++#if !defined(OPENSSL_NO_AES) && defined(EVP_CIPH_CCM_MODE) && OPENSSL_VERSION_NUMBER < 0x100020000
++ EVP_add_cipher(EVP_aes_128_ccm());
++ EVP_add_cipher(EVP_aes_192_ccm());
++ EVP_add_cipher(EVP_aes_256_ccm());
++#endif
++
+ SSL_load_error_strings();
+
+ /* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
+@@ -1173,7 +1314,9 @@ PHP_MINIT_FUNCTION(openssl)
+ #ifdef HAVE_OPENSSL_MD2_H
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD2", OPENSSL_ALGO_MD2, CONST_CS|CONST_PERSISTENT);
+ #endif
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);
++#endif
+ #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA224", OPENSSL_ALGO_SHA224, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA256", OPENSSL_ALGO_SHA256, CONST_CS|CONST_PERSISTENT);
+@@ -1251,7 +1394,9 @@ PHP_MINIT_FUNCTION(openssl)
+ }
+
+ php_stream_xport_register("ssl", php_openssl_ssl_socket_factory TSRMLS_CC);
++#ifndef OPENSSL_NO_SSL3
+ php_stream_xport_register("sslv3", php_openssl_ssl_socket_factory TSRMLS_CC);
++#endif
+ #ifndef OPENSSL_NO_SSL2
+ php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC);
+ #endif
+@@ -1308,7 +1453,9 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
+ #ifndef OPENSSL_NO_SSL2
+ php_stream_xport_unregister("sslv2" TSRMLS_CC);
+ #endif
++#ifndef OPENSSL_NO_SSL3
+ php_stream_xport_unregister("sslv3" TSRMLS_CC);
++#endif
+ php_stream_xport_unregister("tls" TSRMLS_CC);
+ php_stream_xport_unregister("tlsv1.0" TSRMLS_CC);
+ #if OPENSSL_VERSION_NUMBER >= 0x10001001L
+@@ -1893,6 +2040,7 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
+ {
+ GENERAL_NAMES *names;
+ const X509V3_EXT_METHOD *method = NULL;
++ ASN1_OCTET_STRING *extension_data;
+ long i, length, num;
+ const unsigned char *p;
+
+@@ -1901,8 +2049,9 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
+ return -1;
+ }
+
+- p = extension->value->data;
+- length = extension->value->length;
++ extension_data = X509_EXTENSION_get_data(extension);
++ p = extension_data->data;
++ length = extension_data->length;
+ if (method->it) {
+ names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
+ ASN1_ITEM_ptr(method->it)));
+@@ -1965,6 +2114,8 @@ PHP_FUNCTION(openssl_x509_parse)
+ char * tmpstr;
+ zval * subitem;
+ X509_EXTENSION *extension;
++ X509_NAME *subject_name;
++ char *cert_name;
+ char *extname;
+ BIO *bio_out;
+ BUF_MEM *bio_buf;
+@@ -1979,10 +2130,10 @@ PHP_FUNCTION(openssl_x509_parse)
+ }
+ array_init(return_value);
+
+- if (cert->name) {
+- add_assoc_string(return_value, "name", cert->name, 1);
+- }
+-/* add_assoc_bool(return_value, "valid", cert->valid); */
++ subject_name = X509_get_subject_name(cert);
++ cert_name = X509_NAME_oneline(subject_name, NULL, 0);
++ add_assoc_string(return_value, "name", cert_name, 1);
++ OPENSSL_free(cert_name);
+
+ add_assoc_name_entry(return_value, "subject", X509_get_subject_name(cert), useshortnames TSRMLS_CC);
+ /* hash as used in CA directories to lookup cert by subject name */
+@@ -2008,7 +2159,7 @@ PHP_FUNCTION(openssl_x509_parse)
+ add_assoc_string(return_value, "alias", tmpstr, 1);
+ }
+
+- sig_nid = OBJ_obj2nid((cert)->sig_alg->algorithm);
++ sig_nid = X509_get_signature_nid(cert);
+ add_assoc_string(return_value, "signatureTypeSN", (char*)OBJ_nid2sn(sig_nid), 1);
+ add_assoc_string(return_value, "signatureTypeLN", (char*)OBJ_nid2ln(sig_nid), 1);
+ add_assoc_long(return_value, "signatureTypeNID", sig_nid);
+@@ -3217,7 +3368,21 @@ PHP_FUNCTION(openssl_csr_get_public_key)
+ RETURN_FALSE;
+ }
+
+- tpubkey=X509_REQ_get_pubkey(csr);
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
++ /* Due to changes in OpenSSL 1.1 related to locking when decoding CSR,
++ * the pub key is not changed after assigning. It means if we pass
++ * a private key, it will be returned including the private part.
++ * If we duplicate it, then we get just the public part which is
++ * the same behavior as for OpenSSL 1.0 */
++ csr = X509_REQ_dup(csr);
++#endif
++ /* Retrieve the public key from the CSR */
++ tpubkey = X509_REQ_get_pubkey(csr);
++
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
++ /* We need to free the CSR as it was duplicated */
++ X509_REQ_free(csr);
++#endif
+ RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key TSRMLS_CC));
+ return;
+ }
+@@ -3482,13 +3647,20 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
+ {
+ assert(pkey != NULL);
+
+- switch (pkey->type) {
++ switch (EVP_PKEY_id(pkey)) {
+ #ifndef NO_RSA
+ case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA2:
+- assert(pkey->pkey.rsa != NULL);
+- if (pkey->pkey.rsa != NULL && (NULL == pkey->pkey.rsa->p || NULL == pkey->pkey.rsa->q)) {
+- return 0;
++ {
++ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
++ if (rsa != NULL) {
++ const BIGNUM *p, *q;
++
++ RSA_get0_factors(rsa, &p, &q);
++ if (p == NULL || q == NULL) {
++ return 0;
++ }
++ }
+ }
+ break;
+ #endif
+@@ -3498,28 +3670,51 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
+ case EVP_PKEY_DSA2:
+ case EVP_PKEY_DSA3:
+ case EVP_PKEY_DSA4:
+- assert(pkey->pkey.dsa != NULL);
+-
+- if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
+- return 0;
++ {
++ DSA *dsa = EVP_PKEY_get0_DSA(pkey);
++ if (dsa != NULL) {
++ const BIGNUM *p, *q, *g, *pub_key, *priv_key;
++
++ DSA_get0_pqg(dsa, &p, &q, &g);
++ if (p == NULL || q == NULL) {
++ return 0;
++ }
++
++ DSA_get0_key(dsa, &pub_key, &priv_key);
++ if (priv_key == NULL) {
++ return 0;
++ }
++ }
+ }
+ break;
+ #endif
+ #ifndef NO_DH
+ case EVP_PKEY_DH:
+- assert(pkey->pkey.dh != NULL);
+-
+- if (NULL == pkey->pkey.dh->p || NULL == pkey->pkey.dh->priv_key) {
+- return 0;
++ {
++ DH *dh = EVP_PKEY_get0_DH(pkey);
++ if (dh != NULL) {
++ const BIGNUM *p, *q, *g, *pub_key, *priv_key;
++
++ DH_get0_pqg(dh, &p, &q, &g);
++ if (p == NULL) {
++ return 0;
++ }
++
++ DH_get0_key(dh, &pub_key, &priv_key);
++ if (priv_key == NULL) {
++ return 0;
++ }
++ }
+ }
+ break;
+ #endif
+ #ifdef HAVE_EVP_PKEY_EC
+ case EVP_PKEY_EC:
+- assert(pkey->pkey.ec != NULL);
+-
+- if ( NULL == EC_KEY_get0_private_key(pkey->pkey.ec)) {
+- return 0;
++ {
++ EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
++ if (ec != NULL && NULL == EC_KEY_get0_private_key(ec)) {
++ return 0;
++ }
+ }
+ break;
+ #endif
+@@ -3531,34 +3726,80 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
+ }
+ /* }}} */
+
+-#define OPENSSL_PKEY_GET_BN(_type, _name) do { \
+- if (pkey->pkey._type->_name != NULL) { \
+- int len = BN_num_bytes(pkey->pkey._type->_name); \
+- char *str = emalloc(len + 1); \
+- BN_bn2bin(pkey->pkey._type->_name, (unsigned char*)str); \
+- str[len] = 0; \
+- add_assoc_stringl(_type, #_name, str, len, 0); \
+- } \
+- } while (0)
+-
+-#define OPENSSL_PKEY_SET_BN(_ht, _type, _name) do { \
+- zval **bn; \
+- if (zend_hash_find(_ht, #_name, sizeof(#_name), (void**)&bn) == SUCCESS && \
+- Z_TYPE_PP(bn) == IS_STRING) { \
+- _type->_name = BN_bin2bn( \
+- (unsigned char*)Z_STRVAL_PP(bn), \
+- Z_STRLEN_PP(bn), NULL); \
+- } \
++#define OPENSSL_GET_BN(_array, _bn, _name) do { \
++ if (_bn != NULL) { \
++ int len = BN_num_bytes(_bn); \
++ char *str = emalloc(len + 1); \
++ BN_bn2bin(_bn, (unsigned char*)str); \
++ str[len] = 0; \
++ add_assoc_stringl(_array, #_name, str, len, 0); \
++ } \
+ } while (0);
+
++#define OPENSSL_PKEY_GET_BN(_type, _name) OPENSSL_GET_BN(_type, _name, _name)
++
++#define OPENSSL_PKEY_SET_BN(_data, _name) do { \
++ zval **bn; \
++ if (zend_hash_find(Z_ARRVAL_P(_data), #_name, sizeof(#_name),(void**)&bn) == SUCCESS && \
++ Z_TYPE_PP(bn) == IS_STRING) { \
++ _name = BN_bin2bn( \
++ (unsigned char*)Z_STRVAL_PP(bn), \
++ Z_STRLEN_PP(bn), NULL); \
++ } else { \
++ _name = NULL; \
++ } \
++ } while (0);
++
++/* {{{ php_openssl_pkey_init_rsa */
++zend_bool php_openssl_pkey_init_and_assign_rsa(EVP_PKEY *pkey, RSA *rsa, zval *data)
++{
++ BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
++
++ OPENSSL_PKEY_SET_BN(data, n);
++ OPENSSL_PKEY_SET_BN(data, e);
++ OPENSSL_PKEY_SET_BN(data, d);
++ if (!n || !d || !RSA_set0_key(rsa, n, e, d)) {
++ return 0;
++ }
++
++ OPENSSL_PKEY_SET_BN(data, p);
++ OPENSSL_PKEY_SET_BN(data, q);
++ if ((p || q) && !RSA_set0_factors(rsa, p, q)) {
++ return 0;
++ }
++
++ OPENSSL_PKEY_SET_BN(data, dmp1);
++ OPENSSL_PKEY_SET_BN(data, dmq1);
++ OPENSSL_PKEY_SET_BN(data, iqmp);
++ if ((dmp1 || dmq1 || iqmp) && !RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) {
++ return 0;
++ }
++
++ if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
++ return 0;
++ }
++
++ return 1;
++}
++/* }}} */
++
+ /* {{{ php_openssl_pkey_init_dsa */
+-zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
++zend_bool php_openssl_pkey_init_dsa(DSA *dsa, zval *data)
+ {
+- if (!dsa->p || !dsa->q || !dsa->g) {
++ BIGNUM *p, *q, *g, *priv_key, *pub_key;
++ const BIGNUM *priv_key_const, *pub_key_const;
++
++ OPENSSL_PKEY_SET_BN(data, p);
++ OPENSSL_PKEY_SET_BN(data, q);
++ OPENSSL_PKEY_SET_BN(data, g);
++ if (!p || !q || !g || !DSA_set0_pqg(dsa, p, q, g)) {
+ return 0;
+ }
+- if (dsa->priv_key || dsa->pub_key) {
+- return 1;
++
++ OPENSSL_PKEY_SET_BN(data, pub_key);
++ OPENSSL_PKEY_SET_BN(data, priv_key);
++ if (pub_key) {
++ return DSA_set0_key(dsa, pub_key, priv_key);
+ }
+ PHP_OPENSSL_RAND_ADD_TIME();
+ if (!DSA_generate_key(dsa)) {
+@@ -3566,7 +3807,8 @@ zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
+ }
+ /* if BN_mod_exp return -1, then DSA_generate_key succeed for failed key
+ * so we need to double check that public key is created */
+- if (!dsa->pub_key || BN_is_zero(dsa->pub_key)) {
++ DSA_get0_key(dsa, &pub_key_const, &priv_key_const);
++ if (!pub_key_const || BN_is_zero(pub_key_const)) {
+ return 0;
+ }
+ /* all good */
+@@ -3574,14 +3816,66 @@ zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
+ }
+ /* }}} */
+
++/* {{{ php_openssl_dh_pub_from_priv */
++static BIGNUM *php_openssl_dh_pub_from_priv(BIGNUM *priv_key, BIGNUM *g, BIGNUM *p)
++{
++ BIGNUM *pub_key, *priv_key_const_time;
++ BN_CTX *ctx;
++
++ pub_key = BN_new();
++ if (pub_key == NULL) {
++ return NULL;
++ }
++
++ priv_key_const_time = BN_new();
++ if (priv_key_const_time == NULL) {
++ BN_free(pub_key);
++ return NULL;
++ }
++ ctx = BN_CTX_new();
++ if (ctx == NULL) {
++ BN_free(pub_key);
++ BN_free(priv_key_const_time);
++ return NULL;
++ }
++
++ BN_with_flags(priv_key_const_time, priv_key, BN_FLG_CONSTTIME);
++
++ if (!BN_mod_exp_mont(pub_key, g, priv_key_const_time, p, ctx, NULL)) {
++ BN_free(pub_key);
++ pub_key = NULL;
++ }
++
++ BN_free(priv_key_const_time);
++ BN_CTX_free(ctx);
++
++ return pub_key;
++}
++/* }}} */
++
+ /* {{{ php_openssl_pkey_init_dh */
+-zend_bool php_openssl_pkey_init_dh(DH *dh)
++zend_bool php_openssl_pkey_init_dh(DH *dh, zval *data)
+ {
+- if (!dh->p || !dh->g) {
++ BIGNUM *p, *q, *g, *priv_key, *pub_key;
++
++ OPENSSL_PKEY_SET_BN(data, p);
++ OPENSSL_PKEY_SET_BN(data, q);
++ OPENSSL_PKEY_SET_BN(data, g);
++ if (!p || !g || !DH_set0_pqg(dh, p, q, g)) {
+ return 0;
+ }
+- if (dh->pub_key) {
+- return 1;
++
++ OPENSSL_PKEY_SET_BN(data, priv_key);
++ OPENSSL_PKEY_SET_BN(data, pub_key);
++ if (pub_key) {
++ return DH_set0_key(dh, pub_key, priv_key);
++ }
++ if (priv_key) {
++ pub_key = php_openssl_dh_pub_from_priv(priv_key, g, p);
++ if (pub_key == NULL) {
++ return 0;
++ }
++ return DH_set0_key(dh, pub_key, priv_key);
+ }
+ PHP_OPENSSL_RAND_ADD_TIME();
+ if (!DH_generate_key(dh)) {
+@@ -3614,18 +3908,8 @@ PHP_FUNCTION(openssl_pkey_new)
+ if (pkey) {
+ RSA *rsa = RSA_new();
+ if (rsa) {
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, n);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, e);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, d);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, p);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, q);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmp1);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmq1);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, iqmp);
+- if (rsa->n && rsa->d) {
+- if (EVP_PKEY_assign_RSA(pkey, rsa)) {
+- RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+- }
++ if (php_openssl_pkey_init_and_assign_rsa(pkey, rsa, *data)) {
++ RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ }
+ RSA_free(rsa);
+ }
+@@ -3638,12 +3922,7 @@ PHP_FUNCTION(openssl_pkey_new)
+ if (pkey) {
+ DSA *dsa = DSA_new();
+ if (dsa) {
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, p);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, q);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, g);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, priv_key);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, pub_key);
+- if (php_openssl_pkey_init_dsa(dsa)) {
++ if (php_openssl_pkey_init_dsa(dsa, *data)) {
+ if (EVP_PKEY_assign_DSA(pkey, dsa)) {
+ RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ }
+@@ -3659,11 +3938,7 @@ PHP_FUNCTION(openssl_pkey_new)
+ if (pkey) {
+ DH *dh = DH_new();
+ if (dh) {
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, p);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, g);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, priv_key);
+- OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, pub_key);
+- if (php_openssl_pkey_init_dh(dh)) {
++ if (php_openssl_pkey_init_dh(dh, *data)) {
+ if (EVP_PKEY_assign_DH(pkey, dh)) {
+ RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
+ }
+@@ -3738,10 +4013,10 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
+ cipher = NULL;
+ }
+
+- switch (EVP_PKEY_type(key->type)) {
++ switch (EVP_PKEY_base_id(key)) {
+ #ifdef HAVE_EVP_PKEY_EC
+ case EVP_PKEY_EC:
+- pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
++ pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get0_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+ break;
+ #endif
+ default:
+@@ -3807,7 +4082,7 @@ PHP_FUNCTION(openssl_pkey_export)
+ cipher = NULL;
+ }
+
+- switch (EVP_PKEY_type(key->type)) {
++ switch (EVP_PKEY_base_id(key)) {
+ #ifdef HAVE_EVP_PKEY_EC
+ case EVP_PKEY_EC:
+ pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+@@ -3928,25 +4203,33 @@ PHP_FUNCTION(openssl_pkey_get_details)
+ /*TODO: Use the real values once the openssl constants are used
+ * See the enum at the top of this file
+ */
+- switch (EVP_PKEY_type(pkey->type)) {
++ switch (EVP_PKEY_base_id(pkey)) {
+ case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA2:
+- ktype = OPENSSL_KEYTYPE_RSA;
+-
+- if (pkey->pkey.rsa != NULL) {
+- zval *rsa;
+-
+- ALLOC_INIT_ZVAL(rsa);
+- array_init(rsa);
+- OPENSSL_PKEY_GET_BN(rsa, n);
+- OPENSSL_PKEY_GET_BN(rsa, e);
+- OPENSSL_PKEY_GET_BN(rsa, d);
+- OPENSSL_PKEY_GET_BN(rsa, p);
+- OPENSSL_PKEY_GET_BN(rsa, q);
+- OPENSSL_PKEY_GET_BN(rsa, dmp1);
+- OPENSSL_PKEY_GET_BN(rsa, dmq1);
+- OPENSSL_PKEY_GET_BN(rsa, iqmp);
+- add_assoc_zval(return_value, "rsa", rsa);
++ {
++ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
++ ktype = OPENSSL_KEYTYPE_RSA;
++
++ if (rsa != NULL) {
++ zval *z_rsa;
++ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
++
++ RSA_get0_key(rsa, &n, &e, &d);
++ RSA_get0_factors(rsa, &p, &q);
++ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
++
++ ALLOC_INIT_ZVAL(z_rsa);
++ array_init(z_rsa);
++ OPENSSL_PKEY_GET_BN(z_rsa, n);
++ OPENSSL_PKEY_GET_BN(z_rsa, e);
++ OPENSSL_PKEY_GET_BN(z_rsa, d);
++ OPENSSL_PKEY_GET_BN(z_rsa, p);
++ OPENSSL_PKEY_GET_BN(z_rsa, q);
++ OPENSSL_PKEY_GET_BN(z_rsa, dmp1);
++ OPENSSL_PKEY_GET_BN(z_rsa, dmq1);
++ OPENSSL_PKEY_GET_BN(z_rsa, iqmp);
++ add_assoc_zval(return_value, "rsa", z_rsa);
++ }
+ }
+
+ break;
+@@ -3954,42 +4237,55 @@ PHP_FUNCTION(openssl_pkey_get_details)
+ case EVP_PKEY_DSA2:
+ case EVP_PKEY_DSA3:
+ case EVP_PKEY_DSA4:
+- ktype = OPENSSL_KEYTYPE_DSA;
+-
+- if (pkey->pkey.dsa != NULL) {
+- zval *dsa;
+-
+- ALLOC_INIT_ZVAL(dsa);
+- array_init(dsa);
+- OPENSSL_PKEY_GET_BN(dsa, p);
+- OPENSSL_PKEY_GET_BN(dsa, q);
+- OPENSSL_PKEY_GET_BN(dsa, g);
+- OPENSSL_PKEY_GET_BN(dsa, priv_key);
+- OPENSSL_PKEY_GET_BN(dsa, pub_key);
+- add_assoc_zval(return_value, "dsa", dsa);
++ {
++ DSA *dsa = EVP_PKEY_get0_DSA(pkey);
++ ktype = OPENSSL_KEYTYPE_DSA;
++
++ if (dsa != NULL) {
++ zval *z_dsa;
++ const BIGNUM *p, *q, *g, *priv_key, *pub_key;
++
++ DSA_get0_pqg(dsa, &p, &q, &g);
++ DSA_get0_key(dsa, &pub_key, &priv_key);
++
++ ALLOC_INIT_ZVAL(z_dsa);
++ array_init(z_dsa);
++ OPENSSL_PKEY_GET_BN(z_dsa, p);
++ OPENSSL_PKEY_GET_BN(z_dsa, q);
++ OPENSSL_PKEY_GET_BN(z_dsa, g);
++ OPENSSL_PKEY_GET_BN(z_dsa, priv_key);
++ OPENSSL_PKEY_GET_BN(z_dsa, pub_key);
++ add_assoc_zval(return_value, "dsa", z_dsa);
++ }
+ }
+ break;
+ case EVP_PKEY_DH:
+-
+- ktype = OPENSSL_KEYTYPE_DH;
+-
+- if (pkey->pkey.dh != NULL) {
+- zval *dh;
+-
+- ALLOC_INIT_ZVAL(dh);
+- array_init(dh);
+- OPENSSL_PKEY_GET_BN(dh, p);
+- OPENSSL_PKEY_GET_BN(dh, g);
+- OPENSSL_PKEY_GET_BN(dh, priv_key);
+- OPENSSL_PKEY_GET_BN(dh, pub_key);
+- add_assoc_zval(return_value, "dh", dh);
++ {
++ DH *dh = EVP_PKEY_get0_DH(pkey);
++ ktype = OPENSSL_KEYTYPE_DH;
++
++ if (dh != NULL) {
++ zval *z_dh;
++ const BIGNUM *p, *q, *g, *priv_key, *pub_key;
++
++ DH_get0_pqg(dh, &p, &q, &g);
++ DH_get0_key(dh, &pub_key, &priv_key);
++
++ ALLOC_INIT_ZVAL(z_dh);
++ array_init(z_dh);
++ OPENSSL_PKEY_GET_BN(z_dh, p);
++ OPENSSL_PKEY_GET_BN(z_dh, g);
++ OPENSSL_PKEY_GET_BN(z_dh, priv_key);
++ OPENSSL_PKEY_GET_BN(z_dh, pub_key);
++ add_assoc_zval(return_value, "dh", z_dh);
++ }
+ }
+
+ break;
+ #ifdef HAVE_EVP_PKEY_EC
+ case EVP_PKEY_EC:
+ ktype = OPENSSL_KEYTYPE_EC;
+- if (pkey->pkey.ec != NULL) {
++ if (EVP_PKEY_get0_EC_KEY(pkey) != NULL) {
+ zval *ec;
+ const EC_GROUP *ec_group;
+ int nid;
+@@ -4546,13 +4842,13 @@ PHP_FUNCTION(openssl_private_encrypt)
+ cryptedlen = EVP_PKEY_size(pkey);
+ cryptedbuf = emalloc(cryptedlen + 1);
+
+- switch (pkey->type) {
++ switch (EVP_PKEY_id(pkey)) {
+ case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA2:
+ successful = (RSA_private_encrypt(data_len,
+ (unsigned char *)data,
+ cryptedbuf,
+- pkey->pkey.rsa,
++ EVP_PKEY_get0_RSA(pkey),
+ padding) == cryptedlen);
+ break;
+ default:
+@@ -4604,13 +4900,13 @@ PHP_FUNCTION(openssl_private_decrypt)
+ cryptedlen = EVP_PKEY_size(pkey);
+ crypttemp = emalloc(cryptedlen + 1);
+
+- switch (pkey->type) {
++ switch (EVP_PKEY_id(pkey)) {
+ case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA2:
+ cryptedlen = RSA_private_decrypt(data_len,
+ (unsigned char *)data,
+ crypttemp,
+- pkey->pkey.rsa,
++ EVP_PKEY_get0_RSA(pkey),
+ padding);
+ if (cryptedlen != -1) {
+ cryptedbuf = emalloc(cryptedlen + 1);
+@@ -4669,13 +4965,13 @@ PHP_FUNCTION(openssl_public_encrypt)
+ cryptedlen = EVP_PKEY_size(pkey);
+ cryptedbuf = emalloc(cryptedlen + 1);
+
+- switch (pkey->type) {
++ switch (EVP_PKEY_id(pkey)) {
+ case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA2:
+ successful = (RSA_public_encrypt(data_len,
+ (unsigned char *)data,
+ cryptedbuf,
+- pkey->pkey.rsa,
++ EVP_PKEY_get0_RSA(pkey),
+ padding) == cryptedlen);
+ break;
+ default:
+@@ -4728,13 +5024,13 @@ PHP_FUNCTION(openssl_public_decrypt)
+ cryptedlen = EVP_PKEY_size(pkey);
+ crypttemp = emalloc(cryptedlen + 1);
+
+- switch (pkey->type) {
++ switch (EVP_PKEY_id(pkey)) {
+ case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA2:
+ cryptedlen = RSA_public_decrypt(data_len,
+ (unsigned char *)data,
+ crypttemp,
+- pkey->pkey.rsa,
++ EVP_PKEY_get0_RSA(pkey),
+ padding);
+ if (cryptedlen != -1) {
+ cryptedbuf = emalloc(cryptedlen + 1);
+@@ -4798,7 +5094,7 @@ PHP_FUNCTION(openssl_sign)
+ long keyresource = -1;
+ char * data;
+ int data_len;
+- EVP_MD_CTX md_ctx;
++ EVP_MD_CTX *md_ctx;
+ zval *method = NULL;
+ long signature_algo = OPENSSL_ALGO_SHA1;
+ const EVP_MD *mdtype;
+@@ -4831,9 +5127,10 @@ PHP_FUNCTION(openssl_sign)
+ siglen = EVP_PKEY_size(pkey);
+ sigbuf = emalloc(siglen + 1);
+
+- EVP_SignInit(&md_ctx, mdtype);
+- EVP_SignUpdate(&md_ctx, data, data_len);
+- if (EVP_SignFinal (&md_ctx, sigbuf,(unsigned int *)&siglen, pkey)) {
++ md_ctx = EVP_MD_CTX_create();
++ EVP_SignInit(md_ctx, mdtype);
++ EVP_SignUpdate(md_ctx, data, data_len);
++ if (EVP_SignFinal (md_ctx, sigbuf,(unsigned int *)&siglen, pkey)) {
+ zval_dtor(signature);
+ sigbuf[siglen] = '\0';
+ ZVAL_STRINGL(signature, (char *)sigbuf, siglen, 0);
+@@ -4842,7 +5139,7 @@ PHP_FUNCTION(openssl_sign)
+ efree(sigbuf);
+ RETVAL_FALSE;
+ }
+- EVP_MD_CTX_cleanup(&md_ctx);
++ EVP_MD_CTX_destroy(md_ctx);
+ if (keyresource == -1) {
+ EVP_PKEY_free(pkey);
+ }
+@@ -4856,7 +5153,7 @@ PHP_FUNCTION(openssl_verify)
+ zval **key;
+ EVP_PKEY *pkey;
+ int err;
+- EVP_MD_CTX md_ctx;
++ EVP_MD_CTX *md_ctx;
+ const EVP_MD *mdtype;
+ long keyresource = -1;
+ char * data; int data_len;
+@@ -4890,10 +5187,11 @@ PHP_FUNCTION(openssl_verify)
+ RETURN_FALSE;
+ }
+
+- EVP_VerifyInit (&md_ctx, mdtype);
+- EVP_VerifyUpdate (&md_ctx, data, data_len);
+- err = EVP_VerifyFinal (&md_ctx, (unsigned char *)signature, signature_len, pkey);
+- EVP_MD_CTX_cleanup(&md_ctx);
++ md_ctx = EVP_MD_CTX_create();
++ EVP_VerifyInit (md_ctx, mdtype);
++ EVP_VerifyUpdate (md_ctx, data, data_len);
++ err = EVP_VerifyFinal (md_ctx, (unsigned char *)signature, signature_len, pkey);
++ EVP_MD_CTX_destroy(md_ctx);
+
+ if (keyresource == -1) {
+ EVP_PKEY_free(pkey);
+@@ -4917,7 +5215,7 @@ PHP_FUNCTION(openssl_seal)
+ char *method =NULL;
+ int method_len = 0;
+ const EVP_CIPHER *cipher;
+- EVP_CIPHER_CTX ctx;
++ EVP_CIPHER_CTX *ctx;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
+ return;
+@@ -4950,6 +5248,7 @@ PHP_FUNCTION(openssl_seal)
+ memset(eks, 0, sizeof(*eks) * nkeys);
+ key_resources = safe_emalloc(nkeys, sizeof(long), 0);
+ memset(key_resources, 0, sizeof(*key_resources) * nkeys);
++ memset(pkeys, 0, sizeof(*pkeys) * nkeys);
+
+ /* get the public keys we are using to seal this data */
+ zend_hash_internal_pointer_reset_ex(pubkeysht, &pos);
+@@ -4967,27 +5266,28 @@ PHP_FUNCTION(openssl_seal)
+ i++;
+ }
+
+- if (!EVP_EncryptInit(&ctx,cipher,NULL,NULL)) {
++ ctx = EVP_CIPHER_CTX_new();
++ if (ctx == NULL || !EVP_EncryptInit(ctx,cipher,NULL,NULL)) {
+ RETVAL_FALSE;
+- EVP_CIPHER_CTX_cleanup(&ctx);
++ EVP_CIPHER_CTX_free(ctx);
+ goto clean_exit;
+ }
+
+ #if 0
+ /* Need this if allow ciphers that require initialization vector */
+- ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
++ ivlen = EVP_CIPHER_CTX_iv_length(ctx);
+ iv = ivlen ? emalloc(ivlen + 1) : NULL;
+ #endif
+ /* allocate one byte extra to make room for \0 */
+- buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(&ctx));
+- EVP_CIPHER_CTX_cleanup(&ctx);
++ buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(ctx));
++ EVP_CIPHER_CTX_cleanup(ctx);
+
+- if (EVP_SealInit(&ctx, cipher, eks, eksl, NULL, pkeys, nkeys) <= 0 ||
+- !EVP_SealUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len) ||
+- !EVP_SealFinal(&ctx, buf + len1, &len2)) {
++ if (EVP_SealInit(ctx, cipher, eks, eksl, NULL, pkeys, nkeys) <= 0 ||
++ !EVP_SealUpdate(ctx, buf, &len1, (unsigned char *)data, data_len) ||
++ !EVP_SealFinal(ctx, buf + len1, &len2)) {
+ RETVAL_FALSE;
+ efree(buf);
+- EVP_CIPHER_CTX_cleanup(&ctx);
++ EVP_CIPHER_CTX_free(ctx);
+ goto clean_exit;
+ }
+
+@@ -5018,7 +5318,7 @@ PHP_FUNCTION(openssl_seal)
+ efree(buf);
+ }
+ RETVAL_LONG(len1 + len2);
+- EVP_CIPHER_CTX_cleanup(&ctx);
++ EVP_CIPHER_CTX_free(ctx);
+
+ clean_exit:
+ for (i=0; i<nkeys; i++) {
+@@ -5045,7 +5345,7 @@ PHP_FUNCTION(openssl_open)
+ int len1, len2;
+ unsigned char *buf;
+ long keyresource = -1;
+- EVP_CIPHER_CTX ctx;
++ EVP_CIPHER_CTX *ctx;
+ char * data; int data_len;
+ char * ekey; int ekey_len;
+ char *method =NULL;
+@@ -5074,8 +5374,9 @@ PHP_FUNCTION(openssl_open)
+
+ buf = emalloc(data_len + 1);
+
+- if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
+- if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
++ ctx = EVP_CIPHER_CTX_new();
++ if (EVP_OpenInit(ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(ctx, buf, &len1, (unsigned char *)data, data_len)) {
++ if (!EVP_OpenFinal(ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
+ efree(buf);
+ RETVAL_FALSE;
+ } else {
+@@ -5091,7 +5392,7 @@ PHP_FUNCTION(openssl_open)
+ if (keyresource == -1) {
+ EVP_PKEY_free(pkey);
+ }
+- EVP_CIPHER_CTX_cleanup(&ctx);
++ EVP_CIPHER_CTX_free(ctx);
+ }
+ /* }}} */
+
+@@ -5151,7 +5452,7 @@ PHP_FUNCTION(openssl_digest)
+ char *data, *method;
+ int data_len, method_len;
+ const EVP_MD *mdtype;
+- EVP_MD_CTX md_ctx;
++ EVP_MD_CTX *md_ctx;
+ int siglen;
+ unsigned char *sigbuf;
+
+@@ -5167,9 +5468,10 @@ PHP_FUNCTION(openssl_digest)
+ siglen = EVP_MD_size(mdtype);
+ sigbuf = emalloc(siglen + 1);
+
+- EVP_DigestInit(&md_ctx, mdtype);
+- EVP_DigestUpdate(&md_ctx, (unsigned char *)data, data_len);
+- if (EVP_DigestFinal (&md_ctx, (unsigned char *)sigbuf, (unsigned int *)&siglen)) {
++ md_ctx = EVP_MD_CTX_create();
++ EVP_DigestInit(md_ctx, mdtype);
++ EVP_DigestUpdate(md_ctx, (unsigned char *)data, data_len);
++ if (EVP_DigestFinal (md_ctx, (unsigned char *)sigbuf, (unsigned int *)&siglen)) {
+ if (raw_output) {
+ sigbuf[siglen] = '\0';
+ RETVAL_STRINGL((char *)sigbuf, siglen, 0);
+@@ -5185,6 +5487,8 @@ PHP_FUNCTION(openssl_digest)
+ efree(sigbuf);
+ RETVAL_FALSE;
+ }
++
++ EVP_MD_CTX_destroy(md_ctx);
+ }
+ /* }}} */
+
+@@ -5230,7 +5534,7 @@ PHP_FUNCTION(openssl_encrypt)
+ char *data, *method, *password, *iv = "";
+ int data_len, method_len, password_len, iv_len = 0, max_iv_len;
+ const EVP_CIPHER *cipher_type;
+- EVP_CIPHER_CTX cipher_ctx;
++ EVP_CIPHER_CTX *cipher_ctx;
+ int i=0, outlen, keylen;
+ unsigned char *outbuf, *key;
+ zend_bool free_iv;
+@@ -5262,19 +5566,24 @@ PHP_FUNCTION(openssl_encrypt)
+ outlen = data_len + EVP_CIPHER_block_size(cipher_type);
+ outbuf = safe_emalloc(outlen, 1, 1);
+
+- EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL);
++ cipher_ctx = EVP_CIPHER_CTX_new();
++ if (!cipher_ctx) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to create cipher context");
++ RETURN_FALSE;
++ }
++ EVP_EncryptInit(cipher_ctx, cipher_type, NULL, NULL);
+ if (password_len > keylen) {
+- EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
++ EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len);
+ }
+- EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
++ EVP_EncryptInit_ex(cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
+ if (options & OPENSSL_ZERO_PADDING) {
+- EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
++ EVP_CIPHER_CTX_set_padding(cipher_ctx, 0);
+ }
+ if (data_len > 0) {
+- EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
++ EVP_EncryptUpdate(cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
+ }
+ outlen = i;
+- if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
++ if (EVP_EncryptFinal(cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+ outlen += i;
+ if (options & OPENSSL_RAW_DATA) {
+ outbuf[outlen] = '\0';
+@@ -5301,7 +5610,8 @@ PHP_FUNCTION(openssl_encrypt)
+ if (free_iv) {
+ efree(iv);
+ }
+- EVP_CIPHER_CTX_cleanup(&cipher_ctx);
++ EVP_CIPHER_CTX_cleanup(cipher_ctx);
++ EVP_CIPHER_CTX_free(cipher_ctx);
+ }
+ /* }}} */
+
+@@ -5313,7 +5623,7 @@ PHP_FUNCTION(openssl_decrypt)
+ char *data, *method, *password, *iv = "";
+ int data_len, method_len, password_len, iv_len = 0;
+ const EVP_CIPHER *cipher_type;
+- EVP_CIPHER_CTX cipher_ctx;
++ EVP_CIPHER_CTX *cipher_ctx;
+ int i, outlen, keylen;
+ unsigned char *outbuf, *key;
+ int base64_str_len;
+@@ -5359,17 +5669,23 @@ PHP_FUNCTION(openssl_decrypt)
+ outlen = data_len + EVP_CIPHER_block_size(cipher_type);
+ outbuf = emalloc(outlen + 1);
+
+- EVP_DecryptInit(&cipher_ctx, cipher_type, NULL, NULL);
++ cipher_ctx = EVP_CIPHER_CTX_new();
++ if (!cipher_ctx) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to create cipher context");
++ RETURN_FALSE;
++ }
++
++ EVP_DecryptInit(cipher_ctx, cipher_type, NULL, NULL);
+ if (password_len > keylen) {
+- EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
++ EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len);
+ }
+- EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
++ EVP_DecryptInit_ex(cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
+ if (options & OPENSSL_ZERO_PADDING) {
+- EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
++ EVP_CIPHER_CTX_set_padding(cipher_ctx, 0);
+ }
+- EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
++ EVP_DecryptUpdate(cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
+ outlen = i;
+- if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
++ if (EVP_DecryptFinal(cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+ outlen += i;
+ outbuf[outlen] = '\0';
+ RETVAL_STRINGL((char *)outbuf, outlen, 0);
+@@ -5386,7 +5702,8 @@ PHP_FUNCTION(openssl_decrypt)
+ if (base64_str) {
+ efree(base64_str);
+ }
+- EVP_CIPHER_CTX_cleanup(&cipher_ctx);
++ EVP_CIPHER_CTX_cleanup(cipher_ctx);
++ EVP_CIPHER_CTX_free(cipher_ctx);
+ }
+ /* }}} */
+
+@@ -5424,6 +5741,7 @@ PHP_FUNCTION(openssl_dh_compute_key)
+ zval *key;
+ char *pub_str;
+ int pub_len;
++ DH *dh;
+ EVP_PKEY *pkey;
+ BIGNUM *pub;
+ char *data;
+@@ -5433,14 +5751,21 @@ PHP_FUNCTION(openssl_dh_compute_key)
+ return;
+ }
+ ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
+- if (!pkey || EVP_PKEY_type(pkey->type) != EVP_PKEY_DH || !pkey->pkey.dh) {
++ if (pkey == NULL) {
++ RETURN_FALSE;
++ }
++ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
++ RETURN_FALSE;
++ }
++ dh = EVP_PKEY_get0_DH(pkey);
++ if (dh == NULL) {
+ RETURN_FALSE;
+ }
+
+ pub = BN_bin2bn((unsigned char*)pub_str, pub_len, NULL);
+
+- data = emalloc(DH_size(pkey->pkey.dh) + 1);
+- len = DH_compute_key((unsigned char*)data, pub, pkey->pkey.dh);
++ data = emalloc(DH_size(dh) + 1);
++ len = DH_compute_key((unsigned char*)data, pub, dh);
+
+ if (len >= 0) {
+ data[len] = 0;
+diff --git a/ext/openssl/tests/bug41033.phpt b/ext/openssl/tests/bug41033.phpt
+index 4aeae66..50c78fe 100644
+--- a/ext/openssl/tests/bug41033.phpt
++++ b/ext/openssl/tests/bug41033.phpt
+@@ -13,11 +13,11 @@ $pub = 'file://' . dirname(__FILE__) . '/' . 'bug41033pub.pem';
+
+ $prkeyid = openssl_get_privatekey($prv, "1234");
+ $ct = "Hello I am some text!";
+-openssl_sign($ct, $signature, $prkeyid, OPENSSL_ALGO_DSS1);
++openssl_sign($ct, $signature, $prkeyid, OPENSSL_VERSION_NUMBER < 0x10100000 ? OPENSSL_ALGO_DSS1 : OPENSSL_ALGO_SHA1);
+ echo "Signature: ".base64_encode($signature) . "\n";
+
+ $pukeyid = openssl_get_publickey($pub);
+-$valid = openssl_verify($ct, $signature, $pukeyid, OPENSSL_ALGO_DSS1);
++$valid = openssl_verify($ct, $signature, $pukeyid, OPENSSL_VERSION_NUMBER < 0x10100000 ? OPENSSL_ALGO_DSS1 : OPENSSL_ALGO_SHA1);
+ echo "Signature validity: " . $valid . "\n";
+
+
+diff --git a/ext/openssl/tests/bug66501.phpt b/ext/openssl/tests/bug66501.phpt
+index 7ad5e21..c2146ab 100644
+--- a/ext/openssl/tests/bug66501.phpt
++++ b/ext/openssl/tests/bug66501.phpt
+@@ -16,7 +16,7 @@ AwEHoUQDQgAEPq4hbIWHvB51rdWr8ejrjWo4qVNWVugYFtPg/xLQw0mHkIPZ4DvK
+ sqOTOnMoezkbSmVVMuwz9flvnqHGmQvmug==
+ -----END EC PRIVATE KEY-----';
+ $key = openssl_pkey_get_private($pkey);
+-$res = openssl_sign($data ='alpha', $sign, $key, 'ecdsa-with-SHA1');
++$res = openssl_sign($data ='alpha', $sign, $key, OPENSSL_VERSION_NUMBER < 0x10100000 ? 'ecdsa-with-SHA1' : 'SHA1');
+ var_dump($res);
+ --EXPECTF--
+ bool(true)
+diff --git a/ext/openssl/tests/openssl_error_string_basic.phpt b/ext/openssl/tests/openssl_error_string_basic.phpt
+index 82f3099..d94048d 100644
+--- a/ext/openssl/tests/openssl_error_string_basic.phpt
++++ b/ext/openssl/tests/openssl_error_string_basic.phpt
+@@ -105,7 +105,7 @@ expect_openssl_errors('openssl_private_decrypt', ['04065072']);
+ // public encrypt and decrypt with failed padding check and padding
+ @openssl_public_encrypt("data", $crypted, $public_key_file, 1000);
+ @openssl_public_decrypt("data", $crypted, $public_key_file);
+-expect_openssl_errors('openssl_private_(en|de)crypt padding', ['0906D06C', '04068076', '0407006A', '04067072']);
++expect_openssl_errors('openssl_private_(en|de)crypt padding', OPENSSL_VERSION_NUMBER < 0x10100000 ? ['0906D06C', '04068076', '0407006A', '04067072'] : ['0906D06C', '04068076', '04067072']);
+
+ // X509
+ echo "X509 errors\n";
+diff --git a/ext/openssl/tests/sni_server.phpt b/ext/openssl/tests/sni_server.phpt
+index d44a69f..ef23258 100644
+--- a/ext/openssl/tests/sni_server.phpt
++++ b/ext/openssl/tests/sni_server.phpt
+@@ -27,6 +27,9 @@ CODE;
+ $clientCode = <<<'CODE'
+ $flags = STREAM_CLIENT_CONNECT;
+ $ctxArr = [
++ 'verify_peer' => false,
++ 'verify_peer_name' => false,
++ 'allow_self_signed' => true,
+ 'cafile' => __DIR__ . '/sni_server_ca.pem',
+ 'capture_peer_cert' => true
+ ];
+diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
+index d549033..c2d477c 100644
+--- a/ext/openssl/xp_ssl.c
++++ b/ext/openssl/xp_ssl.c
+@@ -935,7 +935,7 @@ static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
+ static const SSL_METHOD *php_select_crypto_method(long method_value, int is_client TSRMLS_DC) /* {{{ */
+ {
+ if (method_value == STREAM_CRYPTO_METHOD_SSLv2) {
+-#ifndef OPENSSL_NO_SSL2
++#if !defined(OPENSSL_NO_SSL2) && OPENSSL_VERSION_NUMBER < 0x10100000L
+ return is_client ? SSLv2_client_method() : SSLv2_server_method();
+ #else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+@@ -1588,12 +1588,26 @@ int php_openssl_setup_crypto(php_stream *stream,
+ }
+ /* }}} */
+
++#define PHP_SSL_MAX_VERSION_LEN 32
++
++static char *php_ssl_cipher_get_version(const SSL_CIPHER *c, char *buffer, size_t max_len) /* {{{ */
++{
++ const char *version = SSL_CIPHER_get_version(c);
++ strncpy(buffer, version, max_len);
++ if (max_len <= strlen(version)) {
++ buffer[max_len - 1] = 0;
++ }
++ return buffer;
++}
++/* }}} */
++
+ static zval *capture_session_meta(SSL *ssl_handle) /* {{{ */
+ {
+ zval *meta_arr;
+ char *proto_str;
+ long proto = SSL_version(ssl_handle);
+ const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_handle);
++ char version_str[PHP_SSL_MAX_VERSION_LEN];
+
+ switch (proto) {
+ #if OPENSSL_VERSION_NUMBER >= 0x10001001L
+@@ -1611,7 +1625,7 @@ static zval *capture_session_meta(SSL *ssl_handle) /* {{{ */
+ add_assoc_string(meta_arr, "protocol", proto_str, 1);
+ add_assoc_string(meta_arr, "cipher_name", (char *) SSL_CIPHER_get_name(cipher), 1);
+ add_assoc_long(meta_arr, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL));
+- add_assoc_string(meta_arr, "cipher_version", SSL_CIPHER_get_version(cipher), 1);
++ add_assoc_string(meta_arr, "cipher_version", php_ssl_cipher_get_version(cipher, version_str, PHP_SSL_MAX_VERSION_LEN), 1);
+
+ return meta_arr;
+ }
+diff --git a/ext/phar/util.c b/ext/phar/util.c
+index 828be8f..06e4e55 100644
+--- a/ext/phar/util.c
++++ b/ext/phar/util.c
+@@ -1531,7 +1531,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
+ BIO *in;
+ EVP_PKEY *key;
+ EVP_MD *mdtype = (EVP_MD *) EVP_sha1();
+- EVP_MD_CTX md_ctx;
++ EVP_MD_CTX *md_ctx;
+ #else
+ int tempsig;
+ #endif
+@@ -1608,7 +1608,8 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
+ return FAILURE;
+ }
+
+- EVP_VerifyInit(&md_ctx, mdtype);
++ md_ctx = EVP_MD_CTX_create();
++ EVP_VerifyInit(md_ctx, mdtype);
+ read_len = end_of_phar;
+
+ if (read_len > sizeof(buf)) {
+@@ -1620,7 +1621,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
+ php_stream_seek(fp, 0, SEEK_SET);
+
+ while (read_size && (len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
+- EVP_VerifyUpdate (&md_ctx, buf, len);
++ EVP_VerifyUpdate (md_ctx, buf, len);
+ read_len -= (off_t)len;
+
+ if (read_len < read_size) {
+@@ -1628,9 +1629,9 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
+ }
+ }
+
+- if (EVP_VerifyFinal(&md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
++ if (EVP_VerifyFinal(md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
+ /* 1: signature verified, 0: signature does not match, -1: failed signature operation */
+- EVP_MD_CTX_cleanup(&md_ctx);
++ EVP_MD_CTX_destroy(md_ctx);
+
+ if (error) {
+ spprintf(error, 0, "broken openssl signature");
+@@ -1639,7 +1640,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
+ return FAILURE;
+ }
+
+- EVP_MD_CTX_cleanup(&md_ctx);
++ EVP_MD_CTX_destroy(md_ctx);
+ #endif
+
+ *signature_len = phar_hex_str((const char*)sig, sig_len, signature TSRMLS_CC);
diff --git a/00040_intl-detect-icu-via-pkg-config.patch b/00040_intl-detect-icu-via-pkg-config.patch
new file mode 100644
index 0000000..dea2949
--- /dev/null
+++ b/00040_intl-detect-icu-via-pkg-config.patch
@@ -0,0 +1,154 @@
+Based on the following upstream commits:
+
+https://github.com/php/php-src/commit/9a8e7b571896f39f83cb000fdb7c466b6d328d52
+https://github.com/php/php-src/pull/3701
+https://github.com/php/php-src/commit/2bd299f7318492fd7e5cafffa562d76ba60e69d4
+
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -2201,49 +2201,16 @@ dnl
+ dnl Common setup macro for ICU
+ dnl
+ AC_DEFUN([PHP_SETUP_ICU],[
+- PHP_ARG_WITH(icu-dir,,
+- [ --with-icu-dir=DIR Specify where ICU libraries and headers can be found], DEFAULT, no)
++ PKG_CHECK_MODULES([ICU], [icu-io >= 50.1])
+
+- if test "$PHP_ICU_DIR" = "no"; then
+- PHP_ICU_DIR=DEFAULT
+- fi
+-
+- if test "$PHP_ICU_DIR" = "DEFAULT"; then
+- dnl Try to find icu-config
+- AC_PATH_PROG(ICU_CONFIG, icu-config, no, [$PATH:/usr/local/bin])
+- else
+- ICU_CONFIG="$PHP_ICU_DIR/bin/icu-config"
+- fi
+-
+- AC_MSG_CHECKING([for location of ICU headers and libraries])
+-
+- dnl Trust icu-config to know better what the install prefix is..
+- icu_install_prefix=`$ICU_CONFIG --prefix 2> /dev/null`
+- if test "$?" != "0" || test -z "$icu_install_prefix"; then
+- AC_MSG_RESULT([not found])
+- AC_MSG_ERROR([Unable to detect ICU prefix or $ICU_CONFIG failed. Please verify ICU install prefix and make sure icu-config works.])
+- else
+- AC_MSG_RESULT([$icu_install_prefix])
+-
+- dnl Check ICU version
+- AC_MSG_CHECKING([for ICU 4.0 or greater])
+- icu_version_full=`$ICU_CONFIG --version`
+- ac_IFS=$IFS
+- IFS="."
+- set $icu_version_full
+- IFS=$ac_IFS
+- icu_version=`expr [$]1 \* 1000 + [$]2`
+- AC_MSG_RESULT([found $icu_version_full])
++ PHP_EVAL_INCLINE($ICU_CFLAGS)
++ PHP_EVAL_LIBLINE($ICU_LIBS, $1)
+
+- if test "$icu_version" -lt "4000"; then
+- AC_MSG_ERROR([ICU version 4.0 or later is required])
+- fi
++ ICU_CFLAGS="$ICU_CFLAGS -DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"
++ ICU_CXXFLAGS="$ICU_CXXFLAGS -DUNISTR_FROM_CHAR_EXPLICIT=explicit -DUNISTR_FROM_STRING_EXPLICIT=explicit"
+
+- ICU_VERSION=$icu_version
+- ICU_INCS=`$ICU_CONFIG --cppflags-searchpath`
+- ICU_LIBS=`$ICU_CONFIG --ldflags --ldflags-icuio`
+- PHP_EVAL_INCLINE($ICU_INCS)
+- PHP_EVAL_LIBLINE($ICU_LIBS, $1)
++ if test "$PKG_CONFIG icu-io --atleast-version=60"; then
++ ICU_CFLAGS="$ICU_CFLAGS -DU_HIDE_OBSOLETE_UTF_OLD_H=1"
+ fi
+ ])
+
+--- a/ext/intl/config.m4
++++ b/ext/intl/config.m4
+@@ -9,18 +9,10 @@ if test "$PHP_INTL" != "no"; then
+ PHP_SETUP_ICU(INTL_SHARED_LIBADD)
+ PHP_SUBST(INTL_SHARED_LIBADD)
+ PHP_REQUIRE_CXX()
+- if test "$icu_version" -ge "4002"; then
+- icu_spoof_src=" spoofchecker/spoofchecker_class.c \
+- spoofchecker/spoofchecker.c\
+- spoofchecker/spoofchecker_create.c\
+- spoofchecker/spoofchecker_main.c"
+- else
+- icu_spoof_src=""
+- fi
++ INTL_COMMON_FLAGS="$ICU_CFLAGS -Wno-write-strings -D__STDC_LIMIT_MACROS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
+ PHP_NEW_EXTENSION(intl, php_intl.c \
+ intl_error.c \
+ intl_convert.c \
+- intl_convertcpp.cpp \
+ collator/collator.c \
+ collator/collator_class.c \
+ collator/collator_sort.c \
+@@ -32,8 +24,6 @@ if test "$PHP_INTL" != "no"; then
+ collator/collator_is_numeric.c \
+ collator/collator_error.c \
+ common/common_error.c \
+- common/common_enum.cpp \
+- common/common_date.cpp \
+ converter/converter.c \
+ formatter/formatter.c \
+ formatter/formatter_main.c \
+@@ -53,17 +43,12 @@ if test "$PHP_INTL" != "no"; then
+ dateformat/dateformat_attr.c \
+ dateformat/dateformat_data.c \
+ dateformat/dateformat_format.c \
+- dateformat/dateformat_format_object.cpp \
+ dateformat/dateformat_parse.c \
+- dateformat/dateformat_create.cpp \
+- dateformat/dateformat_attrcpp.cpp \
+- dateformat/dateformat_helpers.cpp \
+ msgformat/msgformat.c \
+ msgformat/msgformat_attr.c \
+ msgformat/msgformat_class.c \
+ msgformat/msgformat_data.c \
+ msgformat/msgformat_format.c \
+- msgformat/msgformat_helpers.cpp \
+ msgformat/msgformat_parse.c \
+ grapheme/grapheme_string.c \
+ grapheme/grapheme_util.c \
+@@ -73,6 +58,20 @@ if test "$PHP_INTL" != "no"; then
+ transliterator/transliterator.c \
+ transliterator/transliterator_class.c \
+ transliterator/transliterator_methods.c \
++ idn/idn.c \
++ spoofchecker/spoofchecker_class.c \
++ spoofchecker/spoofchecker.c\
++ spoofchecker/spoofchecker_create.c\
++ spoofchecker/spoofchecker_main.c, $ext_shared,,$INTL_COMMON_FLAGS,cxx)
++
++ PHP_INTL_CPP_SOURCES="intl_convertcpp.cpp \
++ common/common_enum.cpp \
++ common/common_date.cpp \
++ dateformat/dateformat_format_object.cpp \
++ dateformat/dateformat_create.cpp \
++ dateformat/dateformat_attrcpp.cpp \
++ dateformat/dateformat_helpers.cpp \
++ msgformat/msgformat_helpers.cpp \
+ timezone/timezone_class.cpp \
+ timezone/timezone_methods.cpp \
+ calendar/calendar_class.cpp \
+@@ -83,9 +82,15 @@ if test "$PHP_INTL" != "no"; then
+ breakiterator/breakiterator_methods.cpp \
+ breakiterator/rulebasedbreakiterator_methods.cpp \
+ breakiterator/codepointiterator_internal.cpp \
+- breakiterator/codepointiterator_methods.cpp \
+- idn/idn.c \
+- $icu_spoof_src, $ext_shared,,$ICU_INCS -Wno-write-strings)
++ breakiterator/codepointiterator_methods.cpp"
++
++ PHP_INTL_CPP_FLAGS="$ICU_CXXFLAGS -Wno-write-strings -D__STDC_LIMIT_MACROS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
++ if test "$ext_shared" = "no"; then
++ PHP_ADD_SOURCES(PHP_EXT_DIR(intl), $PHP_INTL_CPP_SOURCES, $PHP_INTL_CPP_FLAGS)
++ else
++ PHP_ADD_SOURCES_X(PHP_EXT_DIR(intl), $PHP_INTL_CPP_SOURCES, $PHP_INTL_CPP_FLAGS, shared_objects_intl, yes)
++ fi
++
+ PHP_ADD_BUILD_DIR($ext_builddir/collator)
+ PHP_ADD_BUILD_DIR($ext_builddir/converter)
+ PHP_ADD_BUILD_DIR($ext_builddir/common)
diff --git a/00050_intl-use-icu-namespace.patch b/00050_intl-use-icu-namespace.patch
new file mode 100644
index 0000000..715adb3
--- /dev/null
+++ b/00050_intl-use-icu-namespace.patch
@@ -0,0 +1,365 @@
+Based on the following upstream commits:
+
+https://github.com/php/php-src/commit/8d35a423838eb462cd39ee535c5d003073cc5f22
+https://github.com/php/php-src/commit/d8200e48857aeaf09f7127751efc5632ef7660a7
+https://github.com/php/php-src/commit/9a8e7b571896f39f83cb000fdb7c466b6d328d52
+
+--- a/ext/intl/breakiterator/breakiterator_class.cpp
++++ b/ext/intl/breakiterator/breakiterator_class.cpp
+@@ -38,6 +38,7 @@ extern "C" {
+ }
+
+ using PHP::CodePointBreakIterator;
++using icu::RuleBasedBreakIterator;
+
+ /* {{{ Global variables */
+ zend_class_entry *BreakIterator_ce_ptr;
+--- a/ext/intl/breakiterator/breakiterator_class.h
++++ b/ext/intl/breakiterator/breakiterator_class.h
+@@ -26,6 +26,8 @@
+
+ #ifndef USE_BREAKITERATOR_POINTER
+ typedef void BreakIterator;
++#else
++using icu::BreakIterator;
+ #endif
+
+ typedef struct {
+--- a/ext/intl/breakiterator/breakiterator_methods.cpp
++++ b/ext/intl/breakiterator/breakiterator_methods.cpp
+@@ -32,6 +32,8 @@ extern "C" {
+ }
+
+ using PHP::CodePointBreakIterator;
++using icu::BreakIterator;
++using icu::Locale;
+
+ U_CFUNC PHP_METHOD(BreakIterator, __construct)
+ {
+--- a/ext/intl/breakiterator/codepointiterator_internal.cpp
++++ b/ext/intl/breakiterator/codepointiterator_internal.cpp
+@@ -31,6 +31,8 @@ typedef union {
+
+ using namespace PHP;
+
++using icu::UCharCharacterIterator;
++
+ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CodePointBreakIterator);
+
+ CodePointBreakIterator::CodePointBreakIterator()
+--- a/ext/intl/breakiterator/codepointiterator_internal.h
++++ b/ext/intl/breakiterator/codepointiterator_internal.h
+@@ -18,8 +18,11 @@
+ #define CODEPOINTITERATOR_INTERNAL_H
+
+ #include <unicode/brkiter.h>
++#include <unicode/unistr.h>
+
+-using U_ICU_NAMESPACE::BreakIterator;
++using icu::BreakIterator;
++using icu::CharacterIterator;
++using icu::UnicodeString;
+
+ namespace PHP {
+
+--- a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp
++++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp
+@@ -25,6 +25,9 @@ extern "C" {
+
+ #include "../intl_convertcpp.h"
+
++using icu::RuleBasedBreakIterator;
++using icu::Locale;
++
+ static inline RuleBasedBreakIterator *fetch_rbbi(BreakIterator_object *bio) {
+ return (RuleBasedBreakIterator*)bio->biter;
+ }
+--- a/ext/intl/calendar/calendar_class.cpp
++++ b/ext/intl/calendar/calendar_class.cpp
+@@ -34,6 +34,9 @@ extern "C" {
+ #include <assert.h>
+ }
+
++using icu::GregorianCalendar;
++using icu::Locale;
++
+ /* {{{ Global variables */
+ zend_class_entry *Calendar_ce_ptr;
+ zend_class_entry *GregorianCalendar_ce_ptr;
+--- a/ext/intl/calendar/calendar_class.h
++++ b/ext/intl/calendar/calendar_class.h
+@@ -26,6 +26,8 @@
+
+ #ifndef USE_CALENDAR_POINTER
+ typedef void Calendar;
++#else
++using icu::Calendar;
+ #endif
+
+ typedef struct {
+--- a/ext/intl/calendar/calendar_methods.cpp
++++ b/ext/intl/calendar/calendar_methods.cpp
+@@ -40,6 +40,8 @@ extern "C" {
+ }
+ #include "../common/common_enum.h"
+
++using icu::Locale;
++
+ U_CFUNC PHP_METHOD(IntlCalendar, __construct)
+ {
+ zend_throw_exception( NULL,
+--- a/ext/intl/calendar/gregoriancalendar_methods.cpp
++++ b/ext/intl/calendar/gregoriancalendar_methods.cpp
+@@ -23,6 +23,8 @@
+ #include <unicode/locid.h>
+ #include <unicode/calendar.h>
+ #include <unicode/gregocal.h>
++#include <unicode/ustring.h>
++
+ extern "C" {
+ #include "../php_intl.h"
+ #define USE_TIMEZONE_POINTER 1
+@@ -32,6 +34,11 @@ extern "C" {
+ #include <ext/date/php_date.h>
+ }
+
++using icu::GregorianCalendar;
++using icu::Locale;
++using icu::UnicodeString;
++using icu::StringPiece;
++
+ static inline GregorianCalendar *fetch_greg(Calendar_object *co) {
+ return (GregorianCalendar*)co->ucal;
+ }
+--- a/ext/intl/common/common_date.cpp
++++ b/ext/intl/common/common_date.cpp
+@@ -25,6 +25,9 @@ extern "C" {
+ #include <ext/date/php_date.h>
+ }
+
++using icu::TimeZone;
++using icu::UnicodeString;
++
+ #ifndef INFINITY
+ #define INFINITY (DBL_MAX+DBL_MAX)
+ #endif
+--- a/ext/intl/common/common_date.h
++++ b/ext/intl/common/common_date.h
+@@ -28,6 +28,8 @@ U_CDECL_END
+
+ #include <unicode/timezone.h>
+
++using icu::TimeZone;
++
+ U_CFUNC TimeZone *timezone_convert_datetimezone(int type, void *object, int is_datetime, intl_error *outside_error, const char *func TSRMLS_DC);
+ U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz,
+ intl_error *err, const char *func TSRMLS_DC);
+--- a/ext/intl/common/common_enum.h
++++ b/ext/intl/common/common_enum.h
+@@ -69,6 +69,7 @@ U_CFUNC void zoi_with_current_get_current_data(zend_object_iterator *iter, zval
+ U_CFUNC void zoi_with_current_invalidate_current(zend_object_iterator *iter TSRMLS_DC);
+
+ #ifdef __cplusplus
++using icu::StringEnumeration;
+ U_CFUNC void IntlIterator_from_StringEnumeration(StringEnumeration *se, zval *object TSRMLS_DC);
+ #endif
+
+--- a/ext/intl/converter/converter.c
++++ b/ext/intl/converter/converter.c
+@@ -18,6 +18,8 @@
+ #include "zend_exceptions.h"
+
+ #include <unicode/utypes.h>
++#include <unicode/utf8.h>
++#include <unicode/utf16.h>
+ #include <unicode/ucnv.h>
+ #include <unicode/ustring.h>
+
+--- a/ext/intl/dateformat/dateformat_format_object.cpp
++++ b/ext/intl/dateformat/dateformat_format_object.cpp
+@@ -33,6 +33,12 @@ extern "C" {
+ #include "../common/common_date.h"
+ }
+
++using icu::Locale;
++using icu::DateFormat;
++using icu::GregorianCalendar;
++using icu::StringPiece;
++using icu::SimpleDateFormat;
++
+ static const DateFormat::EStyle valid_styles[] = {
+ DateFormat::kNone,
+ DateFormat::kFull,
+--- a/ext/intl/dateformat/dateformat_helpers.cpp
++++ b/ext/intl/dateformat/dateformat_helpers.cpp
+@@ -28,6 +28,8 @@ extern "C" {
+ #include "../calendar/calendar_class.h"
+ }
+
++using icu::GregorianCalendar;
++
+ int datefmt_process_calendar_arg(zval* calendar_zv,
+ Locale const& locale,
+ const char *func_name,
+--- a/ext/intl/dateformat/dateformat_helpers.h
++++ b/ext/intl/dateformat/dateformat_helpers.h
+@@ -22,11 +22,16 @@
+ #endif
+
+ #include <unicode/calendar.h>
++#include <unicode/datefmt.h>
+
+ extern "C" {
+ #include "../php_intl.h"
+ }
+
++using icu::Locale;
++using icu::Calendar;
++using icu::DateFormat;
++
+ int datefmt_process_calendar_arg(zval* calendar_zv,
+ Locale const& locale,
+ const char *func_name,
+--- a/ext/intl/grapheme/grapheme_string.c
++++ b/ext/intl/grapheme/grapheme_string.c
+@@ -24,6 +24,7 @@
+ #include "grapheme_util.h"
+
+ #include <unicode/utypes.h>
++#include <unicode/utf8.h>
+ #include <unicode/ucol.h>
+ #include <unicode/ustring.h>
+ #include <unicode/ubrk.h>
+@@ -860,10 +861,10 @@ PHP_FUNCTION(grapheme_extract)
+ pstr = str + start;
+
+ /* just in case pstr points in the middle of a character, move forward to the start of the next char */
+- if ( !UTF8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) {
++ if ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) {
+ unsigned char *str_end = str + str_len;
+
+- while ( !UTF8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) {
++ while ( !U8_IS_SINGLE(*pstr) && !U8_IS_LEAD(*pstr) ) {
+ pstr++;
+ if ( pstr >= str_end ) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+--- a/ext/intl/intl_convertcpp.h
++++ b/ext/intl/intl_convertcpp.h
+@@ -25,6 +25,8 @@
+
+ #include <unicode/unistr.h>
+
++using icu::UnicodeString;
++
+ int intl_stringFromChar(UnicodeString &ret, char *str, int32_t str_len, UErrorCode *status);
+
+ int intl_charFromString(const UnicodeString &from, char **res, int *res_len, UErrorCode *status);
+--- a/ext/intl/msgformat/msgformat_helpers.cpp
++++ b/ext/intl/msgformat/msgformat_helpers.cpp
+@@ -76,6 +76,16 @@ MessageFormatAdapter::getMessagePattern(MessageFormat* m) {
+ #endif
+ U_NAMESPACE_END
+
++using icu::Formattable;
++using icu::Format;
++using icu::DateFormat;
++using icu::MessageFormat;
++#ifdef HAS_MESSAGE_PATTERN
++using icu::MessagePattern;
++#endif
++using icu::MessageFormatAdapter;
++using icu::FieldPosition;
++
+ U_CFUNC int32_t umsg_format_arg_count(UMessageFormat *fmt)
+ {
+ int32_t fmt_count = 0;
+@@ -227,15 +237,16 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo,
+ UnicodeString typeString = mp.getSubstring(type_part);
+ /* This is all based on the rules in the docs for MessageFormat
+ * @see http://icu-project.org/apiref/icu4c/classMessageFormat.html */
+- if (typeString == "number") {
++#define ASCII_LITERAL(s) UNICODE_STRING(s, sizeof(s)-1)
++ if (typeString == ASCII_LITERAL("number")) {
+ MessagePattern::Part style_part = mp.getPart(i + 1); /* Not advancing i */
+ if (style_part.getType() == UMSGPAT_PART_TYPE_ARG_STYLE) {
+ UnicodeString styleString = mp.getSubstring(style_part);
+- if (styleString == "integer") {
++ if (styleString == ASCII_LITERAL("integer")) {
+ type = Formattable::kInt64;
+- } else if (styleString == "currency") {
++ } else if (styleString == ASCII_LITERAL("currency")) {
+ type = Formattable::kDouble;
+- } else if (styleString == "percent") {
++ } else if (styleString == ASCII_LITERAL("percent")) {
+ type = Formattable::kDouble;
+ } else { /* some style invalid/unknown to us */
+ type = Formattable::kDouble;
+@@ -243,12 +254,13 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo,
+ } else { // if missing style, part, make it a double
+ type = Formattable::kDouble;
+ }
+- } else if ((typeString == "date") || (typeString == "time")) {
++ } else if ((typeString == ASCII_LITERAL("date")) || (typeString == ASCII_LITERAL("time"))) {
+ type = Formattable::kDate;
+- } else if ((typeString == "spellout") || (typeString == "ordinal")
+- || (typeString == "duration")) {
++ } else if ((typeString == ASCII_LITERAL("spellout")) || (typeString == ASCII_LITERAL("ordinal"))
++ || (typeString == ASCII_LITERAL("duration"))) {
+ type = Formattable::kDouble;
+ }
++#undef ASCII_LITERAL
+ } else {
+ /* If there's no UMSGPAT_PART_TYPE_ARG_TYPE right after a
+ * UMSGPAT_ARG_TYPE_SIMPLE argument, then the pattern
+--- a/ext/intl/normalizer/normalizer_normalize.c
++++ b/ext/intl/normalizer/normalizer_normalize.c
+@@ -24,6 +24,7 @@
+ #include "normalizer_class.h"
+ #include "normalizer_normalize.h"
+ #include "intl_convert.h"
++#include <unicode/utf8.h>
+
+ /* {{{ proto string Normalizer::normalize( string $input [, string $form = FORM_C] )
+ * Normalize a string. }}} */
+--- a/ext/intl/timezone/timezone_class.cpp
++++ b/ext/intl/timezone/timezone_class.cpp
+@@ -37,6 +37,8 @@ extern "C" {
+ #include <ext/date/php_date.h>
+ }
+
++using icu::Calendar;
++
+ /* {{{ Global variables */
+ U_CDECL_BEGIN
+ zend_class_entry *TimeZone_ce_ptr = NULL;
+--- a/ext/intl/timezone/timezone_class.h
++++ b/ext/intl/timezone/timezone_class.h
+@@ -29,6 +29,8 @@
+
+ #ifndef USE_TIMEZONE_POINTER
+ typedef void TimeZone;
++#else
++using icu::TimeZone;
+ #endif
+
+ typedef struct {
+--- a/ext/intl/timezone/timezone_methods.cpp
++++ b/ext/intl/timezone/timezone_methods.cpp
+@@ -23,6 +23,7 @@
+ #include <unicode/locid.h>
+ #include <unicode/timezone.h>
+ #include <unicode/ustring.h>
++#include <unicode/calendar.h>
+ #include "intl_convertcpp.h"
+
+ #include "../common/common_date.h"
+@@ -37,6 +38,9 @@ extern "C" {
+ }
+ #include "common/common_enum.h"
+
++using icu::Locale;
++using icu::Calendar;
++
+ U_CFUNC PHP_METHOD(IntlTimeZone, __construct)
+ {
+ zend_throw_exception( NULL,
diff --git a/00060_intl-icu-memory-corruption.patch b/00060_intl-icu-memory-corruption.patch
new file mode 100644
index 0000000..1b18f7f
--- /dev/null
+++ b/00060_intl-icu-memory-corruption.patch
@@ -0,0 +1,88 @@
+Based on the following upstream commits:
+
+https://github.com/php/php-src/commit/45a05f38410d4a67c8c83c09906e2cfb42fc6e4c
+https://github.com/php/php-src/commit/534684d1042978f3c21caf9b665a7aca27f3f325
+
+--- a/ext/intl/msgformat/msgformat_helpers.cpp
++++ b/ext/intl/msgformat/msgformat_helpers.cpp
+@@ -27,6 +27,7 @@
+ #include <unicode/timezone.h>
+ #include <unicode/datefmt.h>
+ #include <unicode/calendar.h>
++#include <unicode/strenum.h>
+
+ #include <vector>
+
+@@ -45,6 +46,7 @@ extern "C" {
+
+ #if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ #define HAS_MESSAGE_PATTERN 1
++#define HAS_MISALLOCATE_MEMORY_BUG 1
+ #endif
+
+ U_NAMESPACE_BEGIN
+@@ -345,6 +347,26 @@ static void umsg_set_timezone(MessageFormatter_object *mfo,
+ return; /* already done */
+ }
+
++#ifdef HAS_MISALLOCATE_MEMORY_BUG
++ /* There is a bug in ICU which prevents MessageFormatter::getFormats()
++ to handle more than 10 formats correctly. The enumerator could be
++ used to walk through the present formatters using getFormat(), which
++ however seems to provide just a readonly access. This workaround
++ prevents crash when there are > 10 formats but doesn't set any error.
++ As a result, only DateFormatters with > 10 subformats are affected.
++ This workaround should be ifdef'd out, when the bug has been fixed
++ in ICU. */
++ icu::StringEnumeration* fnames = mf->getFormatNames(err.code);
++ if (!fnames || U_FAILURE(err.code)) {
++ return;
++ }
++ count = fnames->count(err.code);
++ delete fnames;
++ if (count > 10) {
++ return;
++ }
++#endif
++
+ formats = mf->getFormats(count);
+
+ if (formats == NULL) {
+--- /dev/null
++++ b/ext/intl/tests/bug74484_MessageFormatter.phpt
+@@ -0,0 +1,35 @@
++--TEST--
++Bug #74484 MessageFormatter::formatMessage memory corruption with 11+ named placeholder
++--SKIPIF--
++<?php
++if (!extension_loaded('intl'))
++ die('skip intl extension not enabled');
++if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
++ die('skip for ICU 4.8+');
++?>
++--FILE--
++<?php
++$text = "{a} {b} {c} {d} {e} {f} {g} {h} {i} {j} {k} {l}";
++
++$vars = array(
++ 'a' => 1,
++ 'b' => 2,
++ 'c' => 3,
++ 'd' => 4,
++ 'e' => 5,
++ 'f' => 6,
++ 'g' => 7,
++ 'h' => 8,
++ 'i' => 9,
++ 'j' => 10,
++ 'k' => 11,
++ 'l' => 12
++);
++
++var_dump(MessageFormatter::formatMessage('en_US', $text, $vars));
++
++?>
++==DONE==
++--EXPECT--
++string(26) "1 2 3 4 5 6 7 8 9 10 11 12"
++==DONE==
diff --git a/00070_freetype-2.9.1.patch b/00070_freetype-2.9.1.patch
new file mode 100644
index 0000000..02dfd9c
--- /dev/null
+++ b/00070_freetype-2.9.1.patch
@@ -0,0 +1,233 @@
+--- a/ext/gd/config.m4 2018-04-24 11:09:54.000000000 -0400
++++ b/ext/gd/config.m4 2018-05-04 15:18:49.867283889 -0400
+@@ -186,21 +186,36 @@
+ AC_DEFUN([PHP_GD_FREETYPE2],[
+ if test "$PHP_FREETYPE_DIR" != "no"; then
+
+- for i in $PHP_FREETYPE_DIR /usr/local /usr; do
+- if test -f "$i/bin/freetype-config"; then
+- FREETYPE2_DIR=$i
+- FREETYPE2_CONFIG="$i/bin/freetype-config"
+- break
++ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
++ AC_MSG_CHECKING(for freetype2)
++
++ if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists freetype2 ; then
++
++ FREETYPE2_CFLAGS=`$PKG_CONFIG --cflags freetype2`
++ FREETYPE2_LIBS=`$PKG_CONFIG --libs freetype2`
++ FREETYPE2_VERSION=`$PKG_CONFIG --modversion freetype2`
++ FREETYPE2_DIR="found"
++
++ AC_MSG_RESULT(from pkgconfig: version $FREETYPE2_VERSION found)
++ else
++
++ for i in $PHP_FREETYPE_DIR /usr/local /usr; do
++ if test -f "$i/bin/freetype-config"; then
++ FREETYPE2_DIR=$i
++ FREETYPE2_CONFIG="$i/bin/freetype-config"
++ break
++ fi
++ done
++
++ if test -z "$FREETYPE2_DIR"; then
++ AC_MSG_ERROR([freetype-config not found.])
+ fi
+- done
+
+- if test -z "$FREETYPE2_DIR"; then
+- AC_MSG_ERROR([freetype-config not found.])
++ FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
++ FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
++ AC_MSG_RESULT(found via freetype-config)
+ fi
+
+- FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
+- FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
+-
+ PHP_EVAL_INCLINE($FREETYPE2_CFLAGS)
+ PHP_EVAL_LIBLINE($FREETYPE2_LIBS, GD_SHARED_LIBADD)
+ AC_DEFINE(HAVE_LIBFREETYPE,1,[ ])
+--- a/configure 2018-04-24 11:10:05.000000000 -0400
++++ b/configure 2018-05-04 15:18:45.626367913 -0400
+@@ -34348,21 +34348,79 @@
+
+ if test "$PHP_FREETYPE_DIR" != "no"; then
+
+- for i in $PHP_FREETYPE_DIR /usr/local /usr; do
+- if test -f "$i/bin/freetype-config"; then
+- FREETYPE2_DIR=$i
+- FREETYPE2_CONFIG="$i/bin/freetype-config"
+- break
++ # Extract the first word of "pkg-config", so it can be a program name with args.
++set dummy pkg-config; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_path_PKG_CONFIG+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ case $PKG_CONFIG in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++ test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
++ ;;
++esac
++fi
++PKG_CONFIG=$ac_cv_path_PKG_CONFIG
++if test -n "$PKG_CONFIG"; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
++$as_echo "$PKG_CONFIG" >&6; }
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype2" >&5
++$as_echo_n "checking for freetype2... " >&6; }
++
++
++ if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists freetype2 ; then
++
++ FREETYPE2_CFLAGS=`$PKG_CONFIG --cflags freetype2`
++ FREETYPE2_LIBS=`$PKG_CONFIG --libs freetype2`
++ FREETYPE2_VERSION=`$PKG_CONFIG --modversion freetype2`
++ FREETYPE2_DIR="found"
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: from pkgconfig: version $FREETYPE2_VERSION found" >&5
++$as_echo "from pkgconfig: version $FREETYPE2_VERSION found" >&6; }
++ else
++
++ for i in $PHP_FREETYPE_DIR /usr/local /usr; do
++ if test -f "$i/bin/freetype-config"; then
++ FREETYPE2_DIR=$i
++ FREETYPE2_CONFIG="$i/bin/freetype-config"
++ break
++ fi
++ done
++
++ if test -z "$FREETYPE2_DIR"; then
++ as_fn_error $? "freetype-config not found." "$LINENO" 5
+ fi
+- done
+
+- if test -z "$FREETYPE2_DIR"; then
+- as_fn_error $? "freetype-config not found." "$LINENO" 5
++ FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
++ FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found via freetype-config" >&5
++$as_echo "found via freetype-config" >&6; }
+ fi
+
+- FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
+- FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
+-
+
+ for ac_i in $FREETYPE2_CFLAGS; do
+ case $ac_i in
+@@ -36019,21 +36076,78 @@
+
+ if test "$PHP_FREETYPE_DIR" != "no"; then
+
+- for i in $PHP_FREETYPE_DIR /usr/local /usr; do
+- if test -f "$i/bin/freetype-config"; then
+- FREETYPE2_DIR=$i
+- FREETYPE2_CONFIG="$i/bin/freetype-config"
+- break
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype2" >&5
++$as_echo_n "checking for freetype2... " >&6; }
++ # Extract the first word of "pkg-config", so it can be a program name with args.
++set dummy pkg-config; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_path_PKG_CONFIG+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ case $PKG_CONFIG in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++ test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
++ ;;
++esac
++fi
++PKG_CONFIG=$ac_cv_path_PKG_CONFIG
++if test -n "$PKG_CONFIG"; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
++$as_echo "$PKG_CONFIG" >&6; }
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++
++ if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists freetype2 ; then
++
++ FREETYPE2_CFLAGS=`$PKG_CONFIG --cflags freetype2`
++ FREETYPE2_LIBS=`$PKG_CONFIG --libs freetype2`
++ FREETYPE2_VERSION=`$PKG_CONFIG --modversion freetype2`
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: from pkgconfig: version $FREETYPE_VERSON found" >&5
++$as_echo "from pkgconfig: version $FREETYPE_VERSON found" >&6; }
++ else
++
++ for i in $PHP_FREETYPE_DIR /usr/local /usr; do
++ if test -f "$i/bin/freetype-config"; then
++ FREETYPE2_DIR=$i
++ FREETYPE2_CONFIG="$i/bin/freetype-config"
++ break
++ fi
++ done
++
++ if test -z "$FREETYPE2_DIR"; then
++ as_fn_error $? "freetype-config not found." "$LINENO" 5
+ fi
+- done
+
+- if test -z "$FREETYPE2_DIR"; then
+- as_fn_error $? "freetype-config not found." "$LINENO" 5
++ FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
++ FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found via freetype-config" >&5
++$as_echo "found via freetype-config" >&6; }
+ fi
+
+- FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
+- FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
+-
+
+ for ac_i in $FREETYPE2_CFLAGS; do
+ case $ac_i in
diff --git a/00080_secbug-77396.patch b/00080_secbug-77396.patch
new file mode 100644
index 0000000..d470ce9
--- /dev/null
+++ b/00080_secbug-77396.patch
@@ -0,0 +1,50 @@
+From ad4f312d2f550282cddd2ce369fa865c7aa0c309 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 3 Mar 2019 18:22:32 -0800
+Subject: [PATCH] Fix bug #77396 - Null Pointer Dereference in
+ phar_create_or_parse_filename
+
+---
+ ext/phar/phar.c | 3 +++
+ ext/phar/tests/bug77396.phpt | 15 +++++++++++++++
+ 2 files changed, 18 insertions(+)
+ create mode 100644 ext/phar/tests/bug77396.phpt
+
+diff --git a/ext/phar/phar.c b/ext/phar/phar.c
+index dfb8ac1..7cd33d2 100644
+--- a/ext/phar/phar.c
++++ b/ext/phar/phar.c
+@@ -1403,6 +1403,9 @@ int phar_create_or_parse_filename(char *fname, size_t fname_len, char *alias, si
+ /* set up our manifest */
+ mydata = ecalloc(1, sizeof(phar_archive_data));
+ mydata->fname = expand_filepath(fname, NULL TSRMLS_CC);
++ if (mydata->fname == NULL) {
++ return FAILURE;
++ }
+ fname_len = strlen(mydata->fname);
+ #ifdef PHP_WIN32
+ phar_unixify_path_separators(mydata->fname, fname_len);
+diff --git a/ext/phar/tests/bug77396.phpt b/ext/phar/tests/bug77396.phpt
+new file mode 100644
+index 0000000..f7a2a2f
+--- /dev/null
++++ b/ext/phar/tests/bug77396.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++Bug #77396 Relative filename exceeding maximum path length causes null pointer dereference.
++--SKIPIF--
++<?php if (!extension_loaded("phar")) die("skip"); ?>
++--FILE--
++<?php
++$path = '../' . str_repeat("x", PHP_MAXPATHLEN) . '.tar';
++$phar = new PharData($path);
++?>
++--EXPECTF--
++Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Phar creation or opening failed' in %s/bug77396.php:%d
++Stack trace:
++#0 %s/bug77396.php(%d): PharData->__construct(%s)
++#1 {main}
++ thrown in %s/bug77396.php on line %d
+--
+2.1.4
+
diff --git a/00090_secbug-77431.patch b/00090_secbug-77431.patch
new file mode 100644
index 0000000..1d806ca
--- /dev/null
+++ b/00090_secbug-77431.patch
@@ -0,0 +1,45 @@
+From ae1fad5bb773c4c58c2249472b5c06ca05ebe702 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Wed, 9 Jan 2019 14:26:18 +0100
+Subject: [PATCH] Fix #77431 SplFileInfo::__construct() accepts NUL bytes
+
+`SplFileInfo::__construct()` has to expect a path instead of a string,
+analogous to `SplFileObject::__construct()`.
+---
+ ext/spl/spl_directory.c | 2 +-
+ ext/spl/tests/bug77431.phpt | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+ create mode 100644 ext/spl/tests/bug77431.phpt
+
+diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
+index ef2e72d..e690b94 100644
+--- a/ext/spl/spl_directory.c
++++ b/ext/spl/spl_directory.c
+@@ -1131,7 +1131,7 @@ SPL_METHOD(SplFileInfo, __construct)
+
+ zend_replace_error_handling(EH_THROW, spl_ce_RuntimeException, &error_handling TSRMLS_CC);
+
+- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) {
++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &path, &len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+diff --git a/ext/spl/tests/bug77431.phpt b/ext/spl/tests/bug77431.phpt
+new file mode 100644
+index 0000000..eb1ca96
+--- /dev/null
++++ b/ext/spl/tests/bug77431.phpt
+@@ -0,0 +1,9 @@
++--TEST--
++Bug #77431 (SplFileInfo::__construct() accepts NUL bytes)
++--FILE--
++<?php
++new SplFileInfo("bad\0good");
++?>
++--EXPECTF--
++Fatal error: Uncaught exception 'RuntimeException' with message 'SplFileInfo::__construct() expects parameter 1 to be a valid path, string given' in %s:%d
++Stack trace:%A
+\ No newline at end of file
+--
+2.1.4
+
diff --git a/00100_bug77494.patch b/00100_bug77494.patch
new file mode 100644
index 0000000..e4fd26c
--- /dev/null
+++ b/00100_bug77494.patch
@@ -0,0 +1,54 @@
+From 73f222d722460bebb98a1d2f11f891eefe4defde Mon Sep 17 00:00:00 2001
+From: Dmitry Stogov <dmitry@zend.com>
+Date: Thu, 24 Jan 2019 13:06:36 +0300
+Subject: [PATCH] Fixed bug #77494 (Disabling class causes segfault on member
+ access)
+
+---
+ Zend/tests/bug77494.phpt | 16 ++++++++++++++++
+ Zend/zend_API.c | 11 +++++++++++
+ 2 files changed, 27 insertions(+)
+ create mode 100644 Zend/tests/bug77494.phpt
+
+diff --git a/Zend/tests/bug77494.phpt b/Zend/tests/bug77494.phpt
+new file mode 100644
+index 000000000000..1793f6b219d5
+--- /dev/null
++++ b/Zend/tests/bug77494.phpt
+@@ -0,0 +1,16 @@
++--TEST--
++Bug #77494 (Disabling class causes segfault on member access)
++--SKIPIF--
++<?php if (!extension_loaded("curl")) exit("skip curl extension not loaded"); ?>
++--INI--
++disable_classes=CURLFile
++--FILE--
++<?php
++$a = new CURLFile();
++var_dump($a->name);
++?>
++--EXPECTF--
++Warning: CURLFile() has been disabled for security reasons in %sbug77494.php on line 2
++
++Notice: Undefined property: CURLFile::$name in %sbug77494.php on line 3
++NULL
+diff --git a/Zend/zend_API.c b/Zend/zend_API.c
+index 600520552c52..d4b1502734f1 100644
+--- a/Zend/zend_API.c
++++ b/Zend/zend_API.c
+@@ -2855,5 +2855,15 @@ static zend_object *display_disabled_class(zend_class_entry *class_type) /* {{{
+ zend_object *intern;
++ int i;
+ retval = zend_objects_new(&intern, class_type TSRMLS_CC);
++
++ /* Initialize default properties */
++ if (EXPECTED(class_type->default_properties_count != 0)) {
++ intern->properties_table = emalloc(sizeof(zval*) * class_type->default_properties_count);
++ for (i = 0; i < class_type->default_properties_count; i++) {
++ intern->properties_table[i] = NULL;
++ }
++ }
++
+ zend_error(E_WARNING, "%s() has been disabled for security reasons", class_type->name);
+ return retval;
+ }
diff --git a/00110_secbug-77509.patch b/00110_secbug-77509.patch
new file mode 100644
index 0000000..2a79600
--- /dev/null
+++ b/00110_secbug-77509.patch
@@ -0,0 +1,47 @@
+commit 25aa5f434dfb3337a6617b46224f1b505053d8e9
+Author: Stanislav Malyshev <stas@php.net>
+Date: Fri Mar 1 23:25:45 2019 -0800
+
+ Fix integer overflows on 32-bits
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index cbde3effed..b4563927a5 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -3567,10 +3567,10 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
+ tag_table_type tag_table = exif_get_tag_table(section_index);
+
+ if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) {
+- return FALSE;
+- }
++ return FALSE;
++ }
+
+- if (ImageInfo->FileSize >= dir_offset+2) {
++ if (ImageInfo->FileSize >= 2 && ImageInfo->FileSize - 2 >= dir_offset) {
+ sn = exif_file_sections_add(ImageInfo, M_PSEUDO, 2, NULL);
+ #ifdef EXIF_DEBUG
+ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read from TIFF: filesize(x%04X), IFD dir(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, 2);
+@@ -3578,8 +3578,8 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
+ php_stream_seek(ImageInfo->infile, dir_offset, SEEK_SET); /* we do not know the order of sections */
+ php_stream_read(ImageInfo->infile, (char*)ImageInfo->file.list[sn].data, 2);
+ num_entries = php_ifd_get16u(ImageInfo->file.list[sn].data, ImageInfo->motorola_intel);
+- dir_size = 2/*num dir entries*/ +12/*length of entry*/*num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/;
+- if (ImageInfo->FileSize >= dir_offset+dir_size) {
++ dir_size = 2/*num dir entries*/ +12/*length of entry*/*(size_t)num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/;
++ if (ImageInfo->FileSize >= dir_size && ImageInfo->FileSize - dir_size >= dir_offset) {
+ #ifdef EXIF_DEBUG
+ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read from TIFF: filesize(x%04X), IFD dir(x%04X + x%04X), IFD entries(%d)", ImageInfo->FileSize, dir_offset+2, dir_size-2, num_entries);
+ #endif
+@@ -3662,9 +3662,9 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
+ }
+ }
+ }
+- if (ImageInfo->FileSize >= dir_offset + ImageInfo->file.list[sn].size) {
++ if (ImageInfo->FileSize >= ImageInfo->file.list[sn].size && ImageInfo->FileSize - ImageInfo->file.list[sn].size >= dir_offset) {
+ if (ifd_size > dir_size) {
+- if (dir_offset + ifd_size > ImageInfo->FileSize) {
++ if (ImageInfo->FileSize < ifd_size || dir_offset > ImageInfo->FileSize - ifd_size) {
+ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Error in TIFF: filesize(x%04X) less than size of IFD(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, ifd_size);
+ return FALSE;
+ }
diff --git a/00120_secbug-77540.patch b/00120_secbug-77540.patch
new file mode 100644
index 0000000..aa149d9
--- /dev/null
+++ b/00120_secbug-77540.patch
Binary files differ
diff --git a/00130_secbug-77563.patch b/00130_secbug-77563.patch
new file mode 100644
index 0000000..8101032
--- /dev/null
+++ b/00130_secbug-77563.patch
Binary files differ
diff --git a/00140_secbug-77586.patch b/00140_secbug-77586.patch
new file mode 100644
index 0000000..a4d0795
--- /dev/null
+++ b/00140_secbug-77586.patch
@@ -0,0 +1,83 @@
+From e0f5d62bd6690169998474b62f92a8c5ddf0e699 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 3 Mar 2019 22:33:38 -0800
+Subject: [PATCH] Fix bug #77586 - phar_tar_writeheaders_int() buffer overflow
+
+---
+ ext/phar/tar.c | 7 ++++++-
+ ext/phar/tests/bug71488.phpt | 5 +++--
+ ext/phar/tests/bug77586.phpt | 21 +++++++++++++++++++++
+ ...oua6VE-dne29hvpNWXiVbepwIf8-NRHWM9LITLo3nXZnKVNC | 1 +
+ 5 files changed, 37 insertions(+), 8 deletions(-)
+ create mode 100644 ext/phar/tests/bug77586.phpt
+ create mode 100644 ext/phar/tests/bug77586/files/link-nktarAMLdJBv7BGYnpzg-ZDycSpWN3Ne3kacltOSE-EqfhStJ1EoBpGuoua6VE-dne29hvpNWXiVbepwIf8-NRHWM9LITLo3nXZnKVNC
+
+diff --git a/ext/phar/tar.c b/ext/phar/tar.c
+index 9de3047..20f6882 100644
+--- a/ext/phar/tar.c
++++ b/ext/phar/tar.c
+@@ -762,7 +762,12 @@ static int phar_tar_writeheaders_int(phar_entry_info *entry, void *argument) /*
+ header.typeflag = entry->tar_type;
+
+ if (entry->link) {
+- strncpy(header.linkname, entry->link, strlen(entry->link));
++ if (strlcpy(header.linkname, entry->link, sizeof(header.linkname)) >= sizeof(header.linkname)) {
++ if (fp->error) {
++ spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, link \"%s\" is too long for format", entry->phar->fname, entry->link);
++ }
++ return ZEND_HASH_APPLY_STOP;
++ }
+ }
+
+ strncpy(header.magic, "ustar", sizeof("ustar")-1);
+diff --git a/ext/phar/tests/bug71488.phpt b/ext/phar/tests/bug71488.phpt
+index 53f1304..9c58d89 100644
+--- a/ext/phar/tests/bug71488.phpt
++++ b/ext/phar/tests/bug71488.phpt
+@@ -13,5 +13,6 @@
+ <?php
+ @unlink(__DIR__."/bug71488.test");
+ ?>
+---EXPECT--
+-DONE
+\ No newline at end of file
++--EXPECTF--
++Fatal error: Uncaught BadMethodCallException: tar-based phar "%s/bug71488.test" cannot be created, link "%s" is too long for format in %sbug71488.php:%d
++Stack trace:%A
+diff --git a/ext/phar/tests/bug77586.phpt b/ext/phar/tests/bug77586.phpt
+new file mode 100644
+index 0000000..039cc16
+--- /dev/null
++++ b/ext/phar/tests/bug77586.phpt
+@@ -0,0 +1,21 @@
++--TEST--
++Bug #77586 Symbolic link names in tar-formatted phar must be less than 100 bytes.
++--SKIPIF--
++<?php if (!extension_loaded("phar") || true /* blocked by bug 65332 */) die("skip"); ?>
++--FILE--
++<?php
++$dir = __DIR__."/bug77586";
++$phar = new PharData($dir . "/bug77586.tar");
++$phar->buildFromDirectory($dir . "/files");
++?>
++--CLEAN--
++<?php
++$dir = __DIR__."/bug77586";
++unlink($dir . "/bug77586.tar");
++?>
++--EXPECTF--
++Fatal error: Uncaught PharException: tar-based phar "%s/bug77586.tar" cannot be created, link "%s" is too long for format %s
++Stack trace:
++#0 %s/bug77586.php(%d): PharData->buildFromDirectory('%s')
++#1 {main}
++ thrown in %s/bug77586.php %s on line %d
+diff --git a/ext/phar/tests/bug77586/files/link-nktarAMLdJBv7BGYnpzg-ZDycSpWN3Ne3kacltOSE-EqfhStJ1EoBpGuoua6VE-dne29hvpNWXiVbepwIf8-NRHWM9LITLo3nXZnKVNC b/ext/phar/tests/bug77586/files/link-nktarAMLdJBv7BGYnpzg-ZDycSpWN3Ne3kacltOSE-EqfhStJ1EoBpGuoua6VE-dne29hvpNWXiVbepwIf8-NRHWM9LITLo3nXZnKVNC
+new file mode 100644
+index 0000000..1de5659
+--- /dev/null
++++ b/ext/phar/tests/bug77586/files/link-nktarAMLdJBv7BGYnpzg-ZDycSpWN3Ne3kacltOSE-EqfhStJ1EoBpGuoua6VE-dne29hvpNWXiVbepwIf8-NRHWM9LITLo3nXZnKVNC
+@@ -0,0 +1 @@
++target
+\ No newline at end of file
+--
+2.1.4
diff --git a/00150_secbug-77630.patch b/00150_secbug-77630.patch
new file mode 100644
index 0000000..ed48d36
--- /dev/null
+++ b/00150_secbug-77630.patch
@@ -0,0 +1,89 @@
+From e3133e4db70476fb7adfdedb738483e2255ce0e1 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sat, 2 Mar 2019 23:42:53 -0800
+Subject: [PATCH] Fix bug #77630 - safer rename() procedure
+
+In order to rename safer, we do the following:
+- set umask to 077 (unfortunately, not TS, so excluding ZTS)
+- chown() first, to set proper group before allowing group access
+- chmod() after, even if chown() fails
+---
+ main/streams/plain_wrapper.c | 51 +++++++++++++++++++++++++++++---------------
+ 1 file changed, 34 insertions(+), 17 deletions(-)
+
+diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
+index af890a9..7fdf906 100644
+--- a/main/streams/plain_wrapper.c
++++ b/main/streams/plain_wrapper.c
+@@ -1168,34 +1168,51 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f
+ # ifdef EXDEV
+ if (errno == EXDEV) {
+ struct stat sb;
++# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(NETWARE)
++ /* not sure what to do in ZTS case, umask is not thread-safe */
++ int oldmask = umask(077);
++# endif
++ int success = 0;
+ if (php_copy_file(url_from, url_to TSRMLS_CC) == SUCCESS) {
+ if (VCWD_STAT(url_from, &sb) == 0) {
++ success = 1;
+ # if !defined(TSRM_WIN32) && !defined(NETWARE)
+- if (VCWD_CHMOD(url_to, sb.st_mode)) {
+- if (errno == EPERM) {
+- php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
+- VCWD_UNLINK(url_from);
+- return 1;
+- }
++ /*
++ * Try to set user and permission info on the target.
++ * If we're not root, then some of these may fail.
++ * We try chown first, to set proper group info, relying
++ * on the system environment to have proper umask to not allow
++ * access to the file in the meantime.
++ */
++ if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) {
+ php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
+- return 0;
++ if (errno != EPERM) {
++ success = 0;
++ }
+ }
+- if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) {
+- if (errno == EPERM) {
++
++ if (success) {
++ if (VCWD_CHMOD(url_to, sb.st_mode)) {
+ php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
+- VCWD_UNLINK(url_from);
+- return 1;
++ if (errno != EPERM) {
++ success = 0;
++ }
+ }
+- php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
+- return 0;
+ }
+ # endif
+- VCWD_UNLINK(url_from);
+- return 1;
++ if (success) {
++ VCWD_UNLINK(url_from);
++ }
++ } else {
++ php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
+ }
++ } else {
++ php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
+ }
+- php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
+- return 0;
++# if !defined(ZTS) && !defined(TSRM_WIN32) && !defined(NETWARE)
++ umask(oldmask);
++# endif
++ return success;
+ }
+ # endif
+ #endif
+--
+2.1.4
+
diff --git a/bug77540.jpg b/bug77540.jpg
new file mode 100644
index 0000000..559022d
--- /dev/null
+++ b/bug77540.jpg
Binary files differ
diff --git a/bug77563.jpg b/bug77563.jpg
new file mode 100644
index 0000000..d628015
--- /dev/null
+++ b/bug77563.jpg
Binary files differ