@@ -277,57 +277,73 @@ PHP_FUNCTION(finfo_set_flags)
277277}
278278/* }}} */
279279
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 )
285281{
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+ }
294296
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
296304
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+ }
300319 }
320+ }
301321
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 );
308323
309- case IS_RESOURCE :
310- mode = FILEINFO_MODE_STREAM ;
311- break ;
324+ return ret_val ;
325+ }
312326
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 ;
317335
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 ();
330345 }
346+ php_stream_context * context = php_stream_context_from_zval (zcontext , false);
331347
332348 /* Set options for the current file/buffer. */
333349 if (options ) {
@@ -336,124 +352,121 @@ static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mime
336352 magic_setflags (magic , options );
337353 }
338354
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+ }
358360
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+ }
360367
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 ;
364376
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 ;
382382
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+ }
384387
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 ));
388389
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+ }
397394
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+ }
399402
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 ;
404410
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+ }
412414
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 ();
414425 }
415426 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 ();
418435 }
419436
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 ;
426441 }
427442
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 ));
430445 magic_close (magic );
446+ RETURN_FALSE ;
431447 }
432448
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_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 );
439457
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+ }
446462
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+ }
453465
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 );
458472}
459- /* }}} */
0 commit comments