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:
committed by
Gina Peter Banyard
parent
888eb370cf
commit
03e2cfdad1
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user