@@ -2508,6 +2508,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2508
2508
smart_str main_metadata_str = {0 };
2509
2509
int free_user_stub , free_fp = 1 , free_ufp = 1 ;
2510
2510
int manifest_hack = 0 ;
2511
+ php_stream * shared_cfp = NULL ;
2511
2512
2512
2513
if (phar -> is_persistent ) {
2513
2514
if (error ) {
@@ -2788,10 +2789,13 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2788
2789
return EOF ;
2789
2790
}
2790
2791
2791
- /* create new file that holds the compressed version */
2792
+ /* create new file that holds the compressed versions */
2792
2793
/* work around inability to specify freedom in write and strictness
2793
2794
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 ;
2795
2799
if (!entry -> cfp ) {
2796
2800
if (error ) {
2797
2801
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
2800
2804
php_stream_close (oldfile );
2801
2805
}
2802
2806
php_stream_close (newfile );
2803
- return EOF ;
2807
+ goto cleanup ;
2804
2808
}
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 );
2805
2812
php_stream_flush (file );
2806
2813
if (-1 == phar_seek_efp (entry , 0 , SEEK_SET , 0 , 0 )) {
2807
2814
if (closeoldfile ) {
@@ -2811,7 +2818,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2811
2818
if (error ) {
2812
2819
spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
2813
2820
}
2814
- return EOF ;
2821
+ goto cleanup ;
2815
2822
}
2816
2823
php_stream_filter_append ((& entry -> cfp -> writefilters ), filter );
2817
2824
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
2822
2829
if (error ) {
2823
2830
spprintf (error , 0 , "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
2824
2831
}
2825
- return EOF ;
2832
+ goto cleanup ;
2826
2833
}
2827
2834
php_stream_filter_flush (filter , 1 );
2828
2835
php_stream_flush (entry -> cfp );
2829
2836
php_stream_filter_remove (filter , 1 );
2830
2837
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 ;
2832
2839
/* generate crc on compressed file */
2833
- php_stream_rewind (entry -> cfp );
2834
2840
entry -> old_flags = entry -> flags ;
2835
2841
entry -> is_modified = 1 ;
2836
2842
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
2886
2892
spprintf (error , 0 , "unable to write manifest header of new phar \"%s\"" , phar -> fname );
2887
2893
}
2888
2894
2889
- return EOF ;
2895
+ goto cleanup ;
2890
2896
}
2891
2897
2892
2898
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
2907
2913
spprintf (error , 0 , "unable to write manifest meta-data of new phar \"%s\"" , phar -> fname );
2908
2914
}
2909
2915
2910
- return EOF ;
2916
+ goto cleanup ;
2911
2917
}
2912
2918
smart_str_free (& main_metadata_str );
2913
2919
@@ -2942,7 +2948,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2942
2948
spprintf (error , 0 , "unable to write filename of file \"%s\" to manifest of new phar \"%s\"" , entry -> filename , phar -> fname );
2943
2949
}
2944
2950
}
2945
- return EOF ;
2951
+ goto cleanup ;
2946
2952
}
2947
2953
2948
2954
/* set the manifest meta-data:
@@ -2975,7 +2981,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2975
2981
spprintf (error , 0 , "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"" , entry -> filename , phar -> fname );
2976
2982
}
2977
2983
2978
- return EOF ;
2984
+ goto cleanup ;
2979
2985
}
2980
2986
} ZEND_HASH_FOREACH_END ();
2981
2987
/* 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
2991
2997
spprintf (error , 0 , "unable to write manifest padding byte" );
2992
2998
}
2993
2999
2994
- return EOF ;
3000
+ goto cleanup ;
2995
3001
}
2996
3002
}
2997
3003
@@ -3004,7 +3010,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3004
3010
3005
3011
if (entry -> cfp ) {
3006
3012
file = entry -> cfp ;
3007
- php_stream_rewind (file );
3013
+ php_stream_seek (file , entry -> header_offset , SEEK_SET );
3008
3014
} else {
3009
3015
file = phar_get_efp (entry , 0 );
3010
3016
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
3015
3021
if (error ) {
3016
3022
spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
3017
3023
}
3018
- return EOF ;
3024
+ goto cleanup ;
3019
3025
}
3020
3026
}
3021
3027
@@ -3027,7 +3033,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3027
3033
if (error ) {
3028
3034
spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
3029
3035
}
3030
- return EOF ;
3036
+ goto cleanup ;
3031
3037
}
3032
3038
3033
3039
/* 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
3044
3050
spprintf (error , 0 , "unable to write contents of file \"%s\" to new phar \"%s\"" , entry -> filename , phar -> fname );
3045
3051
}
3046
3052
3047
- return EOF ;
3053
+ goto cleanup ;
3048
3054
}
3049
3055
3050
3056
entry -> is_modified = 0 ;
3051
3057
3052
3058
if (entry -> cfp ) {
3053
- php_stream_close (entry -> cfp );
3054
3059
entry -> cfp = NULL ;
3060
+ entry -> header_offset = 0 ;
3055
3061
}
3056
3062
3057
3063
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
3067
3073
}
3068
3074
} ZEND_HASH_FOREACH_END ();
3069
3075
3076
+ if (shared_cfp != NULL ) {
3077
+ php_stream_close (shared_cfp );
3078
+ shared_cfp = NULL ;
3079
+ }
3080
+
3070
3081
/* append signature */
3071
3082
if (global_flags & PHAR_HDR_SIGNATURE ) {
3072
3083
char sig_buf [4 ];
@@ -3196,6 +3207,19 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3196
3207
return EOF ;
3197
3208
}
3198
3209
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
+
3199
3223
return EOF ;
3200
3224
}
3201
3225
/* }}} */
0 commit comments