Back to index

php5  5.3.10
Classes | Defines | Functions | Variables
func_interceptors.c File Reference
#include "phar_internal.h"

Go to the source code of this file.

Classes

struct  _phar_orig_functions

Defines

#define PHAR_FUNC(name)   static PHP_NAMED_FUNCTION(name)
#define S_ISDIR(mode)   (((mode)&S_IFMT) == S_IFDIR)
#define S_ISREG(mode)   (((mode)&S_IFMT) == S_IFREG)
#define S_ISLNK(mode)   (((mode)&S_IFMT) == S_IFLNK)
#define S_IXROOT   ( S_IXUSR | S_IXGRP | S_IXOTH )
#define IS_LINK_OPERATION(__t)   ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)
#define IS_EXISTS_CHECK(__t)   ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK)
#define IS_ABLE_CHECK(__t)   ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)
#define IS_ACCESS_CHECK(__t)   (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)
#define PharFileFunction(fname, funcnum, orig)
#define PHAR_INTERCEPT(func)
#define PHAR_RELEASE(func)

Functions

 PHAR_FUNC (phar_opendir)
 PHAR_FUNC (phar_file_get_contents)
 PHAR_FUNC (phar_readfile)
 PHAR_FUNC (phar_fopen)
static void phar_fancy_stat (struct stat *stat_sb, int type, zval *return_value TSRMLS_DC)
static void phar_file_stat (const char *filename, php_stat_len filename_length, int type, void(*orig_stat_func)(INTERNAL_FUNCTION_PARAMETERS), INTERNAL_FUNCTION_PARAMETERS)
 PharFileFunction (phar_fileperms, FS_PERMS, orig_fileperms)
 PHAR_FUNC (phar_is_link)
 PharFileFunction (phar_lstat, FS_LSTAT, orig_lstat)
void phar_release_functions (TSRMLS_D)
void phar_intercept_functions_init (TSRMLS_D)
void phar_intercept_functions_shutdown (TSRMLS_D)
void phar_save_orig_functions (TSRMLS_D)
void phar_restore_orig_functions (TSRMLS_D)

Variables

static struct _phar_orig_functions phar_orig_functions

Define Documentation

#define IS_ABLE_CHECK (   __t)    ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)

Definition at line 437 of file func_interceptors.c.

#define IS_ACCESS_CHECK (   __t)    (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)

Definition at line 438 of file func_interceptors.c.

#define IS_EXISTS_CHECK (   __t)    ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK)

Definition at line 436 of file func_interceptors.c.

#define IS_LINK_OPERATION (   __t)    ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)

Definition at line 435 of file func_interceptors.c.

#define PHAR_FUNC (   name)    static PHP_NAMED_FUNCTION(name)

Definition at line 23 of file func_interceptors.c.

#define PHAR_INTERCEPT (   func)
Value:
PHAR_G(orig_##func) = NULL; \
       if (SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \
              PHAR_G(orig_##func) = orig->internal_function.handler; \
              orig->internal_function.handler = phar_##func; \
       }

Definition at line 1056 of file func_interceptors.c.

#define PHAR_RELEASE (   func)
Value:
if (PHAR_G(orig_##func) && SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \
              orig->internal_function.handler = PHAR_G(orig_##func); \
       } \
       PHAR_G(orig_##func) = NULL;

Definition at line 1094 of file func_interceptors.c.

#define PharFileFunction (   fname,
  funcnum,
  orig 
)
Value:
void fname(INTERNAL_FUNCTION_PARAMETERS) { \
       if (!PHAR_G(intercepted)) { \
              PHAR_G(orig)(INTERNAL_FUNCTION_PARAM_PASSTHRU); \
       } else { \
              char *filename; \
              int filename_len; \
		\
		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { \
                     return; \
              } \
		\
		phar_file_stat(filename, (php_stat_len) filename_len, funcnum, PHAR_G(orig), INTERNAL_FUNCTION_PARAM_PASSTHRU); \
       } \
}

Definition at line 808 of file func_interceptors.c.

#define S_ISDIR (   mode)    (((mode)&S_IFMT) == S_IFDIR)

Definition at line 424 of file func_interceptors.c.

#define S_ISLNK (   mode)    (((mode)&S_IFMT) == S_IFLNK)

Definition at line 430 of file func_interceptors.c.

#define S_ISREG (   mode)    (((mode)&S_IFMT) == S_IFREG)

Definition at line 427 of file func_interceptors.c.

#define S_IXROOT   ( S_IXUSR | S_IXGRP | S_IXOTH )

Definition at line 433 of file func_interceptors.c.


Function Documentation

static void phar_fancy_stat ( struct stat *  stat_sb,
int  type,
zval *return_value  TSRMLS_DC 
) [static]

Definition at line 442 of file func_interceptors.c.

{
       zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
               *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
       int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
       char *stat_sb_names[13] = {
              "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
              "size", "atime", "mtime", "ctime", "blksize", "blocks"
       };

#ifndef NETWARE
       if (type >= FS_IS_W && type <= FS_IS_X) {
              if(stat_sb->st_uid==getuid()) {
                     rmask=S_IRUSR;
                     wmask=S_IWUSR;
                     xmask=S_IXUSR;
              } else if(stat_sb->st_gid==getgid()) {
                     rmask=S_IRGRP;
                     wmask=S_IWGRP;
                     xmask=S_IXGRP;
              } else {
                     int   groups, n, i;
                     gid_t *gids;

                     groups = getgroups(0, NULL);
                     if(groups > 0) {
                            gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
                            n=getgroups(groups, gids);
                            for(i=0;i<n;++i){
                                   if(stat_sb->st_gid==gids[i]) {
                                          rmask=S_IRGRP;
                                          wmask=S_IWGRP;
                                          xmask=S_IXGRP;
                                          break;
                                   }
                            }
                            efree(gids);
                     }
              }
       }
#endif

       switch (type) {
       case FS_PERMS:
              RETURN_LONG((long)stat_sb->st_mode);
       case FS_INODE:
              RETURN_LONG((long)stat_sb->st_ino);
       case FS_SIZE:
              RETURN_LONG((long)stat_sb->st_size);
       case FS_OWNER:
              RETURN_LONG((long)stat_sb->st_uid);
       case FS_GROUP:
              RETURN_LONG((long)stat_sb->st_gid);
       case FS_ATIME:
#ifdef NETWARE
              RETURN_LONG((long)stat_sb->st_atime.tv_sec);
#else
              RETURN_LONG((long)stat_sb->st_atime);
#endif
       case FS_MTIME:
#ifdef NETWARE
              RETURN_LONG((long)stat_sb->st_mtime.tv_sec);
#else
              RETURN_LONG((long)stat_sb->st_mtime);
#endif
       case FS_CTIME:
#ifdef NETWARE
              RETURN_LONG((long)stat_sb->st_ctime.tv_sec);
#else
              RETURN_LONG((long)stat_sb->st_ctime);
#endif
       case FS_TYPE:
              if (S_ISLNK(stat_sb->st_mode)) {
                     RETURN_STRING("link", 1);
              }
              switch(stat_sb->st_mode & S_IFMT) {
              case S_IFDIR: RETURN_STRING("dir", 1);
              case S_IFREG: RETURN_STRING("file", 1);
              }
              php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%u)", stat_sb->st_mode & S_IFMT);
              RETURN_STRING("unknown", 1);
       case FS_IS_W:
              RETURN_BOOL((stat_sb->st_mode & wmask) != 0);
       case FS_IS_R:
              RETURN_BOOL((stat_sb->st_mode&rmask)!=0);
       case FS_IS_X:
              RETURN_BOOL((stat_sb->st_mode&xmask)!=0 && !S_ISDIR(stat_sb->st_mode));
       case FS_IS_FILE:
              RETURN_BOOL(S_ISREG(stat_sb->st_mode));
       case FS_IS_DIR:
              RETURN_BOOL(S_ISDIR(stat_sb->st_mode));
       case FS_IS_LINK:
              RETURN_BOOL(S_ISLNK(stat_sb->st_mode));
       case FS_EXISTS:
              RETURN_TRUE; /* the false case was done earlier */
       case FS_LSTAT:
              /* FALLTHROUGH */
       case FS_STAT:
              array_init(return_value);

              MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev);
              MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino);
              MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode);
              MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink);
              MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid);
              MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);
#ifdef HAVE_ST_RDEV
              MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev);
#else
              MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
#endif
              MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
#ifdef NETWARE
              MAKE_LONG_ZVAL_INCREF(stat_atime, (stat_sb->st_atime).tv_sec);
              MAKE_LONG_ZVAL_INCREF(stat_mtime, (stat_sb->st_mtime).tv_sec);
              MAKE_LONG_ZVAL_INCREF(stat_ctime, (stat_sb->st_ctime).tv_sec);
#else
              MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime);
              MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime);
              MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);
#endif
#ifdef HAVE_ST_BLKSIZE
              MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize);
#else
              MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
#endif
#ifdef HAVE_ST_BLOCKS
              MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);
#else
              MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
#endif
              /* Store numeric indexes in propper order */
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);

              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);

              /* Store string indexes referencing the same zval*/
              zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL);

              return;
       }
       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call");
       RETURN_FALSE;
}

Here is the caller graph for this function:

static void phar_file_stat ( const char *  filename,
php_stat_len  filename_length,
int  type,
void(*)(INTERNAL_FUNCTION_PARAMETERS orig_stat_func,
INTERNAL_FUNCTION_PARAMETERS   
) [static]

Definition at line 611 of file func_interceptors.c.

{
       if (!filename_length) {
              RETURN_FALSE;
       }

       if (!IS_ABSOLUTE_PATH(filename, filename_length) && !strstr(filename, "://")) {
              char *arch, *entry, *fname;
              int arch_len, entry_len, fname_len;
              struct stat sb = {0};
              phar_entry_info *data = NULL;
              phar_archive_data *phar;

              fname = zend_get_executed_filename(TSRMLS_C);

              /* we are checking for existence of a file within the relative path.  Chances are good that this is
                 retrieving something from within the phar archive */

              if (strncasecmp(fname, "phar://", 7)) {
                     goto skip_phar;
              }
              fname_len = strlen(fname);
              if (PHAR_G(last_phar) && fname_len - 7 >= PHAR_G(last_phar_name_len) && !memcmp(fname + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) {
                     arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
                     arch_len = PHAR_G(last_phar_name_len);
                     entry = estrndup(filename, filename_length);
                     /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                     entry_len = (int) filename_length;
                     phar = PHAR_G(last_phar);
                     goto splitted;
              }
              if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {

                     efree(entry);
                     entry = estrndup(filename, filename_length);
                     /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                     entry_len = (int) filename_length;
                     if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
                            efree(arch);
                            efree(entry);
                            goto skip_phar;
                     }
splitted:
                     entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
                     if (entry[0] == '/') {
                            if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
                                   efree(entry);
                                   goto stat_entry;
                            }
                            goto notfound;
                     }
                     if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &data)) {
                            efree(entry);
                            goto stat_entry;
                     }
                     if (zend_hash_exists(&(phar->virtual_dirs), entry, entry_len)) {
                            efree(entry);
                            efree(arch);
                            if (IS_EXISTS_CHECK(type)) {
                                   RETURN_TRUE;
                            }
                            sb.st_size = 0;
                            sb.st_mode = 0777;
                            sb.st_mode |= S_IFDIR; /* regular directory */
#ifdef NETWARE
                            sb.st_mtime.tv_sec = phar->max_timestamp;
                            sb.st_atime.tv_sec = phar->max_timestamp;
                            sb.st_ctime.tv_sec = phar->max_timestamp;
#else
                            sb.st_mtime = phar->max_timestamp;
                            sb.st_atime = phar->max_timestamp;
                            sb.st_ctime = phar->max_timestamp;
#endif
                            goto statme_baby;
                     } else {
                            char *save;
                            int save_len;

notfound:
                            efree(entry);
                            save = PHAR_G(cwd);
                            save_len = PHAR_G(cwd_len);
                            /* this file is not in the current directory, use the original path */
                            entry = estrndup(filename, filename_length);
                            entry_len = filename_length;
                            PHAR_G(cwd) = "/";
                            PHAR_G(cwd_len) = 0;
                            /* clean path without cwd */
                            entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
                            if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
                                   PHAR_G(cwd) = save;
                                   PHAR_G(cwd_len) = save_len;
                                   efree(entry);
                                   if (IS_EXISTS_CHECK(type)) {
                                          efree(arch);
                                          RETURN_TRUE;
                                   }
                                   goto stat_entry;
                            }
                            if (zend_hash_exists(&(phar->virtual_dirs), entry + 1, entry_len - 1)) {
                                   PHAR_G(cwd) = save;
                                   PHAR_G(cwd_len) = save_len;
                                   efree(entry);
                                   efree(arch);
                                   if (IS_EXISTS_CHECK(type)) {
                                          RETURN_TRUE;
                                   }
                                   sb.st_size = 0;
                                   sb.st_mode = 0777;
                                   sb.st_mode |= S_IFDIR; /* regular directory */
#ifdef NETWARE
                                   sb.st_mtime.tv_sec = phar->max_timestamp;
                                   sb.st_atime.tv_sec = phar->max_timestamp;
                                   sb.st_ctime.tv_sec = phar->max_timestamp;
#else
                                   sb.st_mtime = phar->max_timestamp;
                                   sb.st_atime = phar->max_timestamp;
                                   sb.st_ctime = phar->max_timestamp;
#endif
                                   goto statme_baby;
                            }
                            PHAR_G(cwd) = save;
                            PHAR_G(cwd_len) = save_len;
                            efree(entry);
                            efree(arch);
                            /* Error Occured */
                            if (!IS_EXISTS_CHECK(type)) {
                                   php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
                            }
                            RETURN_FALSE;
                     }
stat_entry:
                     efree(arch);
                     if (!data->is_dir) {
                            sb.st_size = data->uncompressed_filesize;
                            sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
                            if (data->link) {
                                   sb.st_mode |= S_IFREG|S_IFLNK; /* regular file */
                            } else {
                                   sb.st_mode |= S_IFREG; /* regular file */
                            }
                            /* timestamp is just the timestamp when this was added to the phar */
#ifdef NETWARE
                            sb.st_mtime.tv_sec = data->timestamp;
                            sb.st_atime.tv_sec = data->timestamp;
                            sb.st_ctime.tv_sec = data->timestamp;
#else
                            sb.st_mtime = data->timestamp;
                            sb.st_atime = data->timestamp;
                            sb.st_ctime = data->timestamp;
#endif
                     } else {
                            sb.st_size = 0;
                            sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
                            sb.st_mode |= S_IFDIR; /* regular directory */
                            if (data->link) {
                                   sb.st_mode |= S_IFLNK;
                            }
                            /* timestamp is just the timestamp when this was added to the phar */
#ifdef NETWARE
                            sb.st_mtime.tv_sec = data->timestamp;
                            sb.st_atime.tv_sec = data->timestamp;
                            sb.st_ctime.tv_sec = data->timestamp;
#else
                            sb.st_mtime = data->timestamp;
                            sb.st_atime = data->timestamp;
                            sb.st_ctime = data->timestamp;
#endif
                     }

statme_baby:
                     if (!phar->is_writeable) {
                            sb.st_mode = (sb.st_mode & 0555) | (sb.st_mode & ~0777);
                     }

                     sb.st_nlink = 1;
                     sb.st_rdev = -1;
                     /* this is only for APC, so use /dev/null device - no chance of conflict there! */
                     sb.st_dev = 0xc;
                     /* generate unique inode number for alias/filename, so no phars will conflict */
                     if (data) {
                            sb.st_ino = data->inode;
                     }
#ifndef PHP_WIN32
                     sb.st_blksize = -1;
                     sb.st_blocks = -1;
#endif
                     phar_fancy_stat(&sb, type, return_value TSRMLS_CC);
                     return;
              }
       }
skip_phar:
       orig_stat_func(INTERNAL_FUNCTION_PARAM_PASSTHRU);
       return;
}

Here is the call graph for this function:

PHAR_FUNC ( phar_opendir  )

Definition at line 26 of file func_interceptors.c.

{
       char *filename;
       int filename_len;
       zval *zcontext = NULL;

       if (!PHAR_G(intercepted)) {
              goto skip_phar;
       }

       if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
              && !cached_phars.arBuckets) {
              goto skip_phar;
       }

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &filename, &filename_len, &zcontext) == FAILURE) {
              return;
       }

       if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
              char *arch, *entry, *fname;
              int arch_len, entry_len, fname_len;
              fname = zend_get_executed_filename(TSRMLS_C);

              /* we are checking for existence of a file within the relative path.  Chances are good that this is
                 retrieving something from within the phar archive */

              if (strncasecmp(fname, "phar://", 7)) {
                     goto skip_phar;
              }
              fname_len = strlen(fname);
              if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                     php_stream_context *context = NULL;
                     php_stream *stream;
                     char *name;

                     efree(entry);
                     entry = estrndup(filename, filename_len);
                     /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                     entry_len = filename_len;
                     /* retrieving a file within the current directory, so use this if possible */
                     entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);

                     if (entry[0] == '/') {
                            spprintf(&name, 4096, "phar://%s%s", arch, entry);
                     } else {
                            spprintf(&name, 4096, "phar://%s/%s", arch, entry);
                     }
                     efree(entry);
                     efree(arch);
                     if (zcontext) {
                            context = php_stream_context_from_zval(zcontext, 0);
                     }
                     stream = php_stream_opendir(name, REPORT_ERRORS, context);
                     efree(name);
                     if (!stream) {
                            RETURN_FALSE;
                     }
                     php_stream_to_zval(stream, return_value);
                     return;
              }
       }
skip_phar:
       PHAR_G(orig_opendir)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
       return;
}

Here is the call graph for this function:

PHAR_FUNC ( phar_file_get_contents  )

Definition at line 94 of file func_interceptors.c.

{
       char *filename;
       int filename_len;
       char *contents;
       zend_bool use_include_path = 0;
       php_stream *stream;
       int len;
       long offset = -1;
       long maxlen = PHP_STREAM_COPY_ALL;
       zval *zcontext = NULL;

       if (!PHAR_G(intercepted)) {
              goto skip_phar;
       }

       if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
              && !cached_phars.arBuckets) {
              goto skip_phar;
       }

       /* Parse arguments */
       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
              goto skip_phar;
       }

       if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
              char *arch, *entry, *fname;
              int arch_len, entry_len, fname_len;
              php_stream_context *context = NULL;

              fname = zend_get_executed_filename(TSRMLS_C);

              if (strncasecmp(fname, "phar://", 7)) {
                     goto skip_phar;
              }
              fname_len = strlen(fname);
              if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                     char *name;
                     phar_archive_data *phar;

                     efree(entry);
                     entry = filename;
                     /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                     entry_len = filename_len;

                     if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
                            efree(arch);
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal to zero");
                            RETURN_FALSE;
                     }

                     /* retrieving a file defaults to within the current directory, so use this if possible */
                     if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
                            efree(arch);
                            goto skip_phar;
                     }
                     if (use_include_path) {
                            if ((entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
                                   name = entry;
                                   goto phar_it;
                            } else {
                                   /* this file is not in the phar, use the original path */
                                   efree(arch);
                                   goto skip_phar;
                            }
                     } else {
                            entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                            if (entry[0] == '/') {
                                   if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
                                          /* this file is not in the phar, use the original path */
notfound:
                                          efree(arch);
                                          efree(entry);
                                          goto skip_phar;
                                   }
                            } else {
                                   if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
                                          goto notfound;
                                   }
                            }
                            /* auto-convert to phar:// */
                            if (entry[0] == '/') {
                                   spprintf(&name, 4096, "phar://%s%s", arch, entry);
                            } else {
                                   spprintf(&name, 4096, "phar://%s/%s", arch, entry);
                            }
                            if (entry != filename) {
                                   efree(entry);
                            }
                     }

phar_it:
                     efree(arch);
                     if (zcontext) {
                            context = php_stream_context_from_zval(zcontext, 0);
                     }
                     stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, context);
                     efree(name);

                     if (!stream) {
                            RETURN_FALSE;
                     }

                     if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset);
                            php_stream_close(stream);
                            RETURN_FALSE;
                     }

                     /* uses mmap if possible */
                     if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
#if PHP_MAJOR_VERSION < 6
                            if (PG(magic_quotes_runtime)) {
                                   int newlen;
                                   contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free source string */
                                   len = newlen;
                            }
#endif
                            RETVAL_STRINGL(contents, len, 0);
                     } else if (len == 0) {
                            RETVAL_EMPTY_STRING();
                     } else {
                            RETVAL_FALSE;
                     }

                     php_stream_close(stream);
                     return;
              }
       }
skip_phar:
       PHAR_G(orig_file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
       return;
}

Here is the call graph for this function:

PHAR_FUNC ( phar_readfile  )

Definition at line 230 of file func_interceptors.c.

{
       char *filename;
       int filename_len;
       int size = 0;
       zend_bool use_include_path = 0;
       zval *zcontext = NULL;
       php_stream *stream;

       if (!PHAR_G(intercepted)) {
              goto skip_phar;
       }

       if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
              && !cached_phars.arBuckets) {
              goto skip_phar;
       }
       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
              goto skip_phar;
       }
       if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
              char *arch, *entry, *fname;
              int arch_len, entry_len, fname_len;
              php_stream_context *context = NULL;
              char *name;
              phar_archive_data *phar;
              fname = zend_get_executed_filename(TSRMLS_C);

              if (strncasecmp(fname, "phar://", 7)) {
                     goto skip_phar;
              }
              fname_len = strlen(fname);
              if (FAILURE == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                     goto skip_phar;
              }

              efree(entry);
              entry = filename;
              /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
              entry_len = filename_len;
              /* retrieving a file defaults to within the current directory, so use this if possible */
              if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
                     efree(arch);
                     goto skip_phar;
              }
              if (use_include_path) {
                     if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
                            /* this file is not in the phar, use the original path */
                            efree(arch);
                            goto skip_phar;
                     } else {
                            name = entry;
                     }
              } else {
                     entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                     if (entry[0] == '/') {
                            if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
                                   /* this file is not in the phar, use the original path */
notfound:
                                   efree(entry);
                                   efree(arch);
                                   goto skip_phar;
                            }
                     } else {
                            if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
                                   goto notfound;
                            }
                     }
                     /* auto-convert to phar:// */
                     if (entry[0] == '/') {
                            spprintf(&name, 4096, "phar://%s%s", arch, entry);
                     } else {
                            spprintf(&name, 4096, "phar://%s/%s", arch, entry);
                     }
                     efree(entry);
              }

              efree(arch);
              context = php_stream_context_from_zval(zcontext, 0);
              stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, context);
              efree(name);
              if (stream == NULL) {
                     RETURN_FALSE;
              }
              size = php_stream_passthru(stream);
              php_stream_close(stream);
              RETURN_LONG(size);
       }

skip_phar:
       PHAR_G(orig_readfile)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
       return;

}

Here is the call graph for this function:

PHAR_FUNC ( phar_fopen  )

Definition at line 326 of file func_interceptors.c.

{
       char *filename, *mode;
       int filename_len, mode_len;
       zend_bool use_include_path = 0;
       zval *zcontext = NULL;
       php_stream *stream;

       if (!PHAR_G(intercepted)) {
              goto skip_phar;
       }

       if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
              && !cached_phars.arBuckets) {
              /* no need to check, include_path not even specified in fopen/ no active phars */
              goto skip_phar;
       }
       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
              goto skip_phar;
       }
       if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
              char *arch, *entry, *fname;
              int arch_len, entry_len, fname_len;
              php_stream_context *context = NULL;
              char *name;
              phar_archive_data *phar;
              fname = zend_get_executed_filename(TSRMLS_C);

              if (strncasecmp(fname, "phar://", 7)) {
                     goto skip_phar;
              }
              fname_len = strlen(fname);
              if (FAILURE == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                     goto skip_phar;
              }

              efree(entry);
              entry = filename;
              /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
              entry_len = filename_len;
              /* retrieving a file defaults to within the current directory, so use this if possible */
              if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
                     efree(arch);
                     goto skip_phar;
              }
              if (use_include_path) {
                     if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
                            /* this file is not in the phar, use the original path */
                            efree(arch);
                            goto skip_phar;
                     } else {
                            name = entry;
                     }
              } else {
                     entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                     if (entry[0] == '/') {
                            if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
                                   /* this file is not in the phar, use the original path */
notfound:
                                   efree(entry);
                                   efree(arch);
                                   goto skip_phar;
                            }
                     } else {
                            if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
                                   /* this file is not in the phar, use the original path */
                                   goto notfound;
                            }
                     }
                     /* auto-convert to phar:// */
                     if (entry[0] == '/') {
                            spprintf(&name, 4096, "phar://%s%s", arch, entry);
                     } else {
                            spprintf(&name, 4096, "phar://%s/%s", arch, entry);
                     }
                     efree(entry);
              }

              efree(arch);
              context = php_stream_context_from_zval(zcontext, 0);
              stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, context);
              efree(name);
              if (stream == NULL) {
                     RETURN_FALSE;
              }
              php_stream_to_zval(stream, return_value);
              if (zcontext) {
                     zend_list_addref(Z_RESVAL_P(zcontext));
              }
              return;
       }
skip_phar:
       PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
       return;
}

Here is the call graph for this function:

PHAR_FUNC ( phar_is_link  )

Definition at line 962 of file func_interceptors.c.

{
       char *filename;
       int filename_len;

       if (!PHAR_G(intercepted)) {
              goto skip_phar;
       }

       if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
              && !cached_phars.arBuckets) {
              goto skip_phar;
       }
       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
              goto skip_phar;
       }
       if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
              char *arch, *entry, *fname;
              int arch_len, entry_len, fname_len;
              fname = zend_get_executed_filename(TSRMLS_C);

              /* we are checking for existence of a file within the relative path.  Chances are good that this is
                 retrieving something from within the phar archive */

              if (strncasecmp(fname, "phar://", 7)) {
                     goto skip_phar;
              }
              fname_len = strlen(fname);
              if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                     phar_archive_data *phar;

                     efree(entry);
                     entry = filename;
                     /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                     entry_len = filename_len;
                     /* retrieving a file within the current directory, so use this if possible */
                     if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
                            phar_entry_info *etemp;

                            entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                            if (entry[0] == '/') {
                                   if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
                                          /* this file is not in the current directory, use the original path */
found_it:
                                          efree(entry);
                                          efree(arch);
                                          RETURN_BOOL(etemp->link);
                                   }
                            } else {
                                   if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
                                          goto found_it;
                                   }
                            }
                     }
                     efree(entry);
                     efree(arch);
                     RETURN_FALSE;
              }
       }
skip_phar:
       PHAR_G(orig_is_link)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
       return;
}

Here is the call graph for this function:

Definition at line 1063 of file func_interceptors.c.

{
       zend_function *orig;

       PHAR_INTERCEPT(fopen);
       PHAR_INTERCEPT(file_get_contents);
       PHAR_INTERCEPT(is_file);
       PHAR_INTERCEPT(is_link);
       PHAR_INTERCEPT(is_dir);
       PHAR_INTERCEPT(opendir);
       PHAR_INTERCEPT(file_exists);
       PHAR_INTERCEPT(fileperms);
       PHAR_INTERCEPT(fileinode);
       PHAR_INTERCEPT(filesize);
       PHAR_INTERCEPT(fileowner);
       PHAR_INTERCEPT(filegroup);
       PHAR_INTERCEPT(fileatime);
       PHAR_INTERCEPT(filemtime);
       PHAR_INTERCEPT(filectime);
       PHAR_INTERCEPT(filetype);
       PHAR_INTERCEPT(is_writable);
       PHAR_INTERCEPT(is_readable);
       PHAR_INTERCEPT(is_executable);
       PHAR_INTERCEPT(lstat);
       PHAR_INTERCEPT(stat);
       PHAR_INTERCEPT(readfile);
       PHAR_G(intercepted) = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1100 of file func_interceptors.c.

{
       zend_function *orig;

       PHAR_RELEASE(fopen);
       PHAR_RELEASE(file_get_contents);
       PHAR_RELEASE(is_file);
       PHAR_RELEASE(is_dir);
       PHAR_RELEASE(opendir);
       PHAR_RELEASE(file_exists);
       PHAR_RELEASE(fileperms);
       PHAR_RELEASE(fileinode);
       PHAR_RELEASE(filesize);
       PHAR_RELEASE(fileowner);
       PHAR_RELEASE(filegroup);
       PHAR_RELEASE(fileatime);
       PHAR_RELEASE(filemtime);
       PHAR_RELEASE(filectime);
       PHAR_RELEASE(filetype);
       PHAR_RELEASE(is_writable);
       PHAR_RELEASE(is_readable);
       PHAR_RELEASE(is_executable);
       PHAR_RELEASE(lstat);
       PHAR_RELEASE(stat);
       PHAR_RELEASE(readfile);
       PHAR_G(intercepted) = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1049 of file func_interceptors.c.

{
       PHAR_G(intercepted) = 0;
}

Here is the caller graph for this function:

PharFileFunction ( phar_fileperms  ,
FS_PERMS  ,
orig_fileperms   
)

Definition at line 827 of file func_interceptors.c.

{
       char *filename;
       int filename_len;

       if (!PHAR_G(intercepted)) {
              goto skip_phar;
       }

       if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
              && !cached_phars.arBuckets) {
              goto skip_phar;
       }
       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
              goto skip_phar;
       }
       if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
              char *arch, *entry, *fname;
              int arch_len, entry_len, fname_len;
              fname = zend_get_executed_filename(TSRMLS_C);

              /* we are checking for existence of a file within the relative path.  Chances are good that this is
                 retrieving something from within the phar archive */

              if (strncasecmp(fname, "phar://", 7)) {
                     goto skip_phar;
              }
              fname_len = strlen(fname);
              if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
                     phar_archive_data *phar;

                     efree(entry);
                     entry = filename;
                     /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
                     entry_len = filename_len;
                     /* retrieving a file within the current directory, so use this if possible */
                     if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
                            phar_entry_info *etemp;

                            entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
                            if (entry[0] == '/') {
                                   if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
                                          /* this file is not in the current directory, use the original path */
found_it:
                                          efree(entry);
                                          efree(arch);
                                          RETURN_BOOL(!etemp->is_dir);
                                   }
                            } else {
                                   if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
                                          goto found_it;
                                   }
                            }
                     }
                     if (entry != filename) {
                            efree(entry);
                     }
                     efree(arch);
                     RETURN_FALSE;
              }
       }
skip_phar:
       PHAR_G(orig_is_file)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
       return;
}

Here is the call graph for this function:

PharFileFunction ( phar_lstat  ,
FS_LSTAT  ,
orig_lstat   
)

Definition at line 1029 of file func_interceptors.c.


Variable Documentation