Back to index

php5  5.3.10
Classes | Defines | Functions | Variables
fileinfo.c File Reference
#include "php.h"
#include <magic.h>
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/file.h"
#include "php_fileinfo.h"
#include "fopen_wrappers.h"

Go to the source code of this file.

Classes

struct  php_fileinfo
struct  finfo_object

Defines

#define HOWMANY   65536
#define _S_IFDIR   S_IFDIR
#define FILEINFO_DECLARE_INIT_OBJECT(object)   zval *object = getThis();
#define FILEINFO_REGISTER_OBJECT(_object, _ptr)
#define FILEINFO_FROM_OBJECT(finfo, object)
#define FINFO_SET_OPTION(magic, options)
#define FILEINFO_MODE_BUFFER   0
#define FILEINFO_MODE_STREAM   1
#define FILEINFO_MODE_FILE   2

Functions

static void finfo_objects_dtor (void *object, zend_object_handle handle TSRMLS_DC)
PHP_FILEINFO_API zend_object_value finfo_objects_new (zend_class_entry *class_type TSRMLS_DC)
void finfo_resource_destructor (zend_rsrc_list_entry *rsrc TSRMLS_DC)
 PHP_MINIT_FUNCTION (finfo)
 PHP_MINFO_FUNCTION (fileinfo)
 PHP_FUNCTION (finfo_open)
 PHP_FUNCTION (finfo_close)
 PHP_FUNCTION (finfo_set_flags)
static void _php_finfo_get_type (INTERNAL_FUNCTION_PARAMETERS, int mode, int mimetype_emu)
 PHP_FUNCTION (finfo_file)
 PHP_FUNCTION (finfo_buffer)
 PHP_FUNCTION (mime_content_type)

Variables

static zend_object_handlers finfo_object_handlers
zend_class_entry * finfo_class_entry
zend_function_entry finfo_class_functions []
static int le_fileinfo
zend_function_entry fileinfo_functions []
zend_module_entry fileinfo_module_entry

Class Documentation

struct php_fileinfo

Definition at line 46 of file fileinfo.c.

Collaboration diagram for php_fileinfo:
Class Members
struct magic_set * magic
long options
struct finfo_object

Definition at line 54 of file fileinfo.c.

Collaboration diagram for finfo_object:
Class Members
struct php_fileinfo * ptr
zend_object zo

Define Documentation

#define _S_IFDIR   S_IFDIR

Definition at line 42 of file fileinfo.c.

#define FILEINFO_DECLARE_INIT_OBJECT (   object)    zval *object = getThis();

Definition at line 59 of file fileinfo.c.

#define FILEINFO_FROM_OBJECT (   finfo,
  object 
)
Value:
{ \
       struct finfo_object *obj = zend_object_store_get_object(object TSRMLS_CC); \
       finfo = obj->ptr; \
       if (!finfo) { \
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "The invalid fileinfo object."); \
              RETURN_FALSE; \
       } \
}

Definition at line 69 of file fileinfo.c.

#define FILEINFO_MODE_BUFFER   0

Definition at line 396 of file fileinfo.c.

#define FILEINFO_MODE_FILE   2

Definition at line 398 of file fileinfo.c.

#define FILEINFO_MODE_STREAM   1

Definition at line 397 of file fileinfo.c.

#define FILEINFO_REGISTER_OBJECT (   _object,
  _ptr 
)
Value:
{ \
       struct finfo_object *obj; \
        obj = (struct finfo_object*)zend_object_store_get_object(_object TSRMLS_CC); \
        obj->ptr = _ptr; \
}

Definition at line 62 of file fileinfo.c.

#define FINFO_SET_OPTION (   magic,
  options 
)
Value:
if (magic_setflags(magic, options) == -1) { \
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to set option '%ld' %d:%s", \
                            options, magic_errno(magic), magic_error(magic)); \
              RETURN_FALSE; \
       }

Definition at line 179 of file fileinfo.c.

#define HOWMANY   65536

Definition at line 32 of file fileinfo.c.


Function Documentation

static void _php_finfo_get_type ( INTERNAL_FUNCTION_PARAMETERS  ,
int  mode,
int  mimetype_emu 
) [static]

Definition at line 400 of file fileinfo.c.

{
       long options = 0;
       char *ret_val = NULL, *buffer = NULL;
       int buffer_len;
       struct php_fileinfo *finfo = NULL;
       zval *zfinfo, *zcontext = NULL;
       zval *what;
       char mime_directory[] = "directory";

       struct magic_set *magic = NULL;
       FILEINFO_DECLARE_INIT_OBJECT(object)

       if (mimetype_emu) {

              /* mime_content_type(..) emulation */
              if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &what) == FAILURE) {
                     return;
              }

              switch (Z_TYPE_P(what)) {
                     case IS_STRING:
                            buffer = Z_STRVAL_P(what);
                            buffer_len = Z_STRLEN_P(what);
                            mode = FILEINFO_MODE_FILE;
                            break;

                     case IS_RESOURCE:
                            mode = FILEINFO_MODE_STREAM;
                            break;

                     default:
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only process string or stream arguments");
                            RETURN_FALSE;
              }

              magic = magic_open(MAGIC_MIME_TYPE);
              if (magic_load(magic, NULL) == -1) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database.");
                     goto common;
              }
       } else if (object) {
              if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
                     RETURN_FALSE;
              }
              FILEINFO_FROM_OBJECT(finfo, object);
              magic = finfo->magic;
       } else {
              if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|lr", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
                     RETURN_FALSE;
              }
              ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
              magic = finfo->magic;
       }      

       /* Set options for the current file/buffer. */
       if (options) {
              FINFO_SET_OPTION(magic, options)
       }

       switch (mode) {
              case FILEINFO_MODE_BUFFER:
              {
                     ret_val = (char *) magic_buffer(magic, buffer, buffer_len);
                     break;
              }

              case FILEINFO_MODE_STREAM:
              {
                            php_stream *stream;
                            off_t streampos;

                            php_stream_from_zval_no_verify(stream, &what);
                            if (!stream) {
                                   goto common;
                            }

                            streampos = php_stream_tell(stream); /* remember stream position for restoration */
                            php_stream_seek(stream, 0, SEEK_SET);

                            ret_val = (char *) magic_stream(magic, stream);

                            php_stream_seek(stream, streampos, SEEK_SET);
                            break;
              }

              case FILEINFO_MODE_FILE:
              {
                     /* determine if the file is a local file or remote URL */
                     char *tmp2;
                     php_stream_wrapper *wrap;
                     php_stream_statbuf ssb;

                     if (buffer == NULL || !*buffer) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty filename or path");
                            RETVAL_FALSE;
                            goto clean;
                     }

                     wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0 TSRMLS_CC);

                     if (wrap) {
                            php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
#if PHP_API_VERSION < 20100412
                            php_stream *stream = php_stream_open_wrapper_ex(buffer, "rb", ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);
#else
                            php_stream *stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context);
#endif

                            if (!stream) {
                                   RETVAL_FALSE;
                                   goto clean;
                            }

                            if (php_stream_stat(stream, &ssb) == SUCCESS) {
                                   if (ssb.sb.st_mode & S_IFDIR) {
                                          ret_val = mime_directory;
                                   } else {
                                          ret_val = (char *)magic_stream(magic, stream);
                                   }
                            }

                            php_stream_close(stream);
                     }
                     break;
              }

              default:
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only process string or stream arguments");
       }

common:
       if (ret_val) {
              RETVAL_STRING(ret_val, 1);
       } else {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
              RETVAL_FALSE;
       }

clean:
       if (mimetype_emu) {
              magic_close(magic);
       }

       /* Restore options */
       if (options) {
              FINFO_SET_OPTION(magic, finfo->options)
       }
       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void finfo_objects_dtor ( void *  object,
zend_object_handle handle  TSRMLS_DC 
) [static]

Definition at line 81 of file fileinfo.c.

{
       struct finfo_object *intern = (struct finfo_object *) object;

       if (intern->ptr) {
              magic_close(intern->ptr->magic);
              efree(intern->ptr);
       }

       zend_object_std_dtor(&intern->zo TSRMLS_CC);
       efree(intern);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHP_FILEINFO_API zend_object_value finfo_objects_new ( zend_class_entry *class_type  TSRMLS_DC)

Definition at line 97 of file fileinfo.c.

{
       zend_object_value retval;
       struct finfo_object *intern;
       zval *tmp;

       intern = emalloc(sizeof(struct finfo_object));
       memset(intern, 0, sizeof(struct finfo_object));

       zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
       zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *));

       intern->ptr = NULL;

       retval.handle = zend_objects_store_put(intern, finfo_objects_dtor, NULL, NULL TSRMLS_CC);
       retval.handlers = (zend_object_handlers *) &finfo_object_handlers;

       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 190 of file fileinfo.c.

{
       if (rsrc->ptr) {
              struct php_fileinfo *finfo = (struct php_fileinfo *) rsrc->ptr;
              magic_close(finfo->magic);
              efree(rsrc->ptr);
              rsrc->ptr = NULL;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHP_FUNCTION ( finfo_open  )

Definition at line 281 of file fileinfo.c.

{
       long options = MAGIC_NONE;
       char *file = NULL;
       int file_len = 0;
       struct php_fileinfo *finfo;
       FILEINFO_DECLARE_INIT_OBJECT(object)
       char resolved_path[MAXPATHLEN];

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &options, &file, &file_len) == FAILURE) {
              RETURN_FALSE;
       }
       
       if (object) {
              struct finfo_object *finfo_obj = (struct finfo_object*)zend_object_store_get_object(object TSRMLS_CC);
              
              if (finfo_obj->ptr) {
                     magic_close(finfo_obj->ptr->magic);
                     efree(finfo_obj->ptr);
                     finfo_obj->ptr = NULL;
              }
       }

       if (file_len == 0) {
              file = NULL;
       } else if (file && *file) { /* user specified file, perform open_basedir checks */
              if (strlen(file) != file_len) {
                     RETURN_FALSE;
              }
              if (!VCWD_REALPATH(file, resolved_path)) {
                     RETURN_FALSE;
              }
              file = resolved_path;

#if PHP_API_VERSION < 20100412
              if ((PG(safe_mode) && (!php_checkuid(file, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(file TSRMLS_CC)) {
#else
              if (php_check_open_basedir(file TSRMLS_CC)) {
#endif
                     RETURN_FALSE;
              }
       }

       finfo = emalloc(sizeof(struct php_fileinfo));

       finfo->options = options;
       finfo->magic = magic_open(options);

       if (finfo->magic == NULL) {
              efree(finfo);
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid mode '%ld'.", options);
              RETURN_FALSE; 
       }

       if (magic_load(finfo->magic, file) == -1) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to load magic database at '%s'.", file);
              magic_close(finfo->magic);
              efree(finfo);
              RETURN_FALSE;
       }      

       if (object) {
              FILEINFO_REGISTER_OBJECT(object, finfo);
       } else {
              ZEND_REGISTER_RESOURCE(return_value, finfo, le_fileinfo);
       }      
}

Here is the call graph for this function:

PHP_FUNCTION ( finfo_close  )

Definition at line 352 of file fileinfo.c.

{
       struct php_fileinfo *finfo;
       zval *zfinfo;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zfinfo) == FAILURE) {
              RETURN_FALSE;
       }
       ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);

       zend_list_delete(Z_RESVAL_P(zfinfo));

       RETURN_TRUE;
}

Here is the call graph for this function:

PHP_FUNCTION ( finfo_set_flags  )

Definition at line 370 of file fileinfo.c.

{
       long options;
       struct php_fileinfo *finfo;
       zval *zfinfo;
       FILEINFO_DECLARE_INIT_OBJECT(object)

       if (object) {
              if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &options) == FAILURE) {
                     RETURN_FALSE;
              }
              FILEINFO_FROM_OBJECT(finfo, object);
       } else {
              if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zfinfo, &options) == FAILURE) {
                     RETURN_FALSE;
              }
              ZEND_FETCH_RESOURCE(finfo, struct php_fileinfo *, &zfinfo, -1, "file_info", le_fileinfo);
       }

       FINFO_SET_OPTION(finfo->magic, options)
       finfo->options = options;

       RETURN_TRUE;
}

Here is the call graph for this function:

PHP_FUNCTION ( finfo_file  )

Definition at line 554 of file fileinfo.c.

Here is the call graph for this function:

PHP_FUNCTION ( finfo_buffer  )

Definition at line 562 of file fileinfo.c.

Here is the call graph for this function:

PHP_FUNCTION ( mime_content_type  )

Definition at line 570 of file fileinfo.c.

Here is the call graph for this function:

PHP_MINFO_FUNCTION ( fileinfo  )

Definition at line 270 of file fileinfo.c.

Here is the call graph for this function:

PHP_MINIT_FUNCTION ( finfo  )

Definition at line 217 of file fileinfo.c.

{
       zend_class_entry _finfo_class_entry;
       INIT_CLASS_ENTRY(_finfo_class_entry, "finfo", finfo_class_functions);
       _finfo_class_entry.create_object = finfo_objects_new;
       finfo_class_entry = zend_register_internal_class(&_finfo_class_entry TSRMLS_CC);

       /* copy the standard object handlers to you handler table */
       memcpy(&finfo_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));

       le_fileinfo = zend_register_list_destructors_ex(finfo_resource_destructor, NULL, "file_info", module_number);

       REGISTER_LONG_CONSTANT("FILEINFO_NONE",                 MAGIC_NONE, CONST_CS|CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("FILEINFO_SYMLINK",              MAGIC_SYMLINK, CONST_CS|CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("FILEINFO_MIME",                 MAGIC_MIME, CONST_CS|CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("FILEINFO_MIME_TYPE",     MAGIC_MIME_TYPE, CONST_CS|CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("FILEINFO_MIME_ENCODING",MAGIC_MIME_ENCODING, CONST_CS|CONST_PERSISTENT);
/*     REGISTER_LONG_CONSTANT("FILEINFO_COMPRESS",             MAGIC_COMPRESS, CONST_CS|CONST_PERSISTENT); disabled, as it does fork now */
       REGISTER_LONG_CONSTANT("FILEINFO_DEVICES",              MAGIC_DEVICES, CONST_CS|CONST_PERSISTENT);
       REGISTER_LONG_CONSTANT("FILEINFO_CONTINUE",             MAGIC_CONTINUE, CONST_CS|CONST_PERSISTENT);
#ifdef MAGIC_PRESERVE_ATIME
       REGISTER_LONG_CONSTANT("FILEINFO_PRESERVE_ATIME",       MAGIC_PRESERVE_ATIME, CONST_CS|CONST_PERSISTENT);
#endif
#ifdef MAGIC_RAW
       REGISTER_LONG_CONSTANT("FILEINFO_RAW",                  MAGIC_RAW, CONST_CS|CONST_PERSISTENT);
#endif

       return SUCCESS;
}

Here is the call graph for this function:


Variable Documentation

Initial value:
 {





       PHP_FE(mime_content_type, arginfo_mime_content_type)
       {NULL, NULL, NULL}
}

Definition at line 204 of file fileinfo.c.

zend_module_entry fileinfo_module_entry
Initial value:

Definition at line 250 of file fileinfo.c.

zend_class_entry* finfo_class_entry

Definition at line 52 of file fileinfo.c.

Initial value:

Definition at line 170 of file fileinfo.c.

zend_object_handlers finfo_object_handlers [static]

Definition at line 51 of file fileinfo.c.

int le_fileinfo [static]

Definition at line 187 of file fileinfo.c.