Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions ext/phar/phar_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -716,9 +717,10 @@ PHP_METHOD(Phar, webPhar)

switch (Z_TYPE(retval)) {
case IS_STRING:
efree(entry);
/* TODO: avoid relocation??? */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got some refactoring that will avoid this. We are kinda stepping on each other's toes, but I'm happy to rework my local changes on top of this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, I had to add the dtor here below for the leak fix and that's how I noticed this.
I'll merge this and let you rebase then.

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:
Expand All @@ -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);
Expand All @@ -752,29 +755,28 @@ PHP_METHOD(Phar, webPhar)

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;
entry_len = index_php_len;
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};
Expand All @@ -801,21 +803,32 @@ PHP_METHOD(Phar, webPhar)
*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))) {
Expand Down