@@ -277,57 +277,73 @@ PHP_FUNCTION(finfo_set_flags)
277
277
}
278
278
/* }}} */
279
279
280
- #define FILEINFO_MODE_BUFFER 0
281
- #define FILEINFO_MODE_STREAM 1
282
- #define FILEINFO_MODE_FILE 2
283
-
284
- static void _php_finfo_get_type (INTERNAL_FUNCTION_PARAMETERS , int mode , int mimetype_emu ) /* {{{ */
280
+ static const char * php_fileinfo_from_path (struct magic_set * magic , const zend_string * path , php_stream_context * context )
285
281
{
286
- zend_long options = 0 ;
287
- char * ret_val = NULL , * buffer = NULL ;
288
- size_t buffer_len ;
289
- php_fileinfo * finfo = NULL ;
290
- zval * zcontext = NULL ;
291
- zval * what ;
292
- char mime_directory [] = "directory" ;
293
- struct magic_set * magic = NULL ;
282
+ ZEND_ASSERT (magic != NULL );
283
+ ZEND_ASSERT (path );
284
+ ZEND_ASSERT (ZSTR_LEN (path ) != 0 );
285
+ ZEND_ASSERT (!zend_str_has_nul_byte (path ));
286
+ ZEND_ASSERT (context != NULL );
287
+
288
+ /* determine if the file is a local file or remote URL */
289
+ const char * dummy ;
290
+ php_stream_statbuf ssb ;
291
+
292
+ const php_stream_wrapper * wrap = php_stream_locate_url_wrapper (ZSTR_VAL (path ), & dummy , 0 );
293
+ if (UNEXPECTED (wrap == NULL )) {
294
+ return NULL ;
295
+ }
294
296
295
- if (mimetype_emu ) {
297
+ #ifdef PHP_WIN32
298
+ if (php_stream_stat_path_ex (ZSTR_VAL (path ), 0 , & ssb , context ) == SUCCESS ) {
299
+ if (ssb .sb .st_mode & S_IFDIR ) {
300
+ return "directory" ;
301
+ }
302
+ }
303
+ #endif
296
304
297
- /* mime_content_type(..) emulation */
298
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "z" , & what ) == FAILURE ) {
299
- RETURN_THROWS ();
305
+ php_stream * stream = php_stream_open_wrapper_ex (ZSTR_VAL (path ), "rb" , REPORT_ERRORS , NULL , context );
306
+ if (!stream ) {
307
+ return NULL ;
308
+ }
309
+
310
+ const char * ret_val = NULL ;
311
+ if (php_stream_stat (stream , & ssb ) == SUCCESS ) {
312
+ if (ssb .sb .st_mode & S_IFDIR ) {
313
+ ret_val = "directory" ;
314
+ } else {
315
+ ret_val = magic_stream (magic , stream );
316
+ if (UNEXPECTED (ret_val == NULL )) {
317
+ php_error_docref (NULL , E_WARNING , "Failed identify data %d:%s" , magic_errno (magic ), magic_error (magic ));
318
+ }
300
319
}
320
+ }
301
321
302
- switch (Z_TYPE_P (what )) {
303
- case IS_STRING :
304
- buffer = Z_STRVAL_P (what );
305
- buffer_len = Z_STRLEN_P (what );
306
- mode = FILEINFO_MODE_FILE ;
307
- break ;
322
+ php_stream_close (stream );
308
323
309
- case IS_RESOURCE :
310
- mode = FILEINFO_MODE_STREAM ;
311
- break ;
324
+ return ret_val ;
325
+ }
312
326
313
- default :
314
- zend_argument_type_error (1 , "must be of type resource|string, %s given" , zend_zval_value_name (what ));
315
- RETURN_THROWS ();
316
- }
327
+ /* Return information about a file. */
328
+ PHP_FUNCTION (finfo_file )
329
+ {
330
+ zval * self ;
331
+ zend_string * path = NULL ;
332
+ zend_long options = 0 ;
333
+ zval * zcontext = NULL ;
334
+ php_fileinfo * finfo = NULL ;
317
335
318
- magic = magic_open (MAGIC_MIME_TYPE );
319
- if (magic_load (magic , NULL ) == -1 ) {
320
- php_error_docref (NULL , E_WARNING , "Failed to load magic database" );
321
- goto common ;
322
- }
323
- } else {
324
- zval * self ;
325
- if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Os|lr!" , & self , finfo_class_entry , & buffer , & buffer_len , & options , & zcontext ) == FAILURE ) {
326
- RETURN_THROWS ();
327
- }
328
- FILEINFO_FROM_OBJECT (finfo , self );
329
- magic = finfo -> magic ;
336
+ if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "OP|lr!" , & self , finfo_class_entry , & path , & options , & zcontext ) == FAILURE ) {
337
+ RETURN_THROWS ();
338
+ }
339
+ FILEINFO_FROM_OBJECT (finfo , self );
340
+ struct magic_set * magic = finfo -> magic ;
341
+
342
+ if (UNEXPECTED (ZSTR_LEN (path ) == 0 )) {
343
+ zend_argument_must_not_be_empty_error (2 );
344
+ RETURN_THROWS ();
330
345
}
346
+ php_stream_context * context = php_stream_context_from_zval (zcontext , false);
331
347
332
348
/* Set options for the current file/buffer. */
333
349
if (options ) {
@@ -336,124 +352,121 @@ static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mime
336
352
magic_setflags (magic , options );
337
353
}
338
354
339
- switch (mode ) {
340
- case FILEINFO_MODE_BUFFER :
341
- {
342
- ret_val = (char * ) magic_buffer (magic , buffer , buffer_len );
343
- break ;
344
- }
345
-
346
- case FILEINFO_MODE_STREAM :
347
- {
348
- php_stream * stream ;
349
- zend_off_t streampos ;
350
-
351
- php_stream_from_zval_no_verify (stream , what );
352
- if (!stream ) {
353
- goto common ;
354
- }
355
-
356
- streampos = php_stream_tell (stream ); /* remember stream position for restoration */
357
- php_stream_seek (stream , 0 , SEEK_SET );
355
+ const char * ret_val = php_fileinfo_from_path (magic , path , context );
356
+ /* Restore options */
357
+ if (options ) {
358
+ magic_setflags (magic , finfo -> options );
359
+ }
358
360
359
- ret_val = (char * ) magic_stream (magic , stream );
361
+ if (UNEXPECTED (ret_val == NULL )) {
362
+ RETURN_FALSE ;
363
+ } else {
364
+ RETURN_STRING (ret_val );
365
+ }
366
+ }
360
367
361
- php_stream_seek (stream , streampos , SEEK_SET );
362
- break ;
363
- }
368
+ /* Return information about a string buffer. */
369
+ PHP_FUNCTION (finfo_buffer )
370
+ {
371
+ zval * self ;
372
+ zend_string * buffer = NULL ;
373
+ zend_long options = 0 ;
374
+ zval * dummy_context = NULL ;
375
+ php_fileinfo * finfo = NULL ;
364
376
365
- case FILEINFO_MODE_FILE :
366
- {
367
- /* determine if the file is a local file or remote URL */
368
- const char * tmp2 ;
369
- php_stream_wrapper * wrap ;
370
- php_stream_statbuf ssb ;
371
-
372
- // Implementation is used for both finfo_file() and mimetype_emu()
373
- int buffer_param_num = (mimetype_emu ? 1 : 2 );
374
- if (buffer == NULL || buffer_len == 0 ) {
375
- zend_argument_must_not_be_empty_error (buffer_param_num );
376
- goto clean ;
377
- }
378
- if (CHECK_NULL_PATH (buffer , buffer_len )) {
379
- zend_argument_type_error (buffer_param_num , "must not contain any null bytes" );
380
- goto clean ;
381
- }
377
+ if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "OS|lr!" , & self , finfo_class_entry , & buffer , & options , & dummy_context ) == FAILURE ) {
378
+ RETURN_THROWS ();
379
+ }
380
+ FILEINFO_FROM_OBJECT (finfo , self );
381
+ struct magic_set * magic = finfo -> magic ;
382
382
383
- wrap = php_stream_locate_url_wrapper (buffer , & tmp2 , 0 );
383
+ /* Set options for the current file/buffer. */
384
+ if (options ) {
385
+ magic_setflags (magic , options );
386
+ }
384
387
385
- if (wrap ) {
386
- php_stream * stream ;
387
- php_stream_context * context = php_stream_context_from_zval (zcontext , 0 );
388
+ const char * ret_val = magic_buffer (magic , ZSTR_VAL (buffer ), ZSTR_LEN (buffer ));
388
389
389
- #ifdef PHP_WIN32
390
- if (php_stream_stat_path_ex (buffer , 0 , & ssb , context ) == SUCCESS ) {
391
- if (ssb .sb .st_mode & S_IFDIR ) {
392
- ret_val = mime_directory ;
393
- goto common ;
394
- }
395
- }
396
- #endif
390
+ /* Restore options */
391
+ if (options ) {
392
+ magic_setflags (magic , finfo -> options );
393
+ }
397
394
398
- stream = php_stream_open_wrapper_ex (buffer , "rb" , REPORT_ERRORS , NULL , context );
395
+ if (UNEXPECTED (ret_val == NULL )) {
396
+ php_error_docref (NULL , E_WARNING , "Failed identify data %d:%s" , magic_errno (magic ), magic_error (magic ));
397
+ RETURN_FALSE ;
398
+ } else {
399
+ RETURN_STRING (ret_val );
400
+ }
401
+ }
399
402
400
- if (!stream ) {
401
- RETVAL_FALSE ;
402
- goto clean ;
403
- }
403
+ /* Return content-type for file */
404
+ PHP_FUNCTION (mime_content_type )
405
+ {
406
+ zval * path_or_stream ;
407
+ const zend_string * path = NULL ;
408
+ php_stream * stream = NULL ;
409
+ struct magic_set * magic = NULL ;
404
410
405
- if (php_stream_stat (stream , & ssb ) == SUCCESS ) {
406
- if (ssb .sb .st_mode & S_IFDIR ) {
407
- ret_val = mime_directory ;
408
- } else {
409
- ret_val = (char * )magic_stream (magic , stream );
410
- }
411
- }
411
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "z" , & path_or_stream ) == FAILURE ) {
412
+ RETURN_THROWS ();
413
+ }
412
414
413
- php_stream_close (stream );
415
+ switch (Z_TYPE_P (path_or_stream )) {
416
+ case IS_STRING :
417
+ path = Z_STR_P (path_or_stream );
418
+ if (UNEXPECTED (ZSTR_LEN (path ) == 0 )) {
419
+ zend_argument_must_not_be_empty_error (1 );
420
+ RETURN_THROWS ();
421
+ }
422
+ if (UNEXPECTED (zend_str_has_nul_byte (path ))) {
423
+ zend_argument_type_error (1 , "must not contain any null bytes" );
424
+ RETURN_THROWS ();
414
425
}
415
426
break ;
416
- }
417
- EMPTY_SWITCH_DEFAULT_CASE ()
427
+
428
+ case IS_RESOURCE :
429
+ php_stream_from_zval (stream , path_or_stream );
430
+ break ;
431
+
432
+ default :
433
+ zend_argument_type_error (1 , "must be of type resource|string, %s given" , zend_zval_value_name (path_or_stream ));
434
+ RETURN_THROWS ();
418
435
}
419
436
420
- common :
421
- if (ret_val ) {
422
- RETVAL_STRING (ret_val );
423
- } else {
424
- php_error_docref (NULL , E_WARNING , "Failed identify data %d:%s" , magic_errno (magic ), magic_error (magic ));
425
- RETVAL_FALSE ;
437
+ magic = magic_open (MAGIC_MIME_TYPE );
438
+ if (UNEXPECTED (magic == NULL )) {
439
+ php_error_docref (NULL , E_WARNING , "Failed to load magic database" );
440
+ RETURN_FALSE ;
426
441
}
427
442
428
- clean :
429
- if ( mimetype_emu ) {
443
+ if ( UNEXPECTED ( magic_load ( magic , NULL ) == -1 )) {
444
+ php_error_docref ( NULL , E_WARNING , "Failed identify data %d:%s" , magic_errno ( magic ), magic_error ( magic ));
430
445
magic_close (magic );
446
+ RETURN_FALSE ;
431
447
}
432
448
433
- /* Restore options */
434
- if (options ) {
435
- magic_setflags (magic , finfo -> options );
436
- }
437
- }
438
- /* }}} */
449
+ const char * ret_val ;
450
+ if (path ) {
451
+ php_stream_context * context = php_stream_context_get_default (false);
452
+ ret_val = php_fileinfo_from_path (magic , path , context );
453
+ } else {
454
+ /* remember stream position for restoration */
455
+ zend_off_t current_stream_pos = php_stream_tell (stream );
456
+ php_stream_seek (stream , 0 , SEEK_SET );
439
457
440
- /* {{{ Return information about a file. */
441
- PHP_FUNCTION (finfo_file )
442
- {
443
- _php_finfo_get_type (INTERNAL_FUNCTION_PARAM_PASSTHRU , FILEINFO_MODE_FILE , 0 );
444
- }
445
- /* }}} */
458
+ ret_val = magic_stream (magic , stream );
459
+ if (UNEXPECTED (ret_val == NULL )) {
460
+ php_error_docref (NULL , E_WARNING , "Failed identify data %d:%s" , magic_errno (magic ), magic_error (magic ));
461
+ }
446
462
447
- /* {{{ Return information about a string buffer. */
448
- PHP_FUNCTION (finfo_buffer )
449
- {
450
- _php_finfo_get_type (INTERNAL_FUNCTION_PARAM_PASSTHRU , FILEINFO_MODE_BUFFER , 0 );
451
- }
452
- /* }}} */
463
+ php_stream_seek (stream , current_stream_pos , SEEK_SET );
464
+ }
453
465
454
- /* {{{ Return content-type for file */
455
- PHP_FUNCTION (mime_content_type )
456
- {
457
- _php_finfo_get_type (INTERNAL_FUNCTION_PARAM_PASSTHRU , -1 , 1 );
466
+ if (UNEXPECTED (ret_val == NULL )) {
467
+ RETVAL_FALSE ;
468
+ } else {
469
+ RETVAL_STRING (ret_val );
470
+ }
471
+ magic_close (magic );
458
472
}
459
- /* }}} */
0 commit comments