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

ext/phar: Refactor flushing of archive to only take string stub file

This commit is contained in:
Gina Peter Bnayard
2024-09-12 22:57:26 +02:00
committed by Gina Peter Banyard
parent 888eb370cf
commit 03e2cfdad1
7 changed files with 104 additions and 218 deletions

View File

@@ -507,7 +507,7 @@ int phar_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url_from, int mo
return 0;
}
phar_flush(phar, 0, 0, 0, &error);
phar_flush(phar, &error);
if (error) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", entry.filename, phar->fname, error);
@@ -634,7 +634,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options
} else {
entry->is_deleted = 1;
entry->is_modified = 1;
phar_flush(phar, 0, 0, 0, &error);
phar_flush(phar, &error);
if (error) {
php_stream_wrapper_log_error(wrapper, options, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", entry->filename, phar->fname, error);

View File

@@ -433,7 +433,7 @@ void phar_entry_remove(phar_entry_data *idata, char **error) /* {{{ */
}
if (!phar->donotflush) {
phar_flush(phar, 0, 0, 0, error);
phar_flush(phar, error);
}
}
/* }}} */
@@ -2520,27 +2520,30 @@ zend_string *phar_create_default_stub(const char *index_php, const char *web_ind
}
/* }}} */
int phar_flush(phar_archive_data *phar, char **error) {
return phar_flush_ex(phar, NULL, false, error);
}
/**
* Save phar contents to disk
*
* user_stub contains either a string, or a resource pointer, if len is a negative length.
* user_stub and len should be both 0 if the default or existing stub should be used
* if user_stub is NULL the default or existing stub should be used
*/
int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int convert, char **error) /* {{{ */
int phar_flush_ex(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */
{
char halt_stub[] = "__HALT_COMPILER();";
zend_string *newstub;
phar_entry_info *entry, *newentry;
size_t halt_offset;
int restore_alias_len, global_flags = 0, closeoldfile;
char *pos, has_dirs = 0;
bool has_dirs = 0;
char manifest[18], entry_buffer[24];
zend_off_t manifest_ftell;
zend_long offset;
size_t wrote;
uint32_t manifest_len, mytime, new_manifest_count;
uint32_t newcrc32;
php_stream *file, *oldfile, *newfile, *stubfile;
php_stream *file, *oldfile, *newfile;
php_stream_filter *filter;
php_serialize_data_t metadata_hash;
smart_str main_metadata_str = {0};
@@ -2566,11 +2569,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
zend_hash_clean(&phar->virtual_dirs);
if (phar->is_zip) {
return phar_zip_flush(phar, user_stub, len, convert, error);
return phar_zip_flush(phar, user_stub, is_default_stub, error);
}
if (phar->is_tar) {
return phar_tar_flush(phar, user_stub, len, convert, error);
return phar_tar_flush(phar, user_stub, is_default_stub, error);
}
if (PHAR_G(readonly)) {
@@ -2597,44 +2600,9 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
}
if (user_stub) {
zend_string *suser_stub;
bool free_user_stub = false;
char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), strlen(halt_stub));
if (len < 0) {
/* resource passed in */
if (!(php_stream_from_zval_no_verify(stubfile, (zval *)user_stub))) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
spprintf(error, 0, "unable to access resource to copy stub to new phar \"%s\"", phar->fname);
}
return EOF;
}
if (len == -1) {
len = PHP_STREAM_COPY_ALL;
} else {
len = -len;
}
user_stub = 0;
if (!(suser_stub = php_stream_copy_to_mem(stubfile, len, 0))) {
if (closeoldfile) {
php_stream_close(oldfile);
}
php_stream_close(newfile);
if (error) {
spprintf(error, 0, "unable to read resource to copy stub to new phar \"%s\"", phar->fname);
}
return EOF;
}
free_user_stub = true;
user_stub = ZSTR_VAL(suser_stub);
len = ZSTR_LEN(suser_stub);
}
if ((pos = php_stristr(user_stub, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) {
if (pos == NULL) {
if (closeoldfile) {
php_stream_close(oldfile);
}
@@ -2642,14 +2610,17 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
if (error) {
spprintf(error, 0, "illegal stub for phar \"%s\" (__HALT_COMPILER(); is missing)", phar->fname);
}
if (free_user_stub) {
zend_string_free(suser_stub);
}
return EOF;
}
len = pos - user_stub + 18;
if ((size_t)len != php_stream_write(newfile, user_stub, len)
|| 5 != php_stream_write(newfile, " ?>\r\n", 5)) {
size_t len = pos - ZSTR_VAL(user_stub) + strlen(halt_stub);
const char end_sequence[] = " ?>\r\n";
size_t end_sequence_len = strlen(end_sequence);
if (
len != php_stream_write(newfile, ZSTR_VAL(user_stub), len)
|| end_sequence_len != php_stream_write(newfile, end_sequence, end_sequence_len)
) {
if (closeoldfile) {
php_stream_close(oldfile);
}
@@ -2657,15 +2628,9 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
if (error) {
spprintf(error, 0, "unable to create stub from string in new phar \"%s\"", phar->fname);
}
if (free_user_stub) {
zend_string_free(suser_stub);
}
return EOF;
}
phar->halt_offset = len + 5;
if (free_user_stub) {
zend_string_free(suser_stub);
}
phar->halt_offset = len + end_sequence_len;
} else {
size_t written;

View File

@@ -447,12 +447,12 @@ zend_result phar_copy_on_write(phar_archive_data **pphar);
bool phar_is_tar(char *buf, char *fname);
zend_result phar_parse_tarfile(php_stream* fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, uint32_t compression, char **error);
zend_result phar_open_or_create_tar(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error);
int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int defaultstub, char **error);
int phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error);
/* zip functions in zip.c */
int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alias, size_t alias_len, phar_archive_data** pphar, char **error);
int phar_open_or_create_zip(char *fname, size_t fname_len, char *alias, size_t alias_len, int is_data, uint32_t options, phar_archive_data** pphar, char **error);
int phar_zip_flush(phar_archive_data *archive, char *user_stub, zend_long len, int defaultstub, char **error);
int phar_zip_flush(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error);
#ifdef PHAR_MAIN
extern const php_stream_wrapper php_stream_phar_wrapper;
@@ -468,7 +468,8 @@ phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t
phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security);
phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security);
zend_result phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security);
int phar_flush(phar_archive_data *archive, char *user_stub, zend_long len, int convert, char **error);
int phar_flush_ex(phar_archive_data *archive, zend_string *user_stub, bool is_default_stub, char **error);
int phar_flush(phar_archive_data *archive, char **error);
zend_result phar_detect_phar_fname_ext(const char *filename, size_t filename_len, const char **ext_str, size_t *ext_len, int executable, int for_create, int is_complete);
zend_result phar_split_fname(const char *filename, size_t filename_len, char **arch, size_t *arch_len, char **entry, size_t *entry_len, int executable, int for_create);

View File

@@ -1812,7 +1812,7 @@ PHP_METHOD(Phar, buildFromDirectory)
}
phar_obj->archive->ufp = pass.fp;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -1877,7 +1877,7 @@ PHP_METHOD(Phar, buildFromIterator)
if (SUCCESS == spl_iterator_apply(obj, (spl_iterator_apply_func_t) phar_build, (void *) &pass)) {
phar_obj->archive->ufp = pass.fp;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
efree(error);
@@ -2194,7 +2194,7 @@ its_ok:
return NULL;
}
phar_flush(phar, 0, 0, 1, &error);
phar_flush_ex(phar, NULL, 1, &error);
if (error) {
zend_hash_str_del(&(PHAR_G(phar_fname_map)), newpath, phar->fname_len);
@@ -2642,7 +2642,7 @@ PHP_METHOD(Phar, delete)
RETURN_THROWS();
}
phar_flush(phar_obj->archive, NULL, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
efree(error);
@@ -2754,7 +2754,7 @@ valid_alias:
phar_obj->archive->alias = estrndup(ZSTR_VAL(new_alias), ZSTR_LEN(new_alias));
phar_obj->archive->alias_len = ZSTR_LEN(new_alias);
phar_obj->archive->is_temporary_alias = 0;
phar_flush(phar_obj->archive, NULL, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
phar_obj->archive->alias = oldalias;
@@ -2835,7 +2835,7 @@ PHP_METHOD(Phar, stopBuffering)
}
phar_obj->archive->donotflush = 0;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -2849,9 +2849,9 @@ PHP_METHOD(Phar, stopBuffering)
*/
PHP_METHOD(Phar, setStub)
{
char *error;
zend_string *stub;
zval *zstub;
char *stub, *error;
size_t stub_len;
zend_long len = -1;
php_stream *stream;
@@ -2883,16 +2883,26 @@ PHP_METHOD(Phar, setStub)
}
if ((php_stream_from_zval_no_verify(stream, zstub)) != NULL) {
if (len > 0) {
len = -len;
} else {
len = -1;
}
if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) {
zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname);
RETURN_THROWS();
}
phar_flush(phar_obj->archive, (char *) zstub, len, 0, &error);
zend_string *stub_file_content = NULL;
if (len > 0) {
stub_file_content = php_stream_copy_to_mem(stream, len, false);
} else {
stub_file_content = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, false);
}
if (stub_file_content == NULL) {
zend_throw_exception_ex(phar_ce_PharException, 0, "unable to read resource to copy stub to new phar \"%s\"", phar_obj->archive->fname);
RETURN_THROWS();
}
phar_flush_ex(phar_obj->archive, stub_file_content, /* is_default_stub */ false, &error);
zend_string_release_ex(stub_file_content, false);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
efree(error);
@@ -2902,12 +2912,12 @@ PHP_METHOD(Phar, setStub)
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0,
"Cannot change stub, unable to read from input stream");
}
} else if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &stub, &stub_len) == SUCCESS) {
} else if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &stub) == SUCCESS) {
if (phar_obj->archive->is_persistent && FAILURE == phar_copy_on_write(&(phar_obj->archive))) {
zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname);
RETURN_THROWS();
}
phar_flush(phar_obj->archive, stub, stub_len, 0, &error);
phar_flush_ex(phar_obj->archive, stub, /* is_default_stub */ false, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -2988,7 +2998,7 @@ PHP_METHOD(Phar, setDefaultStub)
zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" is persistent, unable to copy on write", phar_obj->archive->fname);
RETURN_THROWS();
}
phar_flush(phar_obj->archive, stub ? ZSTR_VAL(stub) : 0, stub ? ZSTR_LEN(stub) : 0, 1, &error);
phar_flush_ex(phar_obj->archive, stub, /* is_default_stub */ true, &error);
if (created_stub) {
zend_string_free(stub);
@@ -3044,7 +3054,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm)
PHAR_G(openssl_privatekey) = key;
PHAR_G(openssl_privatekey_len) = key_len;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
efree(error);
@@ -3353,7 +3363,7 @@ PHP_METHOD(Phar, compressFiles)
}
pharobj_set_compression(&phar_obj->archive->manifest, flags);
phar_obj->archive->is_modified = 1;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s", error);
@@ -3397,7 +3407,7 @@ PHP_METHOD(Phar, decompressFiles)
}
phar_obj->archive->is_modified = 1;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s", error);
@@ -3492,7 +3502,7 @@ PHP_METHOD(Phar, copy)
zend_hash_str_add_mem(&oldentry->phar->manifest, ZSTR_VAL(new_file), tmp_len, &newentry, sizeof(phar_entry_info));
phar_obj->archive->is_modified = 1;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -3673,7 +3683,7 @@ static void phar_add_file(phar_archive_data **pphar, zend_string *file_name, con
*pphar = data->phar;
}
phar_entry_delref(data);
phar_flush(*pphar, 0, 0, 0, &error);
phar_flush(*pphar, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -3716,7 +3726,7 @@ static void phar_mkdir(phar_archive_data **pphar, zend_string *dir_name)
*pphar = data->phar;
}
phar_entry_delref(data);
phar_flush(*pphar, 0, 0, 0, &error);
phar_flush(*pphar, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -3800,7 +3810,7 @@ PHP_METHOD(Phar, offsetUnset)
entry->is_modified = 0;
entry->is_deleted = 1;
/* we need to "flush" the stream to save the newly deleted file on disk */
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -4070,7 +4080,7 @@ PHP_METHOD(Phar, setMetadata)
}
phar_obj->archive->is_modified = 1;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -4101,7 +4111,7 @@ PHP_METHOD(Phar, delMetadata)
phar_metadata_tracker_free(&phar_obj->archive->metadata_tracker, phar_obj->archive->is_persistent);
phar_obj->archive->is_modified = 1;
phar_flush(phar_obj->archive, 0, 0, 0, &error);
phar_flush(phar_obj->archive, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -4669,7 +4679,7 @@ PHP_METHOD(PharFileInfo, chmod)
BG(CurrentLStatFile) = NULL;
BG(CurrentStatFile) = NULL;
phar_flush(entry_obj->entry->phar, 0, 0, 0, &error);
phar_flush(entry_obj->entry->phar, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -4752,7 +4762,7 @@ PHP_METHOD(PharFileInfo, setMetadata)
entry_obj->entry->is_modified = 1;
entry_obj->entry->phar->is_modified = 1;
phar_flush(entry_obj->entry->phar, 0, 0, 0, &error);
phar_flush(entry_obj->entry->phar, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -4799,7 +4809,7 @@ PHP_METHOD(PharFileInfo, delMetadata)
entry_obj->entry->is_modified = 1;
entry_obj->entry->phar->is_modified = 1;
phar_flush(entry_obj->entry->phar, 0, 0, 0, &error);
phar_flush(entry_obj->entry->phar, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -4979,7 +4989,7 @@ PHP_METHOD(PharFileInfo, compress)
entry_obj->entry->phar->is_modified = 1;
entry_obj->entry->is_modified = 1;
phar_flush(entry_obj->entry->phar, 0, 0, 0, &error);
phar_flush(entry_obj->entry->phar, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);
@@ -5071,7 +5081,7 @@ PHP_METHOD(PharFileInfo, decompress)
entry_obj->entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
entry_obj->entry->phar->is_modified = 1;
entry_obj->entry->is_modified = 1;
phar_flush(entry_obj->entry->phar, 0, 0, 0, &error);
phar_flush(entry_obj->entry->phar, &error);
if (error) {
zend_throw_exception_ex(phar_ce_PharException, 0, "%s", error);

View File

@@ -474,7 +474,7 @@ static int phar_stream_flush(php_stream *stream) /* {{{ */
if (data->internal_file->is_modified) {
data->internal_file->timestamp = time(0);
ret = phar_flush(data->phar, 0, 0, 0, &error);
ret = phar_flush(data->phar, &error);
if (error) {
php_stream_wrapper_log_error(stream->wrapper, REPORT_ERRORS, "%s", error);
efree(error);
@@ -955,7 +955,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from
}
if (is_modified) {
phar_flush(phar, 0, 0, 0, &error);
phar_flush(phar, &error);
if (error) {
php_url_free(resource_from);
php_url_free(resource_to);

View File

@@ -955,12 +955,12 @@ static int phar_tar_setupmetadata(zval *zv, void *argument) /* {{{ */
}
/* }}} */
int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int defaultstub, char **error) /* {{{ */
int phar_tar_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */
{
phar_entry_info entry = {0};
static const char newstub[] = "<?php // tar-based phar archive stub file\n__HALT_COMPILER();";
php_stream *oldfile, *newfile, *stubfile;
int closeoldfile, free_user_stub;
php_stream *oldfile, *newfile;
int closeoldfile;
size_t signature_length;
struct _phar_pass_tar_info pass;
char *buf, *signature, sigbuf[8];
@@ -1017,74 +1017,34 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
}
/* set stub */
if (user_stub && !defaultstub) {
char *pos;
if (len < 0) {
/* resource passed in */
if (!(php_stream_from_zval_no_verify(stubfile, (zval *)user_stub))) {
if (error) {
spprintf(error, 0, "unable to access resource to copy stub to new tar-based phar \"%s\"", phar->fname);
}
return EOF;
}
if (len == -1) {
len = PHP_STREAM_COPY_ALL;
} else {
len = -len;
}
user_stub = 0;
if (user_stub && !is_default_stub) {
char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), sizeof(halt_stub) - 1);
// TODO: refactor to avoid reallocation ???
//??? len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)
{
zend_string *str = php_stream_copy_to_mem(stubfile, len, 0);
if (str) {
len = ZSTR_LEN(str);
user_stub = estrndup(ZSTR_VAL(str), ZSTR_LEN(str));
zend_string_release_ex(str, 0);
} else {
user_stub = NULL;
len = 0;
}
}
if (!len || !user_stub) {
if (error) {
spprintf(error, 0, "unable to read resource to copy stub to new tar-based phar \"%s\"", phar->fname);
}
return EOF;
}
free_user_stub = 1;
} else {
free_user_stub = 0;
}
if ((pos = php_stristr(user_stub, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) {
if (pos == NULL) {
if (error) {
spprintf(error, 0, "illegal stub for tar-based phar \"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
}
return EOF;
}
len = pos - user_stub + 18;
size_t len = pos - ZSTR_VAL(user_stub) + strlen(halt_stub);
const char end_sequence[] = " ?>\r\n";
size_t end_sequence_len = strlen(end_sequence);
entry.fp = php_stream_fopen_tmpfile();
if (entry.fp == NULL) {
spprintf(error, 0, "phar error: unable to create temporary file");
return EOF;
}
entry.uncompressed_filesize = len + 5;
entry.uncompressed_filesize = len + end_sequence_len;
if ((size_t)len != php_stream_write(entry.fp, user_stub, len)
|| 5 != php_stream_write(entry.fp, " ?>\r\n", 5)) {
if (
len != php_stream_write(entry.fp, ZSTR_VAL(user_stub), len)
|| end_sequence_len != php_stream_write(entry.fp, end_sequence, end_sequence_len)
) {
if (error) {
spprintf(error, 0, "unable to create stub from string in new tar-based phar \"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
}
php_stream_close(entry.fp);
return EOF;
}
@@ -1092,10 +1052,6 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
entry.filename_len = sizeof(".phar/stub.php")-1;
zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info));
if (free_user_stub) {
efree(user_stub);
}
} else {
/* Either this is a brand new phar (add the stub), or the default stub is required (overwrite the stub) */
entry.fp = php_stream_fopen_tmpfile();
@@ -1115,7 +1071,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
entry.filename_len = sizeof(".phar/stub.php")-1;
if (!defaultstub) {
if (!is_default_stub) {
if (!zend_hash_str_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
if (NULL == zend_hash_str_add_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
php_stream_close(entry.fp);

View File

@@ -1251,14 +1251,13 @@ static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pas
}
/* }}} */
int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int defaultstub, char **error) /* {{{ */
int phar_zip_flush(phar_archive_data *phar, zend_string *user_stub, bool is_default_stub, char **error) /* {{{ */
{
char *pos;
static const char newstub[] = "<?php // zip-based phar archive stub file\n__HALT_COMPILER();";
char halt_stub[] = "__HALT_COMPILER();";
php_stream *stubfile, *oldfile;
int free_user_stub, closeoldfile = 0;
php_stream *oldfile;
int closeoldfile = 0;
phar_entry_info entry = {0};
char *temperr = NULL;
struct _phar_zip_pass pass;
@@ -1315,75 +1314,34 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
}
/* set stub */
if (user_stub && !defaultstub) {
if (len < 0) {
/* resource passed in */
if (!(php_stream_from_zval_no_verify(stubfile, (zval *)user_stub))) {
if (error) {
spprintf(error, 0, "unable to access resource to copy stub to new zip-based phar \"%s\"", phar->fname);
}
return EOF;
}
if (user_stub && !is_default_stub) {
char *pos = php_stristr(ZSTR_VAL(user_stub), halt_stub, ZSTR_LEN(user_stub), strlen(halt_stub));
if (len == -1) {
len = PHP_STREAM_COPY_ALL;
} else {
len = -len;
}
user_stub = 0;
// TODO: refactor to avoid reallocation ???
//??? len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)
{
zend_string *str = php_stream_copy_to_mem(stubfile, len, 0);
if (str) {
len = ZSTR_LEN(str);
user_stub = estrndup(ZSTR_VAL(str), ZSTR_LEN(str));
zend_string_release_ex(str, 0);
} else {
user_stub = NULL;
len = 0;
}
}
if (!len || !user_stub) {
if (error) {
spprintf(error, 0, "unable to read resource to copy stub to new zip-based phar \"%s\"", phar->fname);
}
return EOF;
}
free_user_stub = 1;
} else {
free_user_stub = 0;
}
if ((pos = php_stristr(user_stub, halt_stub, len, sizeof(halt_stub) - 1)) == NULL) {
if (pos == NULL) {
if (error) {
spprintf(error, 0, "illegal stub for zip-based phar \"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
}
return EOF;
}
len = pos - user_stub + 18;
size_t len = pos - ZSTR_VAL(user_stub) + strlen(halt_stub);
const char end_sequence[] = " ?>\r\n";
size_t end_sequence_len = strlen(end_sequence);
entry.fp = php_stream_fopen_tmpfile();
if (entry.fp == NULL) {
spprintf(error, 0, "phar error: unable to create temporary file");
return EOF;
}
entry.uncompressed_filesize = len + 5;
entry.uncompressed_filesize = len + end_sequence_len;
if ((size_t)len != php_stream_write(entry.fp, user_stub, len)
|| 5 != php_stream_write(entry.fp, " ?>\r\n", 5)) {
if (
len != php_stream_write(entry.fp, ZSTR_VAL(user_stub), len)
|| end_sequence_len != php_stream_write(entry.fp, end_sequence, end_sequence_len)
) {
if (error) {
spprintf(error, 0, "unable to create stub from string in new zip-based phar \"%s\"", phar->fname);
}
if (free_user_stub) {
efree(user_stub);
}
php_stream_close(entry.fp);
return EOF;
}
@@ -1392,10 +1350,6 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
entry.filename_len = sizeof(".phar/stub.php")-1;
zend_hash_str_update_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info));
if (free_user_stub) {
efree(user_stub);
}
} else {
/* Either this is a brand new phar (add the stub), or the default stub is required (overwrite the stub) */
entry.fp = php_stream_fopen_tmpfile();
@@ -1415,7 +1369,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int
entry.filename = estrndup(".phar/stub.php", sizeof(".phar/stub.php")-1);
entry.filename_len = sizeof(".phar/stub.php")-1;
if (!defaultstub) {
if (!is_default_stub) {
if (!zend_hash_str_exists(&phar->manifest, ".phar/stub.php", sizeof(".phar/stub.php")-1)) {
if (NULL == zend_hash_str_add_mem(&phar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info))) {
php_stream_close(entry.fp);