diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 41f45bd17f1..4fe61db412a 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -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); diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 131bc675530..77fa49794aa 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -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; diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index eb836ac691a..d8e319eeb6e 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -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); diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 0d992a6dd7f..4a2f8726191 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -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); diff --git a/ext/phar/stream.c b/ext/phar/stream.c index f5e1d9514c7..710de5d63c3 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -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); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 44a8e127e23..8340dbb527c 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -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[] = "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); diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 70cdfc9cc1b..c793485ee4d 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -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[] = "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);