@@ -2558,6 +2558,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2558
2558
smart_str main_metadata_str = {0 };
2559
2559
int free_user_stub , free_fp = 1 , free_ufp = 1 ;
2560
2560
int manifest_hack = 0 ;
2561
+ php_stream * shared_cfp = NULL ;
2561
2562
2562
2563
if (phar -> is_persistent ) {
2563
2564
if (error ) {
@@ -2835,10 +2836,13 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2835
2836
return EOF ;
2836
2837
}
2837
2838
2838
- /* create new file that holds the compressed version */
2839
+ /* create new file that holds the compressed versions */
2839
2840
/* work around inability to specify freedom in write and strictness
2840
2841
in read count */
2841
- entry -> cfp = php_stream_fopen_tmpfile ();
2842
+ if (shared_cfp == NULL ) {
2843
+ shared_cfp = php_stream_fopen_tmpfile ();
2844
+ }
2845
+ entry -> cfp = shared_cfp ;
2842
2846
if (!entry -> cfp ) {
2843
2847
if (error ) {
2844
2848
spprintf (error , 0 , "unable to create temporary file" );
@@ -2847,8 +2851,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2847
2851
php_stream_close (oldfile );
2848
2852
}
2849
2853
php_stream_close (newfile );
2850
- return EOF ;
2854
+ goto cleanup ;
2851
2855
}
2856
+ /* for real phars, header_offset is unused; we misuse it here to store the offset in the temp file */
2857
+ ZEND_ASSERT (entry -> header_offset == 0 );
2858
+ entry -> header_offset = php_stream_tell (entry -> cfp );
2852
2859
php_stream_flush (file );
2853
2860
if (-1 == phar_seek_efp (entry , 0 , SEEK_SET , 0 , 0 )) {
2854
2861
if (closeoldfile ) {
@@ -2858,7 +2865,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2858
2865
if (error ) {
2859
2866
spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
2860
2867
}
2861
- return EOF ;
2868
+ goto cleanup ;
2862
2869
}
2863
2870
php_stream_filter_append ((& entry -> cfp -> writefilters ), filter );
2864
2871
if (SUCCESS != php_stream_copy_to_stream_ex (file , entry -> cfp , entry -> uncompressed_filesize , NULL )) {
@@ -2869,15 +2876,14 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2869
2876
if (error ) {
2870
2877
spprintf (error , 0 , "unable to copy compressed file contents of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
2871
2878
}
2872
- return EOF ;
2879
+ goto cleanup ;
2873
2880
}
2874
2881
php_stream_filter_flush (filter , 1 );
2875
2882
php_stream_flush (entry -> cfp );
2876
2883
php_stream_filter_remove (filter , 1 );
2877
2884
php_stream_seek (entry -> cfp , 0 , SEEK_END );
2878
- entry -> compressed_filesize = (uint32_t ) php_stream_tell (entry -> cfp );
2885
+ entry -> compressed_filesize = (( uint32_t ) php_stream_tell (entry -> cfp )) - entry -> header_offset ;
2879
2886
/* generate crc on compressed file */
2880
- php_stream_rewind (entry -> cfp );
2881
2887
entry -> old_flags = entry -> flags ;
2882
2888
entry -> is_modified = 1 ;
2883
2889
global_flags |= (entry -> flags & PHAR_ENT_COMPRESSION_MASK );
@@ -2933,7 +2939,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2933
2939
spprintf (error , 0 , "unable to write manifest header of new phar \"%s\"" , phar -> fname );
2934
2940
}
2935
2941
2936
- return EOF ;
2942
+ goto cleanup ;
2937
2943
}
2938
2944
2939
2945
phar -> alias_len = restore_alias_len ;
@@ -2954,7 +2960,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2954
2960
spprintf (error , 0 , "unable to write manifest meta-data of new phar \"%s\"" , phar -> fname );
2955
2961
}
2956
2962
2957
- return EOF ;
2963
+ goto cleanup ;
2958
2964
}
2959
2965
smart_str_free (& main_metadata_str );
2960
2966
@@ -2990,7 +2996,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
2990
2996
spprintf (error , 0 , "unable to write filename of file \"%s\" to manifest of new phar \"%s\"" , entry -> filename , phar -> fname );
2991
2997
}
2992
2998
}
2993
- return EOF ;
2999
+ goto cleanup ;
2994
3000
}
2995
3001
2996
3002
/* set the manifest meta-data:
@@ -3024,7 +3030,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3024
3030
spprintf (error , 0 , "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"" , entry -> filename , phar -> fname );
3025
3031
}
3026
3032
3027
- return EOF ;
3033
+ goto cleanup ;
3028
3034
}
3029
3035
} ZEND_HASH_FOREACH_END ();
3030
3036
/* Hack - see bug #65028, add padding byte to the end of the manifest */
@@ -3040,7 +3046,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3040
3046
spprintf (error , 0 , "unable to write manifest padding byte" );
3041
3047
}
3042
3048
3043
- return EOF ;
3049
+ goto cleanup ;
3044
3050
}
3045
3051
}
3046
3052
@@ -3053,7 +3059,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3053
3059
3054
3060
if (entry -> cfp ) {
3055
3061
file = entry -> cfp ;
3056
- php_stream_rewind (file );
3062
+ php_stream_seek (file , entry -> header_offset , SEEK_SET );
3057
3063
} else {
3058
3064
file = phar_get_efp (entry , 0 );
3059
3065
if (-1 == phar_seek_efp (entry , 0 , SEEK_SET , 0 , 0 )) {
@@ -3064,7 +3070,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3064
3070
if (error ) {
3065
3071
spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
3066
3072
}
3067
- return EOF ;
3073
+ goto cleanup ;
3068
3074
}
3069
3075
}
3070
3076
@@ -3076,7 +3082,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3076
3082
if (error ) {
3077
3083
spprintf (error , 0 , "unable to seek to start of file \"%s\" while creating new phar \"%s\"" , entry -> filename , phar -> fname );
3078
3084
}
3079
- return EOF ;
3085
+ goto cleanup ;
3080
3086
}
3081
3087
3082
3088
/* this will have changed for all files that have either changed compression or been modified */
@@ -3093,14 +3099,14 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3093
3099
spprintf (error , 0 , "unable to write contents of file \"%s\" to new phar \"%s\"" , entry -> filename , phar -> fname );
3094
3100
}
3095
3101
3096
- return EOF ;
3102
+ goto cleanup ;
3097
3103
}
3098
3104
3099
3105
entry -> is_modified = 0 ;
3100
3106
3101
3107
if (entry -> cfp ) {
3102
- php_stream_close (entry -> cfp );
3103
3108
entry -> cfp = NULL ;
3109
+ entry -> header_offset = 0 ;
3104
3110
}
3105
3111
3106
3112
if (entry -> fp_type == PHAR_MOD ) {
@@ -3116,6 +3122,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3116
3122
}
3117
3123
} ZEND_HASH_FOREACH_END ();
3118
3124
3125
+ if (shared_cfp != NULL ) {
3126
+ php_stream_close (shared_cfp );
3127
+ shared_cfp = NULL ;
3128
+ }
3129
+
3119
3130
/* append signature */
3120
3131
if (global_flags & PHAR_HDR_SIGNATURE ) {
3121
3132
char sig_buf [4 ];
@@ -3245,6 +3256,19 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
3245
3256
return EOF ;
3246
3257
}
3247
3258
3259
+ return EOF ;
3260
+
3261
+ cleanup :
3262
+ if (shared_cfp != NULL ) {
3263
+ php_stream_close (shared_cfp );
3264
+ }
3265
+ ZEND_HASH_FOREACH_PTR (& phar -> manifest , entry ) {
3266
+ if (entry -> cfp ) {
3267
+ entry -> cfp = NULL ;
3268
+ entry -> header_offset = 0 ;
3269
+ }
3270
+ } ZEND_HASH_FOREACH_END ();
3271
+
3248
3272
return EOF ;
3249
3273
}
3250
3274
/* }}} */
0 commit comments