From 5a6d58d591960e0695a274278f11b1a196b4e82e Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 21 Apr 2025 13:10:27 +0100 Subject: [PATCH 1/2] ext/openssl: various arrays optimisations. pre-allocated sizes and/or packed arrays. --- ext/openssl/openssl.c | 15 ++++++++++----- ext/openssl/openssl_backend_common.c | 7 ++++--- ext/openssl/xp_ssl.c | 7 ++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index b17159d46aabc..d386e33216e5f 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1063,17 +1063,20 @@ PHP_FUNCTION(openssl_x509_parse) add_assoc_string(return_value, "signatureTypeSN", (char*)OBJ_nid2sn(sig_nid)); add_assoc_string(return_value, "signatureTypeLN", (char*)OBJ_nid2ln(sig_nid)); add_assoc_long(return_value, "signatureTypeNID", sig_nid); - array_init(&subitem); + + int x509_count = X509_PURPOSE_get_count(); + array_init_size(&subitem, x509_count); /* NOTE: the purposes are added as integer keys - the keys match up to the X509_PURPOSE_SSL_XXX defines in x509v3.h */ - for (i = 0; i < X509_PURPOSE_get_count(); i++) { + for (i = 0; i < x509_count; i++) { int id, purpset; char * pname; X509_PURPOSE * purp; zval subsub; - array_init(&subsub); + array_init_size(&subsub, 3); + zend_hash_real_init_packed(Z_ARRVAL(subsub)); purp = X509_PURPOSE_get0(i); id = X509_PURPOSE_get_id(purp); @@ -4138,15 +4141,16 @@ PHP_FUNCTION(openssl_seal) ZEND_TRY_ASSIGN_REF_NEW_STR(sealdata, zend_string_init((char*)buf, len1 + len2, 0)); efree(buf); - ekeys = zend_try_array_init(ekeys); + ekeys = zend_try_array_init_size(ekeys, nkeys); if (!ekeys) { EVP_CIPHER_CTX_free(ctx); goto clean_exit; } + zend_hash_real_init_packed(Z_ARRVAL_P(ekeys)); for (i=0; issl_handle); if (chain && sk_X509_num(chain) > 0) { - int i; - array_init(&arr); + int i, num_chains = sk_X509_num(chain); + array_init_size(&arr, num_chains); + zend_hash_real_init_packed(Z_ARRVAL(arr)); for (i = 0; i < sk_X509_num(chain); i++) { X509 *mycert = X509_dup(sk_X509_value(chain, i)); @@ -1761,7 +1762,7 @@ static int php_openssl_capture_peer_certs(php_stream *stream, object_init_ex(&zcert, php_openssl_certificate_ce); cert_object = Z_OPENSSL_CERTIFICATE_P(&zcert); cert_object->x509 = mycert; - add_next_index_zval(&arr, &zcert); + add_index_zval(&arr, i, &zcert); } } else { From c7424fd033ec9641d72cf7723e4fc3100936f326 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 22 Apr 2025 12:24:23 +0100 Subject: [PATCH 2/2] add array_init* variants --- Zend/zend_API.h | 10 ++++++++++ ext/openssl/openssl.c | 3 +-- ext/openssl/openssl_backend_common.c | 3 +-- ext/openssl/xp_ssl.c | 3 +-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index a644de8e15134..418aa319c127e 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -536,6 +536,16 @@ ZEND_API const char *zend_get_type_by_const(int type); #define array_init(arg) ZVAL_ARR((arg), zend_new_array(0)) #define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size)) +#define array_init_packed(arg) \ + do { \ + array_init(arg); \ + zend_hash_real_init_packed(Z_ARRVAL_P(arg)); \ + } while (0) +#define array_init_packed_size(arg, size) \ + do { \ + array_init_size(arg, size); \ + zend_hash_real_init_packed(Z_ARRVAL_P(arg)); \ + } while (0) ZEND_API void object_init(zval *arg); ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *ce); ZEND_API zend_result object_init_with_constructor(zval *arg, zend_class_entry *class_type, uint32_t param_count, zval *params, HashTable *named_params); diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index d386e33216e5f..1e1ed717971a4 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1075,8 +1075,7 @@ PHP_FUNCTION(openssl_x509_parse) X509_PURPOSE * purp; zval subsub; - array_init_size(&subsub, 3); - zend_hash_real_init_packed(Z_ARRVAL(subsub)); + array_init_packed_size(&subsub, 3); purp = X509_PURPOSE_get0(i); id = X509_PURPOSE_get_id(purp); diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index cc0e4eaaef7df..60881a2947157 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -83,8 +83,7 @@ void php_openssl_add_assoc_name_entry(zval * val, char * key, X509_NAME * name, if (Z_TYPE_P(data) == IS_ARRAY) { add_next_index_stringl(data, (const char *)to_add, to_add_len); } else if (Z_TYPE_P(data) == IS_STRING) { - array_init_size(&tmp, 2); - zend_hash_real_init_packed(Z_ARRVAL(tmp)); + array_init_packed_size(&tmp, 2); add_index_str(&tmp, 0, zend_string_copy(Z_STR_P(data))); add_index_stringl(&tmp, 1, (const char *)to_add, to_add_len); zend_hash_str_update(Z_ARRVAL(subitem), sname, strlen(sname), &tmp); diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 3dccbab1d27dc..a67ab9150bb54 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1753,8 +1753,7 @@ static int php_openssl_capture_peer_certs(php_stream *stream, if (chain && sk_X509_num(chain) > 0) { int i, num_chains = sk_X509_num(chain); - array_init_size(&arr, num_chains); - zend_hash_real_init_packed(Z_ARRVAL(arr)); + array_init_packed_size(&arr, num_chains); for (i = 0; i < sk_X509_num(chain); i++) { X509 *mycert = X509_dup(sk_X509_value(chain, i));