@@ -275,181 +275,198 @@ PHP_FUNCTION(finfo_set_flags)
275275}
276276/* }}} */
277277
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 )
283279{
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+ }
315294
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" ;
325299 }
326- FILEINFO_FROM_OBJECT (finfo , self );
327- magic = finfo -> magic ;
328300 }
301+ #endif
329302
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 ;
333306 }
334307
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+ }
340317 }
318+ }
341319
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 );
354321
355- ret_val = (char * ) magic_stream (magic , stream );
322+ return ret_val ;
323+ }
356324
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 ;
360334
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 ;
378340
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);
380346
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+ }
384351
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+ }
393358
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+ }
395364
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 ;
400374
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 ;
408380
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 );
414384 }
415385
416- common :
386+ const char * ret_val = magic_buffer (magic , ZSTR_VAL (buffer ), ZSTR_LEN (buffer ));
387+
417388 if (ret_val ) {
418389 RETVAL_STRING (ret_val );
419390 } else {
420391 php_error_docref (NULL , E_WARNING , "Failed identify data %d:%s" , magic_errno (magic ), magic_error (magic ));
421392 RETVAL_FALSE ;
422393 }
423394
424- clean :
425- if (mimetype_emu ) {
426- magic_close (magic );
427- }
428-
429395 /* Restore options */
430396 if (options ) {
431397 magic_setflags (magic , options );
432398 }
433399}
434400/* }}} */
435401
436- /* {{{ Return information about a file. */
437- PHP_FUNCTION (finfo_file )
402+ /* Return content-type for file */
403+ PHP_FUNCTION (mime_content_type )
438404{
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 ;
442409
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+ }
449414
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 );
454472}
455- /* }}} */
0 commit comments