@@ -195,6 +195,13 @@ static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRM
195
195
}
196
196
/* }}} */
197
197
198
+ #if !HAVE_STRNLEN
199
+ static size_t strnlen (const char * s , size_t maxlen ) {
200
+ char * r = (char * )memchr (s , '\0' , maxlen );
201
+ return r ? r - s : maxlen ;
202
+ }
203
+ #endif
204
+
198
205
int phar_parse_tarfile (php_stream * fp , char * fname , int fname_len , char * alias , int alias_len , phar_archive_data * * pphar , int is_data , php_uint32 compression , char * * error TSRMLS_DC ) /* {{{ */
199
206
{
200
207
char buf [512 ], * actual_alias = NULL , * p ;
@@ -204,6 +211,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
204
211
php_uint32 sum1 , sum2 , size , old ;
205
212
phar_archive_data * myphar , * * actual ;
206
213
int last_was_longlink = 0 ;
214
+ int linkname_len ;
207
215
208
216
if (error ) {
209
217
* error = NULL ;
@@ -264,7 +272,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
264
272
goto next ;
265
273
}
266
274
267
- if (((!old && hdr -> prefix [0 ] == 0 ) || old ) && strlen (hdr -> name ) == sizeof (".phar/signature.bin" )- 1 && !strncmp (hdr -> name , ".phar/signature.bin" , sizeof (".phar/signature.bin" )- 1 )) {
275
+ if (((!old && hdr -> prefix [0 ] == 0 ) || old ) && strnlen (hdr -> name , 100 ) == sizeof (".phar/signature.bin" )- 1 && !strncmp (hdr -> name , ".phar/signature.bin" , sizeof (".phar/signature.bin" )- 1 )) {
268
276
off_t curloc ;
269
277
270
278
if (size > 511 ) {
@@ -474,20 +482,22 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
474
482
}
475
483
476
484
entry .link = NULL ;
477
-
485
+ /* link field is null-terminated unless it has 100 non-null chars.
486
+ * Thus we can not use strlen. */
487
+ linkname_len = strnlen (hdr -> linkname , 100 );
478
488
if (entry .tar_type == TAR_LINK ) {
479
- if (!zend_hash_exists (& myphar -> manifest , hdr -> linkname , strlen ( hdr -> linkname ) )) {
489
+ if (!zend_hash_exists (& myphar -> manifest , hdr -> linkname , linkname_len )) {
480
490
if (error ) {
481
- spprintf (error , 4096 , "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%s\"" , fname , hdr -> linkname );
491
+ spprintf (error , 4096 , "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%.* s\"" , fname , linkname_len , hdr -> linkname );
482
492
}
483
493
pefree (entry .filename , entry .is_persistent );
484
494
php_stream_close (fp );
485
495
phar_destroy_phar_data (myphar TSRMLS_CC );
486
496
return FAILURE ;
487
497
}
488
- entry .link = estrdup (hdr -> linkname );
498
+ entry .link = estrndup (hdr -> linkname , linkname_len );
489
499
} else if (entry .tar_type == TAR_SYMLINK ) {
490
- entry .link = estrdup (hdr -> linkname );
500
+ entry .link = estrndup (hdr -> linkname , linkname_len );
491
501
}
492
502
phar_set_inode (& entry TSRMLS_CC );
493
503
zend_hash_add (& myphar -> manifest , entry .filename , entry .filename_len , (void * )& entry , sizeof (phar_entry_info ), (void * * ) & newentry );
0 commit comments