@@ -2508,6 +2508,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
25082508 smart_str main_metadata_str = {0 };
25092509 int free_user_stub , free_fp = 1 , free_ufp = 1 ;
25102510 int manifest_hack = 0 ;
2511+ php_stream * shared_cfp = NULL ;
25112512
25122513 if (phar -> is_persistent ) {
25132514 if (error ) {
@@ -2788,10 +2789,13 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
27882789 return EOF ;
27892790 }
27902791
2791- /* create new file that holds the compressed version */
2792+ /* create new file that holds the compressed versions */
27922793 /* work around inability to specify freedom in write and strictness
27932794 in read count */
2794- entry -> cfp = php_stream_fopen_tmpfile ();
2795+ if (shared_cfp == NULL ) {
2796+ shared_cfp = php_stream_fopen_tmpfile ();
2797+ }
2798+ entry -> cfp = shared_cfp ;
27952799 if (!entry -> cfp ) {
27962800 if (error ) {
27972801 spprintf (error , 0 , "unable to create temporary file" );
@@ -2800,8 +2804,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
28002804 php_stream_close (oldfile );
28012805 }
28022806 php_stream_close (newfile );
2803- return EOF ;
2807+ goto cleanup ;
28042808 }
2809+ /* for real phars, header_offset is unused; we misuse it here to store the offset in the temp file */
2810+ ZEND_ASSERT (entry -> header_offset == 0 );
2811+ entry -> header_offset = php_stream_tell (entry -> cfp );
28052812 php_stream_flush (file );
28062813 if (-1 == phar_seek_efp (entry , 0 , SEEK_SET , 0 , 0 )) {
28072814 if (closeoldfile ) {
@@ -2811,7 +2818,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
28112818 if (error ) {
28122819 spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
28132820 }
2814- return EOF ;
2821+ goto cleanup ;
28152822 }
28162823 php_stream_filter_append ((& entry -> cfp -> writefilters ), filter );
28172824 if (SUCCESS != php_stream_copy_to_stream_ex (file , entry -> cfp , entry -> uncompressed_filesize , NULL )) {
@@ -2822,15 +2829,14 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
28222829 if (error ) {
28232830 spprintf (error , 0 , "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
28242831 }
2825- return EOF ;
2832+ goto cleanup ;
28262833 }
28272834 php_stream_filter_flush (filter , 1 );
28282835 php_stream_flush (entry -> cfp );
28292836 php_stream_filter_remove (filter , 1 );
28302837 php_stream_seek (entry -> cfp , 0 , SEEK_END );
2831- entry -> compressed_filesize = (uint32_t ) php_stream_tell (entry -> cfp );
2838+ entry -> compressed_filesize = (( uint32_t ) php_stream_tell (entry -> cfp )) - entry -> header_offset ;
28322839 /* generate crc on compressed file */
2833- php_stream_rewind (entry -> cfp );
28342840 entry -> old_flags = entry -> flags ;
28352841 entry -> is_modified = 1 ;
28362842 global_flags |= (entry -> flags & PHAR_ENT_COMPRESSION_MASK );
@@ -2886,7 +2892,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
28862892 spprintf (error , 0 , "unable to write manifest header of new phar \"%s\"" , phar -> fname );
28872893 }
28882894
2889- return EOF ;
2895+ goto cleanup ;
28902896 }
28912897
28922898 phar -> alias_len = restore_alias_len ;
@@ -2907,7 +2913,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
29072913 spprintf (error , 0 , "unable to write manifest meta-data of new phar \"%s\"" , phar -> fname );
29082914 }
29092915
2910- return EOF ;
2916+ goto cleanup ;
29112917 }
29122918 smart_str_free (& main_metadata_str );
29132919
@@ -2942,7 +2948,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
29422948 spprintf (error , 0 , "unable to write filename of file \"%s\" to manifest of new phar \"%s\"" , entry -> filename , phar -> fname );
29432949 }
29442950 }
2945- return EOF ;
2951+ goto cleanup ;
29462952 }
29472953
29482954 /* set the manifest meta-data:
@@ -2975,7 +2981,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
29752981 spprintf (error , 0 , "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"" , entry -> filename , phar -> fname );
29762982 }
29772983
2978- return EOF ;
2984+ goto cleanup ;
29792985 }
29802986 } ZEND_HASH_FOREACH_END ();
29812987 /* Hack - see bug #65028, add padding byte to the end of the manifest */
@@ -2991,7 +2997,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
29912997 spprintf (error , 0 , "unable to write manifest padding byte" );
29922998 }
29932999
2994- return EOF ;
3000+ goto cleanup ;
29953001 }
29963002 }
29973003
@@ -3004,7 +3010,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
30043010
30053011 if (entry -> cfp ) {
30063012 file = entry -> cfp ;
3007- php_stream_rewind (file );
3013+ php_stream_seek (file , entry -> header_offset , SEEK_SET );
30083014 } else {
30093015 file = phar_get_efp (entry , 0 );
30103016 if (-1 == phar_seek_efp (entry , 0 , SEEK_SET , 0 , 0 )) {
@@ -3015,7 +3021,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
30153021 if (error ) {
30163022 spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
30173023 }
3018- return EOF ;
3024+ goto cleanup ;
30193025 }
30203026 }
30213027
@@ -3027,7 +3033,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
30273033 if (error ) {
30283034 spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
30293035 }
3030- return EOF ;
3036+ goto cleanup ;
30313037 }
30323038
30333039 /* this will have changed for all files that have either changed compression or been modified */
@@ -3044,14 +3050,14 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
30443050 spprintf (error , 0 , "unable to write contents of file \"%s\" to new phar \"%s\"" , entry -> filename , phar -> fname );
30453051 }
30463052
3047- return EOF ;
3053+ goto cleanup ;
30483054 }
30493055
30503056 entry -> is_modified = 0 ;
30513057
30523058 if (entry -> cfp ) {
3053- php_stream_close (entry -> cfp );
30543059 entry -> cfp = NULL ;
3060+ entry -> header_offset = 0 ;
30553061 }
30563062
30573063 if (entry -> fp_type == PHAR_MOD ) {
@@ -3067,6 +3073,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
30673073 }
30683074 } ZEND_HASH_FOREACH_END ();
30693075
3076+ if (shared_cfp != NULL ) {
3077+ php_stream_close (shared_cfp );
3078+ shared_cfp = NULL ;
3079+ }
3080+
30703081 /* append signature */
30713082 if (global_flags & PHAR_HDR_SIGNATURE ) {
30723083 char sig_buf [4 ];
@@ -3196,6 +3207,19 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
31963207 return EOF ;
31973208 }
31983209
3210+ return EOF ;
3211+
3212+ cleanup :
3213+ if (shared_cfp != NULL ) {
3214+ php_stream_close (shared_cfp );
3215+ }
3216+ ZEND_HASH_FOREACH_PTR (& phar -> manifest , entry ) {
3217+ if (entry -> cfp ) {
3218+ entry -> cfp = NULL ;
3219+ entry -> header_offset = 0 ;
3220+ }
3221+ } ZEND_HASH_FOREACH_END ();
3222+
31993223 return EOF ;
32003224}
32013225/* }}} */
0 commit comments