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