1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

phar: Get rid of bailouts in Phar::webPhar() (#20190)

Bailouts are bad because they stop the GC etc. They also hide leaks.
This makes the behaviour equivalent to exit(), as it's meant to stop
the request (which is why bailout was used).

We also have to fix some leaks that pop up then.
This commit is contained in:
Niels Dossche
2025-10-16 23:01:41 +02:00
committed by GitHub
parent 984416dde3
commit fbac7a366f

View File

@@ -699,6 +699,7 @@ PHP_METHOD(Phar, webPhar)
zval params, retval;
ZVAL_STRINGL(&params, entry, entry_len);
efree(entry);
rewrite_fci.param_count = 1;
rewrite_fci.params = &params;
@@ -716,9 +717,10 @@ PHP_METHOD(Phar, webPhar)
switch (Z_TYPE(retval)) {
case IS_STRING:
efree(entry);
/* TODO: avoid relocation??? */
entry = estrndup(Z_STRVAL_P(rewrite_fci.retval), Z_STRLEN_P(rewrite_fci.retval));
entry_len = Z_STRLEN_P(rewrite_fci.retval);
zval_ptr_dtor_str(&retval);
break;
case IS_TRUE:
case IS_FALSE:
@@ -729,15 +731,16 @@ PHP_METHOD(Phar, webPhar)
}
efree(pt);
zend_bailout();
zend_throw_unwind_exit();
return;
default:
zval_ptr_dtor(&retval);
zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: rewrite callback must return a string or false");
cleanup_fail:
if (free_pathinfo) {
efree(path_info);
}
efree(entry);
efree(pt);
#ifdef PHP_WIN32
efree(fname);
@@ -752,6 +755,10 @@ cleanup_fail:
if (!entry_len || (entry_len == 1 && entry[0] == '/')) {
efree(entry);
efree(pt);
bool is_entry_allocated = false;
/* direct request */
if (index_php_len) {
entry = index_php;
@@ -759,22 +766,17 @@ cleanup_fail:
if (entry[0] != '/') {
spprintf(&entry, 0, "/%s", index_php);
++entry_len;
is_entry_allocated = true;
}
} else {
/* assume "index.php" is starting point */
entry = estrndup("/index.php", sizeof("/index.php"));
entry = "/index.php";
entry_len = sizeof("/index.php")-1;
}
if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) ||
(info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) {
phar_do_404(phar, fname, fname_len, f404);
if (free_pathinfo) {
efree(path_info);
}
zend_bailout();
} else {
char *tmp = NULL, sa = '\0';
sapi_header_line ctr = {0};
@@ -801,21 +803,32 @@ cleanup_fail:
*tmp = sa;
}
if (free_pathinfo) {
efree(path_info);
}
sapi_header_op(SAPI_HEADER_REPLACE, &ctr);
sapi_send_headers();
efree((void *) ctr.line);
zend_bailout();
}
if (is_entry_allocated) {
efree(entry);
}
if (free_pathinfo) {
efree(path_info);
}
zend_throw_unwind_exit();
return;
}
if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, NULL) ||
(info = phar_get_entry_info(phar, entry, entry_len, NULL, false)) == NULL) {
efree(entry);
efree(pt);
if (free_pathinfo) {
efree(path_info);
}
phar_do_404(phar, fname, fname_len, f404);
zend_bailout();
zend_throw_unwind_exit();
return;
}
if (mimeoverride && zend_hash_num_elements(Z_ARRVAL_P(mimeoverride))) {