diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 05655aa41515..ca084981195b 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2995,17 +2995,12 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen switch(phar->sig_flags) { default: { - char *digest = NULL; - size_t digest_len; - char *signature_error = NULL; - if (FAILURE == phar_create_signature(phar, newfile, &digest, &digest_len, &signature_error)) { + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { spprintf(error, 0, "phar error: unable to write signature: %s", signature_error); efree(signature_error); - if (digest) { - efree(digest); - } if (must_close_old_file) { php_stream_close(oldfile); } @@ -3013,14 +3008,14 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_flush_ex(phar_archive_data *phar, zen return EOF; } - php_stream_write(newfile, digest, digest_len); - efree(digest); + php_stream_write(newfile, ZSTR_VAL(signature), ZSTR_LEN(signature)); if (phar->sig_flags == PHAR_SIG_OPENSSL || phar->sig_flags == PHAR_SIG_OPENSSL_SHA256 || phar->sig_flags == PHAR_SIG_OPENSSL_SHA512) { - phar_set_32(sig_buf, digest_len); + phar_set_32(sig_buf, ZSTR_LEN(signature)); php_stream_write(newfile, sig_buf, 4); } + zend_string_release_ex(signature, false); break; } } diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 4afe485ddf76..f2ac683d8b25 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -413,7 +413,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(3) zend_result phar_open_executed_filename(char *ali zend_result phar_free_alias(const phar_archive_data *phar); zend_result phar_get_archive(phar_archive_data **archive, const char *fname, size_t fname_len, const char *alias, size_t alias_len, char **error); zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, const char *fname, char **signature, size_t *signature_len, char **error); -ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error); +ZEND_ATTRIBUTE_NONNULL zend_string* phar_create_signature(phar_archive_data *phar, php_stream *fp, char **error); /* utility functions */ zend_string *phar_create_default_stub(const zend_string *php_index_str, const zend_string *web_index_str, char **error); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 7492fed85748..efb1932a737a 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -968,9 +968,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze phar_entry_info entry = {0}; php_stream *oldfile, *newfile; bool must_close_old_file = false; - size_t signature_length; struct _phar_pass_tar_info pass; - char *buf, *signature, sigbuf[8]; + char *buf, sigbuf[8]; entry.flags = PHAR_ENT_PERM_DEF_FILE; entry.timestamp = time(NULL); @@ -1168,7 +1167,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */ if (!phar->is_data || phar->sig_flags) { char *signature_error = NULL; - if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, &signature_error)) { + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { spprintf(error, 0, "phar error: unable to write signature to tar-based phar: %s", signature_error); efree(signature_error); @@ -1184,7 +1184,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze if (entry.fp == NULL) { *error = estrdup("phar error: unable to create temporary file"); - efree(signature); + zend_string_release_ex(signature, false); if (must_close_old_file) { php_stream_close(oldfile); } @@ -1203,10 +1203,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze # define PHAR_SET_32(destination, source) memcpy(destination, &source, 4) #endif PHAR_SET_32(sigbuf, phar->sig_flags); - PHAR_SET_32(sigbuf + 4, signature_length); + PHAR_SET_32(sigbuf + 4, ZSTR_LEN(signature)); - if (8 != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) { - efree(signature); + if (8 != php_stream_write(entry.fp, sigbuf, 8) || ZSTR_LEN(signature) != php_stream_write(entry.fp, ZSTR_VAL(signature), ZSTR_LEN(signature))) { + zend_string_release_ex(signature, false); spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", ZSTR_VAL(phar->fname)); if (must_close_old_file) { @@ -1218,11 +1218,11 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 4) int phar_tar_flush(phar_archive_data *phar, ze ALLOCA_FLAG(use_heap); ZSTR_ALLOCA_INIT(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1, use_heap); - efree(signature); - entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8; + entry.uncompressed_filesize = entry.compressed_filesize = ZSTR_LEN(signature) + 8; /* throw out return value and write the signature */ phar_tar_writeheaders_int(&entry, &pass); ZSTR_ALLOCA_FREE(entry.filename, use_heap); + zend_string_release_ex(signature, false); if (*error) { if (must_close_old_file) { diff --git a/ext/phar/util.c b/ext/phar/util.c index 136dae4f882d..363d63177e60 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -1801,8 +1801,9 @@ zend_result phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t s } /* }}} */ -ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */ +ZEND_ATTRIBUTE_NONNULL zend_string* phar_create_signature(phar_archive_data *phar, php_stream *fp, char **error) /* {{{ */ { + zend_string *signature = NULL; unsigned char buf[1024]; size_t sig_len; @@ -1825,8 +1826,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_SHA512Final(digest, &context); - *signature = estrndup((char *) digest, 64); - *signature_length = 64; + signature = zend_string_init((const char*)digest, 64, false); break; } default: @@ -1843,8 +1843,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_SHA256Final(digest, &context); - *signature = estrndup((char *) digest, 32); - *signature_length = 32; + signature = zend_string_init((const char*)digest, 32, false); break; } case PHAR_SIG_OPENSSL_SHA512: @@ -1870,7 +1869,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar if (in == NULL) { spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); - return FAILURE; + return NULL; } key = PEM_read_bio_PrivateKey(in, NULL,NULL, ""); @@ -1878,14 +1877,14 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar if (!key) { *error = estrdup("unable to process private key"); - return FAILURE; + return NULL; } md_ctx = EVP_MD_CTX_create(); if (md_ctx == NULL) { EVP_PKEY_free(key); spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); - return FAILURE; + return NULL; } siglen = EVP_PKEY_size(key); @@ -1896,7 +1895,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); - return FAILURE; + return NULL; } while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) { @@ -1905,7 +1904,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", ZSTR_VAL(phar->fname)); - return FAILURE; + return NULL; } } @@ -1914,12 +1913,14 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar EVP_MD_CTX_destroy(md_ctx); efree(sigbuf); spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); - return FAILURE; + return NULL; } sigbuf[siglen] = '\0'; EVP_PKEY_free(key); EVP_MD_CTX_destroy(md_ctx); + signature = zend_string_init((const char*)sigbuf, siglen, false); + efree(sigbuf); #else size_t siglen; sigbuf = NULL; @@ -1928,11 +1929,11 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar if (FAILURE == phar_call_openssl_signverify(true, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) { spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", ZSTR_VAL(phar->fname)); - return FAILURE; + return NULL; } + signature = zend_string_init((const char*)sigbuf, siglen, false); + efree(sigbuf); #endif - *signature = (char *) sigbuf; - *signature_length = siglen; } break; case PHAR_SIG_SHA1: { @@ -1946,8 +1947,7 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_SHA1Final(digest, &context); - *signature = estrndup((char *) digest, 20); - *signature_length = 20; + signature = zend_string_init((const char*)digest, 20, false); break; } case PHAR_SIG_MD5: { @@ -1961,14 +1961,13 @@ ZEND_ATTRIBUTE_NONNULL zend_result phar_create_signature(phar_archive_data *phar } PHP_MD5Final(digest, &context); - *signature = estrndup((char *) digest, 16); - *signature_length = 16; + signature = zend_string_init((const char*)digest, 16, false); break; } } - phar->sig_len = phar_hex_str((const char *)*signature, *signature_length, &phar->signature); - return SUCCESS; + phar->sig_len = phar_hex_str(ZSTR_VAL(signature), ZSTR_LEN(signature), &phar->signature); + return signature; } /* }}} */ diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 44d962dae39d..67b0f418826a 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -1148,8 +1148,7 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar { /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */ if (!phar->is_data || phar->sig_flags) { - size_t signature_length; - char *signature, sigbuf[8]; + char sigbuf[8]; phar_entry_info entry = {0}; php_stream *newfile; zend_off_t tell; @@ -1171,11 +1170,10 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar } char *signature_error = NULL; - if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, &signature_error)) { - if (signature_error) { - spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar: %s", signature_error); - efree(signature_error); - } + zend_string *signature = phar_create_signature(phar, newfile, &signature_error); + if (!signature) { + spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar: %s", signature_error); + efree(signature_error); php_stream_close(newfile); return FAILURE; @@ -1185,17 +1183,17 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar entry.fp_type = PHAR_MOD; entry.is_modified = 1; if (entry.fp == NULL) { - efree(signature); + zend_string_release_ex(signature, false); spprintf(pass->error, 0, "phar error: unable to create temporary file for signature"); php_stream_close(newfile); return FAILURE; } PHAR_SET_32(sigbuf, phar->sig_flags); - PHAR_SET_32(sigbuf + 4, signature_length); + PHAR_SET_32(sigbuf + 4, ZSTR_LEN(signature)); - if (Z_UL(8) != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) { - efree(signature); + if (Z_UL(8) != php_stream_write(entry.fp, sigbuf, 8) || ZSTR_LEN(signature) != php_stream_write(entry.fp, ZSTR_VAL(signature), ZSTR_LEN(signature))) { + zend_string_release_ex(signature, false); if (pass->error) { spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar %s", ZSTR_VAL(phar->fname)); } @@ -1206,13 +1204,13 @@ static zend_result phar_zip_applysignature(phar_archive_data *phar, struct _phar ALLOCA_FLAG(use_heap); ZSTR_ALLOCA_INIT(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1, use_heap); - efree(signature); - entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8; + entry.uncompressed_filesize = entry.compressed_filesize = ZSTR_LEN(signature) + 8; entry.phar = phar; /* throw out return value and write the signature */ phar_zip_changed_apply_int(&entry, (void *)pass); ZSTR_ALLOCA_FREE(entry.filename, use_heap); php_stream_close(newfile); + zend_string_release_ex(signature, false); if (pass->error && *(pass->error)) { /* error is set by writeheaders */