PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/phar - func_interceptors.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 516 598 86.3 %
Date: 2014-10-30 Functions: 30 30 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | phar php single-file executable PHP extension                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 2005-2014 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt.                                 |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Gregory Beaver <cellog@php.net>                             |
      16             :   +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : /* $Id$ */
      20             : 
      21             : #include "phar_internal.h"
      22             : 
      23             : #define PHAR_FUNC(name) \
      24             :         static PHP_NAMED_FUNCTION(name)
      25             : 
      26         791 : PHAR_FUNC(phar_opendir) /* {{{ */
      27             : {
      28             :         char *filename;
      29             :         size_t filename_len;
      30         791 :         zval *zcontext = NULL;
      31             : 
      32         791 :         if (!PHAR_G(intercepted)) {
      33         783 :                 goto skip_phar;
      34             :         }
      35             : 
      36           9 :         if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
      37           1 :                 && !cached_phars.arHash) {
      38           1 :                 goto skip_phar;
      39             :         }
      40             : 
      41           7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|z", &filename, &filename_len, &zcontext) == FAILURE) {
      42           1 :                 return;
      43             :         }
      44             : 
      45           6 :         if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
      46             :                 char *arch, *entry, *fname;
      47             :                 int arch_len, entry_len, fname_len;
      48           4 :                 fname = (char*)zend_get_executed_filename(TSRMLS_C);
      49             : 
      50             :                 /* we are checking for existence of a file within the relative path.  Chances are good that this is
      51             :                    retrieving something from within the phar archive */
      52             : 
      53           4 :                 if (strncasecmp(fname, "phar://", 7)) {
      54           1 :                         goto skip_phar;
      55             :                 }
      56           3 :                 fname_len = strlen(fname);
      57           3 :                 if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
      58           3 :                         php_stream_context *context = NULL;
      59             :                         php_stream *stream;
      60             :                         char *name;
      61             : 
      62           3 :                         efree(entry);
      63           3 :                         entry = estrndup(filename, filename_len);
      64             :                         /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
      65           3 :                         entry_len = filename_len;
      66             :                         /* retrieving a file within the current directory, so use this if possible */
      67           3 :                         entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
      68             : 
      69           3 :                         if (entry[0] == '/') {
      70           1 :                                 spprintf(&name, 4096, "phar://%s%s", arch, entry);
      71             :                         } else {
      72           2 :                                 spprintf(&name, 4096, "phar://%s/%s", arch, entry);
      73             :                         }
      74           3 :                         efree(entry);
      75           3 :                         efree(arch);
      76           3 :                         if (zcontext) {
      77           1 :                                 context = php_stream_context_from_zval(zcontext, 0);
      78             :                         }
      79           3 :                         stream = php_stream_opendir(name, REPORT_ERRORS, context);
      80           3 :                         efree(name);
      81           3 :                         if (!stream) {
      82           1 :                                 RETURN_FALSE;
      83             :                         }
      84           2 :                         php_stream_to_zval(stream, return_value);
      85           2 :                         return;
      86             :                 }
      87             :         }
      88             : skip_phar:
      89         787 :         PHAR_G(orig_opendir)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
      90         787 :         return;
      91             : }
      92             : /* }}} */
      93             : 
      94        3202 : PHAR_FUNC(phar_file_get_contents) /* {{{ */
      95             : {
      96             :         char *filename;
      97             :         size_t filename_len;
      98             :         zend_string *contents;
      99        3202 :         zend_bool use_include_path = 0;
     100             :         php_stream *stream;
     101        3202 :         zend_long offset = -1;
     102        3202 :         zend_long maxlen = PHP_STREAM_COPY_ALL;
     103        3202 :         zval *zcontext = NULL;
     104             : 
     105        3202 :         if (!PHAR_G(intercepted)) {
     106        3187 :                 goto skip_phar;
     107             :         }
     108             : 
     109          16 :         if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     110           1 :                 && !cached_phars.arHash) {
     111           1 :                 goto skip_phar;
     112             :         }
     113             : 
     114             :         /* Parse arguments */
     115          14 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
     116           1 :                 goto skip_phar;
     117             :         }
     118             : 
     119          13 :         if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
     120             :                 char *arch, *entry, *fname;
     121             :                 int arch_len, entry_len, fname_len;
     122          12 :                 php_stream_context *context = NULL;
     123             : 
     124          12 :                 fname = (char*)zend_get_executed_filename(TSRMLS_C);
     125             : 
     126          12 :                 if (strncasecmp(fname, "phar://", 7)) {
     127           0 :                         goto skip_phar;
     128             :                 }
     129          12 :                 fname_len = strlen(fname);
     130          12 :                 if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
     131             :                         char *name;
     132             :                         phar_archive_data *phar;
     133             : 
     134          12 :                         efree(entry);
     135          12 :                         entry = filename;
     136             :                         /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
     137          12 :                         entry_len = filename_len;
     138             : 
     139          12 :                         if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
     140           1 :                                 efree(arch);
     141           1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal to zero");
     142           1 :                                 RETURN_FALSE;
     143             :                         }
     144             : 
     145             :                         /* retrieving a file defaults to within the current directory, so use this if possible */
     146          11 :                         if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
     147           0 :                                 efree(arch);
     148           0 :                                 goto skip_phar;
     149             :                         }
     150          11 :                         if (use_include_path) {
     151           2 :                                 if ((entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
     152           2 :                                         name = entry;
     153           2 :                                         goto phar_it;
     154             :                                 } else {
     155             :                                         /* this file is not in the phar, use the original path */
     156           0 :                                         efree(arch);
     157           0 :                                         goto skip_phar;
     158             :                                 }
     159             :                         } else {
     160           9 :                                 entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
     161           9 :                                 if (entry[0] == '/') {
     162           3 :                                         if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
     163             :                                                 /* this file is not in the phar, use the original path */
     164             : notfound:
     165           1 :                                                 efree(arch);
     166           1 :                                                 efree(entry);
     167           1 :                                                 goto skip_phar;
     168             :                                         }
     169             :                                 } else {
     170           6 :                                         if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) {
     171           1 :                                                 goto notfound;
     172             :                                         }
     173             :                                 }
     174             :                                 /* auto-convert to phar:// */
     175           8 :                                 if (entry[0] == '/') {
     176           3 :                                         spprintf(&name, 4096, "phar://%s%s", arch, entry);
     177             :                                 } else {
     178           5 :                                         spprintf(&name, 4096, "phar://%s/%s", arch, entry);
     179             :                                 }
     180           8 :                                 if (entry != filename) {
     181           8 :                                         efree(entry);
     182             :                                 }
     183             :                         }
     184             : 
     185             : phar_it:
     186          10 :                         efree(arch);
     187          10 :                         if (zcontext) {
     188           3 :                                 context = php_stream_context_from_zval(zcontext, 0);
     189             :                         }
     190          10 :                         stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, context);
     191          10 :                         efree(name);
     192             : 
     193          10 :                         if (!stream) {
     194           1 :                                 RETURN_FALSE;
     195             :                         }
     196             : 
     197           9 :                         if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
     198           1 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %pd in the stream", offset);
     199           1 :                                 php_stream_close(stream);
     200           1 :                                 RETURN_FALSE;
     201             :                         }
     202             : 
     203             :                         /* uses mmap if possible */
     204           8 :                         contents = php_stream_copy_to_mem(stream, maxlen, 0);
     205          15 :                         if (contents && contents->len > 0) {
     206           7 :                                 RETVAL_STR(contents);
     207           1 :                         } else if (contents) {
     208             :                                 zend_string_release(contents);
     209           1 :                                 RETVAL_EMPTY_STRING();
     210             :                         } else {
     211           0 :                                 RETVAL_FALSE;
     212             :                         }
     213             : 
     214           8 :                         php_stream_close(stream);
     215           8 :                         return;
     216             :                 }
     217             :         }
     218             : skip_phar:
     219        3191 :         PHAR_G(orig_file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     220        3191 :         return;
     221             : }
     222             : /* }}} */
     223             : 
     224         460 : PHAR_FUNC(phar_readfile) /* {{{ */
     225             : {
     226             :         char *filename;
     227             :         size_t filename_len;
     228         460 :         int size = 0;
     229         460 :         zend_bool use_include_path = 0;
     230         460 :         zval *zcontext = NULL;
     231             :         php_stream *stream;
     232             : 
     233         460 :         if (!PHAR_G(intercepted)) {
     234         457 :                 goto skip_phar;
     235             :         }
     236             : 
     237           4 :         if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     238           1 :                 && !cached_phars.arHash) {
     239           1 :                 goto skip_phar;
     240             :         }
     241           2 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
     242           0 :                 goto skip_phar;
     243             :         }
     244           2 :         if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
     245             :                 char *arch, *entry, *fname;
     246             :                 int arch_len, entry_len, fname_len;
     247           2 :                 php_stream_context *context = NULL;
     248             :                 char *name;
     249             :                 phar_archive_data *phar;
     250           2 :                 fname = (char*)zend_get_executed_filename(TSRMLS_C);
     251             : 
     252           2 :                 if (strncasecmp(fname, "phar://", 7)) {
     253           0 :                         goto skip_phar;
     254             :                 }
     255           2 :                 fname_len = strlen(fname);
     256           2 :                 if (FAILURE == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
     257           0 :                         goto skip_phar;
     258             :                 }
     259             : 
     260           2 :                 efree(entry);
     261           2 :                 entry = filename;
     262             :                 /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
     263           2 :                 entry_len = filename_len;
     264             :                 /* retrieving a file defaults to within the current directory, so use this if possible */
     265           2 :                 if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
     266           0 :                         efree(arch);
     267           0 :                         goto skip_phar;
     268             :                 }
     269           2 :                 if (use_include_path) {
     270           1 :                         if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
     271             :                                 /* this file is not in the phar, use the original path */
     272           0 :                                 efree(arch);
     273           0 :                                 goto skip_phar;
     274             :                         } else {
     275           1 :                                 name = entry;
     276             :                         }
     277             :                 } else {
     278           1 :                         entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
     279           1 :                         if (entry[0] == '/') {
     280           1 :                                 if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
     281             :                                         /* this file is not in the phar, use the original path */
     282             : notfound:
     283           0 :                                         efree(entry);
     284           0 :                                         efree(arch);
     285           0 :                                         goto skip_phar;
     286             :                                 }
     287             :                         } else {
     288           0 :                                 if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) {
     289           0 :                                         goto notfound;
     290             :                                 }
     291             :                         }
     292             :                         /* auto-convert to phar:// */
     293           1 :                         if (entry[0] == '/') {
     294           1 :                                 spprintf(&name, 4096, "phar://%s%s", arch, entry);
     295             :                         } else {
     296           0 :                                 spprintf(&name, 4096, "phar://%s/%s", arch, entry);
     297             :                         }
     298           1 :                         efree(entry);
     299             :                 }
     300             : 
     301           2 :                 efree(arch);
     302           2 :                 context = php_stream_context_from_zval(zcontext, 0);
     303           2 :                 stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, context);
     304           2 :                 efree(name);
     305           2 :                 if (stream == NULL) {
     306           0 :                         RETURN_FALSE;
     307             :                 }
     308           2 :                 size = php_stream_passthru(stream);
     309           2 :                 php_stream_close(stream);
     310           2 :                 RETURN_LONG(size);
     311             :         }
     312             : 
     313             : skip_phar:
     314         458 :         PHAR_G(orig_readfile)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     315         458 :         return;
     316             : 
     317             : }
     318             : /* }}} */
     319             : 
     320       24196 : PHAR_FUNC(phar_fopen) /* {{{ */
     321             : {
     322             :         char *filename, *mode;
     323             :         size_t filename_len, mode_len;
     324       24196 :         zend_bool use_include_path = 0;
     325       24196 :         zval *zcontext = NULL;
     326             :         php_stream *stream;
     327             : 
     328       24196 :         if (!PHAR_G(intercepted)) {
     329       24189 :                 goto skip_phar;
     330             :         }
     331             : 
     332           8 :         if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     333           1 :                 && !cached_phars.arHash) {
     334             :                 /* no need to check, include_path not even specified in fopen/ no active phars */
     335           1 :                 goto skip_phar;
     336             :         }
     337           6 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ps|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
     338           1 :                 goto skip_phar;
     339             :         }
     340           5 :         if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
     341             :                 char *arch, *entry, *fname;
     342             :                 size_t arch_len, entry_len, fname_len;
     343           4 :                 php_stream_context *context = NULL;
     344             :                 char *name;
     345             :                 phar_archive_data *phar;
     346           4 :                 fname = (char*)zend_get_executed_filename(TSRMLS_C);
     347             : 
     348           4 :                 if (strncasecmp(fname, "phar://", 7)) {
     349           0 :                         goto skip_phar;
     350             :                 }
     351           4 :                 fname_len = strlen(fname);
     352           4 :                 if (FAILURE == phar_split_fname(fname, fname_len, &arch, (int *)&arch_len, &entry, (int *)&entry_len, 2, 0 TSRMLS_CC)) {
     353           0 :                         goto skip_phar;
     354             :                 }
     355             : 
     356           4 :                 efree(entry);
     357           4 :                 entry = filename;
     358             :                 /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
     359           4 :                 entry_len = filename_len;
     360             :                 /* retrieving a file defaults to within the current directory, so use this if possible */
     361           4 :                 if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
     362           0 :                         efree(arch);
     363           0 :                         goto skip_phar;
     364             :                 }
     365           4 :                 if (use_include_path) {
     366           3 :                         if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
     367             :                                 /* this file is not in the phar, use the original path */
     368           1 :                                 efree(arch);
     369           1 :                                 goto skip_phar;
     370             :                         } else {
     371           2 :                                 name = entry;
     372             :                         }
     373             :                 } else {
     374           1 :                         entry = phar_fix_filepath(estrndup(entry, entry_len), (int *)&entry_len, 1 TSRMLS_CC);
     375           1 :                         if (entry[0] == '/') {
     376           1 :                                 if (!zend_hash_str_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
     377             :                                         /* this file is not in the phar, use the original path */
     378             : notfound:
     379           0 :                                         efree(entry);
     380           0 :                                         efree(arch);
     381           0 :                                         goto skip_phar;
     382             :                                 }
     383             :                         } else {
     384           0 :                                 if (!zend_hash_str_exists(&(phar->manifest), entry, entry_len)) {
     385             :                                         /* this file is not in the phar, use the original path */
     386           0 :                                         goto notfound;
     387             :                                 }
     388             :                         }
     389             :                         /* auto-convert to phar:// */
     390           1 :                         if (entry[0] == '/') {
     391           1 :                                 spprintf(&name, 4096, "phar://%s%s", arch, entry);
     392             :                         } else {
     393           0 :                                 spprintf(&name, 4096, "phar://%s/%s", arch, entry);
     394             :                         }
     395           1 :                         efree(entry);
     396             :                 }
     397             : 
     398           3 :                 efree(arch);
     399           3 :                 context = php_stream_context_from_zval(zcontext, 0);
     400           3 :                 stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, context);
     401           3 :                 efree(name);
     402           3 :                 if (stream == NULL) {
     403           0 :                         RETURN_FALSE;
     404             :                 }
     405           3 :                 php_stream_to_zval(stream, return_value);
     406           3 :                 if (zcontext) {
     407           0 :                         Z_ADDREF_P(zcontext);
     408             :                 }
     409           3 :                 return;
     410             :         }
     411             : skip_phar:
     412       24193 :         PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     413       24192 :         return;
     414             : }
     415             : /* }}} */
     416             : 
     417             : #ifndef S_ISDIR
     418             : #define S_ISDIR(mode)   (((mode)&S_IFMT) == S_IFDIR)
     419             : #endif
     420             : #ifndef S_ISREG
     421             : #define S_ISREG(mode)   (((mode)&S_IFMT) == S_IFREG)
     422             : #endif
     423             : #ifndef S_ISLNK
     424             : #define S_ISLNK(mode)   (((mode)&S_IFMT) == S_IFLNK)
     425             : #endif
     426             : 
     427             : #define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
     428             : 
     429             : #define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)
     430             : #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)
     431             : #define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)
     432             : #define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)
     433             : 
     434             : /* {{{ php_stat
     435             :  */
     436          19 : static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value TSRMLS_DC)
     437             : {
     438             :         zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev,
     439             :                  stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks;
     440          19 :         int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
     441             :         char *stat_sb_names[13] = {
     442             :                 "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
     443             :                 "size", "atime", "mtime", "ctime", "blksize", "blocks"
     444          19 :         };
     445             : 
     446             : #ifndef NETWARE
     447          19 :         if (type >= FS_IS_W && type <= FS_IS_X) {
     448           3 :                 if(stat_sb->st_uid==getuid()) {
     449           0 :                         rmask=S_IRUSR;
     450           0 :                         wmask=S_IWUSR;
     451           0 :                         xmask=S_IXUSR;
     452           3 :                 } else if(stat_sb->st_gid==getgid()) {
     453           0 :                         rmask=S_IRGRP;
     454           0 :                         wmask=S_IWGRP;
     455           0 :                         xmask=S_IXGRP;
     456             :                 } else {
     457             :                         int   groups, n, i;
     458             :                         gid_t *gids;
     459             : 
     460           3 :                         groups = getgroups(0, NULL);
     461           3 :                         if(groups > 0) {
     462           3 :                                 gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
     463           3 :                                 n=getgroups(groups, gids);
     464           9 :                                 for(i=0;i<n;++i){
     465           6 :                                         if(stat_sb->st_gid==gids[i]) {
     466           0 :                                                 rmask=S_IRGRP;
     467           0 :                                                 wmask=S_IWGRP;
     468           0 :                                                 xmask=S_IXGRP;
     469           0 :                                                 break;
     470             :                                         }
     471             :                                 }
     472           3 :                                 efree(gids);
     473             :                         }
     474             :                 }
     475             :         }
     476             : #endif
     477             : 
     478          19 :         switch (type) {
     479             :         case FS_PERMS:
     480           1 :                 RETURN_LONG((zend_long)stat_sb->st_mode);
     481             :         case FS_INODE:
     482           1 :                 RETURN_LONG((zend_long)stat_sb->st_ino);
     483             :         case FS_SIZE:
     484           1 :                 RETURN_LONG((zend_long)stat_sb->st_size);
     485             :         case FS_OWNER:
     486           1 :                 RETURN_LONG((zend_long)stat_sb->st_uid);
     487             :         case FS_GROUP:
     488           1 :                 RETURN_LONG((zend_long)stat_sb->st_gid);
     489             :         case FS_ATIME:
     490             : #ifdef NETWARE
     491             :                 RETURN_LONG((zend_long)stat_sb->st_atime.tv_sec);
     492             : #else
     493           1 :                 RETURN_LONG((zend_long)stat_sb->st_atime);
     494             : #endif
     495             :         case FS_MTIME:
     496             : #ifdef NETWARE
     497             :                 RETURN_LONG((zend_long)stat_sb->st_mtime.tv_sec);
     498             : #else
     499           1 :                 RETURN_LONG((zend_long)stat_sb->st_mtime);
     500             : #endif
     501             :         case FS_CTIME:
     502             : #ifdef NETWARE
     503             :                 RETURN_LONG((zend_long)stat_sb->st_ctime.tv_sec);
     504             : #else
     505           1 :                 RETURN_LONG((zend_long)stat_sb->st_ctime);
     506             : #endif
     507             :         case FS_TYPE:
     508           3 :                 if (S_ISLNK(stat_sb->st_mode)) {
     509           2 :                         RETURN_STRING("link");
     510             :                 }
     511           2 :                 switch(stat_sb->st_mode & S_IFMT) {
     512           2 :                 case S_IFDIR: RETURN_STRING("dir");
     513           2 :                 case S_IFREG: RETURN_STRING("file");
     514             :                 }
     515           0 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%u)", stat_sb->st_mode & S_IFMT);
     516           0 :                 RETURN_STRING("unknown");
     517             :         case FS_IS_W:
     518           1 :                 RETURN_BOOL((stat_sb->st_mode & wmask) != 0);
     519             :         case FS_IS_R:
     520           1 :                 RETURN_BOOL((stat_sb->st_mode&rmask)!=0);
     521             :         case FS_IS_X:
     522           1 :                 RETURN_BOOL((stat_sb->st_mode&xmask)!=0 && !S_ISDIR(stat_sb->st_mode));
     523             :         case FS_IS_FILE:
     524           0 :                 RETURN_BOOL(S_ISREG(stat_sb->st_mode));
     525             :         case FS_IS_DIR:
     526           1 :                 RETURN_BOOL(S_ISDIR(stat_sb->st_mode));
     527             :         case FS_IS_LINK:
     528           0 :                 RETURN_BOOL(S_ISLNK(stat_sb->st_mode));
     529             :         case FS_EXISTS:
     530           2 :                 RETURN_TRUE; /* the false case was done earlier */
     531             :         case FS_LSTAT:
     532             :                 /* FALLTHROUGH */
     533             :         case FS_STAT:
     534           2 :                 array_init(return_value);
     535             : 
     536           2 :                 ZVAL_LONG(&stat_dev, stat_sb->st_dev);
     537           2 :                 ZVAL_LONG(&stat_ino, stat_sb->st_ino);
     538           2 :                 ZVAL_LONG(&stat_mode, stat_sb->st_mode);
     539           2 :                 ZVAL_LONG(&stat_nlink, stat_sb->st_nlink);
     540           2 :                 ZVAL_LONG(&stat_uid, stat_sb->st_uid);
     541           2 :                 ZVAL_LONG(&stat_gid, stat_sb->st_gid);
     542             : #ifdef HAVE_ST_RDEV
     543           2 :                 ZVAL_LONG(&stat_rdev, stat_sb->st_rdev);
     544             : #else
     545             :                 ZVAL_LONG(&stat_rdev, -1);
     546             : #endif
     547           2 :                 ZVAL_LONG(&stat_size, stat_sb->st_size);
     548             : #ifdef NETWARE
     549             :                 ZVAL_LONG(&stat_atime, (stat_sb->st_atime).tv_sec);
     550             :                 ZVAL_LONG(&stat_mtime, (stat_sb->st_mtime).tv_sec);
     551             :                 ZVAL_LONG(&stat_ctime, (stat_sb->st_ctime).tv_sec);
     552             : #else
     553           2 :                 ZVAL_LONG(&stat_atime, stat_sb->st_atime);
     554           2 :                 ZVAL_LONG(&stat_mtime, stat_sb->st_mtime);
     555           2 :                 ZVAL_LONG(&stat_ctime, stat_sb->st_ctime);
     556             : #endif
     557             : #ifdef HAVE_ST_BLKSIZE
     558           2 :                 ZVAL_LONG(&stat_blksize, stat_sb->st_blksize);
     559             : #else
     560             :                 ZVAL_LONG(&stat_blksize,-1);
     561             : #endif
     562             : #ifdef HAVE_ST_BLOCKS
     563           2 :                 ZVAL_LONG(&stat_blocks, stat_sb->st_blocks);
     564             : #else
     565             :                 ZVAL_LONG(&stat_blocks,-1);
     566             : #endif
     567             :                 /* Store numeric indexes in propper order */
     568           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_dev);
     569           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_ino);
     570           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_mode);
     571           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_nlink);
     572           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_uid);
     573           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_gid);
     574             : 
     575           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_rdev);
     576           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_size);
     577           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_atime);
     578           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_mtime);
     579           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_ctime);
     580           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_blksize);
     581           2 :                 zend_hash_next_index_insert(HASH_OF(return_value), &stat_blocks);
     582             : 
     583             :                 /* Store string indexes referencing the same zval*/
     584           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0]), &stat_dev);
     585           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1]), &stat_ino);
     586           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2]), &stat_mode);
     587           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3]), &stat_nlink);
     588           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4]), &stat_uid);
     589           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5]), &stat_gid);
     590           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6]), &stat_rdev);
     591           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7]), &stat_size);
     592           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8]), &stat_atime);
     593           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9]), &stat_mtime);
     594           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10]), &stat_ctime);
     595           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize);
     596           4 :                 zend_hash_str_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks);
     597             : 
     598           2 :                 return;
     599             :         }
     600           0 :         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call");
     601           0 :         RETURN_FALSE;
     602             : }
     603             : /* }}} */
     604             : 
     605          27 : 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) /* {{{ */
     606             : {
     607          27 :         if (!filename_length) {
     608           1 :                 RETURN_FALSE;
     609             :         }
     610             : 
     611          26 :         if (!IS_ABSOLUTE_PATH(filename, filename_length) && !strstr(filename, "://")) {
     612             :                 char *arch, *entry, *fname;
     613             :                 int arch_len, entry_len, fname_len;
     614          25 :                 zend_stat_t sb = {0};
     615          25 :                 phar_entry_info *data = NULL;
     616             :                 phar_archive_data *phar;
     617             : 
     618          25 :                 fname = (char*)zend_get_executed_filename(TSRMLS_C);
     619             : 
     620             :                 /* we are checking for existence of a file within the relative path.  Chances are good that this is
     621             :                    retrieving something from within the phar archive */
     622             : 
     623          25 :                 if (strncasecmp(fname, "phar://", 7)) {
     624           0 :                         goto skip_phar;
     625             :                 }
     626          25 :                 fname_len = strlen(fname);
     627          25 :                 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))) {
     628          21 :                         arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
     629          21 :                         arch_len = PHAR_G(last_phar_name_len);
     630          21 :                         entry = estrndup(filename, filename_length);
     631             :                         /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
     632          21 :                         entry_len = (int) filename_length;
     633          21 :                         phar = PHAR_G(last_phar);
     634          21 :                         goto splitted;
     635             :                 }
     636           4 :                 if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
     637             : 
     638           1 :                         efree(entry);
     639           1 :                         entry = estrndup(filename, filename_length);
     640             :                         /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
     641           1 :                         entry_len = (int) filename_length;
     642           1 :                         if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
     643           0 :                                 efree(arch);
     644           0 :                                 efree(entry);
     645           0 :                                 goto skip_phar;
     646             :                         }
     647             : splitted:
     648          22 :                         entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
     649          22 :                         if (entry[0] == '/') {
     650          38 :                                 if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
     651          17 :                                         efree(entry);
     652          17 :                                         goto stat_entry;
     653             :                                 }
     654           2 :                                 goto notfound;
     655             :                         }
     656           6 :                         if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) {
     657           2 :                                 efree(entry);
     658           2 :                                 goto stat_entry;
     659             :                         }
     660           1 :                         if (zend_hash_str_exists(&(phar->virtual_dirs), entry, entry_len)) {
     661           1 :                                 efree(entry);
     662           1 :                                 efree(arch);
     663           1 :                                 if (IS_EXISTS_CHECK(type)) {
     664           1 :                                         RETURN_TRUE;
     665             :                                 }
     666           0 :                                 sb.st_size = 0;
     667           0 :                                 sb.st_mode = 0777;
     668           0 :                                 sb.st_mode |= S_IFDIR; /* regular directory */
     669             : #ifdef NETWARE
     670             :                                 sb.st_mtime.tv_sec = phar->max_timestamp;
     671             :                                 sb.st_atime.tv_sec = phar->max_timestamp;
     672             :                                 sb.st_ctime.tv_sec = phar->max_timestamp;
     673             : #else
     674           0 :                                 sb.st_mtime = phar->max_timestamp;
     675           0 :                                 sb.st_atime = phar->max_timestamp;
     676           0 :                                 sb.st_ctime = phar->max_timestamp;
     677             : #endif
     678           0 :                                 goto statme_baby;
     679             :                         } else {
     680             :                                 char *save;
     681             :                                 int save_len;
     682             : 
     683             : notfound:
     684           2 :                                 efree(entry);
     685           2 :                                 save = PHAR_G(cwd);
     686           2 :                                 save_len = PHAR_G(cwd_len);
     687             :                                 /* this file is not in the current directory, use the original path */
     688           2 :                                 entry = estrndup(filename, filename_length);
     689           2 :                                 entry_len = filename_length;
     690           2 :                                 PHAR_G(cwd) = "/";
     691           2 :                                 PHAR_G(cwd_len) = 0;
     692             :                                 /* clean path without cwd */
     693           2 :                                 entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
     694           4 :                                 if (NULL != (data = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
     695           0 :                                         PHAR_G(cwd) = save;
     696           0 :                                         PHAR_G(cwd_len) = save_len;
     697           0 :                                         efree(entry);
     698           0 :                                         if (IS_EXISTS_CHECK(type)) {
     699           0 :                                                 efree(arch);
     700           0 :                                                 RETURN_TRUE;
     701             :                                         }
     702           0 :                                         goto stat_entry;
     703             :                                 }
     704           2 :                                 if (zend_hash_str_exists(&(phar->virtual_dirs), entry + 1, entry_len - 1)) {
     705           0 :                                         PHAR_G(cwd) = save;
     706           0 :                                         PHAR_G(cwd_len) = save_len;
     707           0 :                                         efree(entry);
     708           0 :                                         efree(arch);
     709           0 :                                         if (IS_EXISTS_CHECK(type)) {
     710           0 :                                                 RETURN_TRUE;
     711             :                                         }
     712           0 :                                         sb.st_size = 0;
     713           0 :                                         sb.st_mode = 0777;
     714           0 :                                         sb.st_mode |= S_IFDIR; /* regular directory */
     715             : #ifdef NETWARE
     716             :                                         sb.st_mtime.tv_sec = phar->max_timestamp;
     717             :                                         sb.st_atime.tv_sec = phar->max_timestamp;
     718             :                                         sb.st_ctime.tv_sec = phar->max_timestamp;
     719             : #else
     720           0 :                                         sb.st_mtime = phar->max_timestamp;
     721           0 :                                         sb.st_atime = phar->max_timestamp;
     722           0 :                                         sb.st_ctime = phar->max_timestamp;
     723             : #endif
     724           0 :                                         goto statme_baby;
     725             :                                 }
     726           2 :                                 PHAR_G(cwd) = save;
     727           2 :                                 PHAR_G(cwd_len) = save_len;
     728           2 :                                 efree(entry);
     729           2 :                                 efree(arch);
     730             :                                 /* Error Occurred */
     731           2 :                                 if (!IS_EXISTS_CHECK(type)) {
     732           1 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
     733             :                                 }
     734           2 :                                 RETURN_FALSE;
     735             :                         }
     736             : stat_entry:
     737          19 :                         efree(arch);
     738          19 :                         if (!data->is_dir) {
     739          18 :                                 sb.st_size = data->uncompressed_filesize;
     740          18 :                                 sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
     741          18 :                                 if (data->link) {
     742           1 :                                         sb.st_mode |= S_IFREG|S_IFLNK; /* regular file */
     743             :                                 } else {
     744          17 :                                         sb.st_mode |= S_IFREG; /* regular file */
     745             :                                 }
     746             :                                 /* timestamp is just the timestamp when this was added to the phar */
     747             : #ifdef NETWARE
     748             :                                 sb.st_mtime.tv_sec = data->timestamp;
     749             :                                 sb.st_atime.tv_sec = data->timestamp;
     750             :                                 sb.st_ctime.tv_sec = data->timestamp;
     751             : #else
     752          18 :                                 sb.st_mtime = data->timestamp;
     753          18 :                                 sb.st_atime = data->timestamp;
     754          18 :                                 sb.st_ctime = data->timestamp;
     755             : #endif
     756             :                         } else {
     757           1 :                                 sb.st_size = 0;
     758           1 :                                 sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
     759           1 :                                 sb.st_mode |= S_IFDIR; /* regular directory */
     760           1 :                                 if (data->link) {
     761           0 :                                         sb.st_mode |= S_IFLNK;
     762             :                                 }
     763             :                                 /* timestamp is just the timestamp when this was added to the phar */
     764             : #ifdef NETWARE
     765             :                                 sb.st_mtime.tv_sec = data->timestamp;
     766             :                                 sb.st_atime.tv_sec = data->timestamp;
     767             :                                 sb.st_ctime.tv_sec = data->timestamp;
     768             : #else
     769           1 :                                 sb.st_mtime = data->timestamp;
     770           1 :                                 sb.st_atime = data->timestamp;
     771           1 :                                 sb.st_ctime = data->timestamp;
     772             : #endif
     773             :                         }
     774             : 
     775             : statme_baby:
     776          19 :                         if (!phar->is_writeable) {
     777           1 :                                 sb.st_mode = (sb.st_mode & 0555) | (sb.st_mode & ~0777);
     778             :                         }
     779             : 
     780          19 :                         sb.st_nlink = 1;
     781          19 :                         sb.st_rdev = -1;
     782             :                         /* this is only for APC, so use /dev/null device - no chance of conflict there! */
     783          19 :                         sb.st_dev = 0xc;
     784             :                         /* generate unique inode number for alias/filename, so no phars will conflict */
     785          19 :                         if (data) {
     786          19 :                                 sb.st_ino = data->inode;
     787             :                         }
     788             : #ifndef PHP_WIN32
     789          19 :                         sb.st_blksize = -1;
     790          19 :                         sb.st_blocks = -1;
     791             : #endif
     792          19 :                         phar_fancy_stat(&sb, type, return_value TSRMLS_CC);
     793          19 :                         return;
     794             :                 }
     795             :         }
     796             : skip_phar:
     797           4 :         orig_stat_func(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     798           4 :         return;
     799             : }
     800             : /* }}} */
     801             : 
     802             : #define PharFileFunction(fname, funcnum, orig) \
     803             : void fname(INTERNAL_FUNCTION_PARAMETERS) { \
     804             :         if (!PHAR_G(intercepted)) { \
     805             :                 PHAR_G(orig)(INTERNAL_FUNCTION_PARAM_PASSTHRU); \
     806             :         } else { \
     807             :                 char *filename; \
     808             :                 size_t filename_len; \
     809             :                 \
     810             :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { \
     811             :                         return; \
     812             :                 } \
     813             :                 \
     814             :                 phar_file_stat(filename, (php_stat_len) filename_len, funcnum, PHAR_G(orig), INTERNAL_FUNCTION_PARAM_PASSTHRU); \
     815             :         } \
     816             : }
     817             : /* }}} */
     818             : 
     819             : /* {{{ proto int fileperms(string filename)
     820             :    Get file permissions */
     821        6785 : PharFileFunction(phar_fileperms, FS_PERMS, orig_fileperms)
     822             : /* }}} */
     823             : 
     824             : /* {{{ proto int fileinode(string filename)
     825             :    Get file inode */
     826          71 : PharFileFunction(phar_fileinode, FS_INODE, orig_fileinode)
     827             : /* }}} */
     828             : 
     829             : /* {{{ proto int filesize(string filename)
     830             :    Get file size */
     831       13811 : PharFileFunction(phar_filesize, FS_SIZE, orig_filesize)
     832             : /* }}} */
     833             : 
     834             : /* {{{ proto int fileowner(string filename)
     835             :    Get file owner */
     836          82 : PharFileFunction(phar_fileowner, FS_OWNER, orig_fileowner)
     837             : /* }}} */
     838             : 
     839             : /* {{{ proto int filegroup(string filename)
     840             :    Get file group */
     841          54 : PharFileFunction(phar_filegroup, FS_GROUP, orig_filegroup)
     842             : /* }}} */
     843             : 
     844             : /* {{{ proto int fileatime(string filename)
     845             :    Get last access time of file */
     846          53 : PharFileFunction(phar_fileatime, FS_ATIME, orig_fileatime)
     847             : /* }}} */
     848             : 
     849             : /* {{{ proto int filemtime(string filename)
     850             :    Get last modification time of file */
     851          53 : PharFileFunction(phar_filemtime, FS_MTIME, orig_filemtime)
     852             : /* }}} */
     853             : 
     854             : /* {{{ proto int filectime(string filename)
     855             :    Get inode modification time of file */
     856          48 : PharFileFunction(phar_filectime, FS_CTIME, orig_filectime)
     857             : /* }}} */
     858             : 
     859             : /* {{{ proto string filetype(string filename)
     860             :    Get file type */
     861          42 : PharFileFunction(phar_filetype, FS_TYPE, orig_filetype)
     862             : /* }}} */
     863             : 
     864             : /* {{{ proto bool is_writable(string filename)
     865             :    Returns true if file can be written */
     866         568 : PharFileFunction(phar_is_writable, FS_IS_W, orig_is_writable)
     867             : /* }}} */
     868             : 
     869             : /* {{{ proto bool is_readable(string filename)
     870             :    Returns true if file can be read */
     871         698 : PharFileFunction(phar_is_readable, FS_IS_R, orig_is_readable)
     872             : /* }}} */
     873             : 
     874             : /* {{{ proto bool is_executable(string filename)
     875             :    Returns true if file is executable */
     876         617 : PharFileFunction(phar_is_executable, FS_IS_X, orig_is_executable)
     877             : /* }}} */
     878             : 
     879             : /* {{{ proto bool file_exists(string filename)
     880             :    Returns true if filename exists */
     881        3113 : PharFileFunction(phar_file_exists, FS_EXISTS, orig_file_exists)
     882             : /* }}} */
     883             : 
     884             : /* {{{ proto bool is_dir(string filename)
     885             :    Returns true if file is directory */
     886       28064 : PharFileFunction(phar_is_dir, FS_IS_DIR, orig_is_dir)
     887             : /* }}} */
     888             : 
     889        1293 : PHAR_FUNC(phar_is_file) /* {{{ */
     890             : {
     891             :         char *filename;
     892             :         size_t filename_len;
     893             : 
     894        1293 :         if (!PHAR_G(intercepted)) {
     895        1285 :                 goto skip_phar;
     896             :         }
     897             : 
     898           9 :         if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     899           1 :                 && !cached_phars.arHash) {
     900           1 :                 goto skip_phar;
     901             :         }
     902           7 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
     903           1 :                 goto skip_phar;
     904             :         }
     905           6 :         if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
     906             :                 char *arch, *entry, *fname;
     907             :                 int arch_len, entry_len, fname_len;
     908           5 :                 fname = (char*)zend_get_executed_filename(TSRMLS_C);
     909             : 
     910             :                 /* we are checking for existence of a file within the relative path.  Chances are good that this is
     911             :                    retrieving something from within the phar archive */
     912             : 
     913           5 :                 if (strncasecmp(fname, "phar://", 7)) {
     914           0 :                         goto skip_phar;
     915             :                 }
     916           5 :                 fname_len = strlen(fname);
     917           5 :                 if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
     918             :                         phar_archive_data *phar;
     919             : 
     920           5 :                         efree(entry);
     921           5 :                         entry = filename;
     922             :                         /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
     923           5 :                         entry_len = filename_len;
     924             :                         /* retrieving a file within the current directory, so use this if possible */
     925           5 :                         if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
     926             :                                 phar_entry_info *etemp;
     927             : 
     928           5 :                                 entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
     929           5 :                                 if (entry[0] == '/') {
     930           6 :                                         if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
     931             :                                                 /* this file is not in the current directory, use the original path */
     932             : found_it:
     933           4 :                                                 efree(entry);
     934           4 :                                                 efree(arch);
     935           4 :                                                 RETURN_BOOL(!etemp->is_dir);
     936             :                                         }
     937             :                                 } else {
     938           4 :                                         if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) {
     939           1 :                                                 goto found_it;
     940             :                                         }
     941             :                                 }
     942             :                         }
     943           1 :                         if (entry != filename) {
     944           1 :                                 efree(entry);
     945             :                         }
     946           1 :                         efree(arch);
     947           1 :                         RETURN_FALSE;
     948             :                 }
     949             :         }
     950             : skip_phar:
     951        1288 :         PHAR_G(orig_is_file)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     952        1288 :         return;
     953             : }
     954             : /* }}} */
     955             : 
     956          63 : PHAR_FUNC(phar_is_link) /* {{{ */
     957             : {
     958             :         char *filename;
     959             :         size_t filename_len;
     960             : 
     961          63 :         if (!PHAR_G(intercepted)) {
     962          56 :                 goto skip_phar;
     963             :         }
     964             : 
     965           8 :         if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     966           1 :                 && !cached_phars.arHash) {
     967           1 :                 goto skip_phar;
     968             :         }
     969           6 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
     970           1 :                 goto skip_phar;
     971             :         }
     972           5 :         if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
     973             :                 char *arch, *entry, *fname;
     974             :                 int arch_len, entry_len, fname_len;
     975           5 :                 fname = (char*)zend_get_executed_filename(TSRMLS_C);
     976             : 
     977             :                 /* we are checking for existence of a file within the relative path.  Chances are good that this is
     978             :                    retrieving something from within the phar archive */
     979             : 
     980           5 :                 if (strncasecmp(fname, "phar://", 7)) {
     981           0 :                         goto skip_phar;
     982             :                 }
     983           5 :                 fname_len = strlen(fname);
     984           5 :                 if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
     985             :                         phar_archive_data *phar;
     986             : 
     987           5 :                         efree(entry);
     988           5 :                         entry = filename;
     989             :                         /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
     990           5 :                         entry_len = filename_len;
     991             :                         /* retrieving a file within the current directory, so use this if possible */
     992           5 :                         if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
     993             :                                 phar_entry_info *etemp;
     994             : 
     995           5 :                                 entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
     996           5 :                                 if (entry[0] == '/') {
     997           4 :                                         if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry + 1, entry_len - 1))) {
     998             :                                                 /* this file is not in the current directory, use the original path */
     999             : found_it:
    1000           3 :                                                 efree(entry);
    1001           3 :                                                 efree(arch);
    1002           3 :                                                 RETURN_BOOL(etemp->link);
    1003             :                                         }
    1004             :                                 } else {
    1005           6 :                                         if (NULL != (etemp = zend_hash_str_find_ptr(&(phar->manifest), entry, entry_len))) {
    1006           1 :                                                 goto found_it;
    1007             :                                         }
    1008             :                                 }
    1009             :                         }
    1010           2 :                         efree(entry);
    1011           2 :                         efree(arch);
    1012           2 :                         RETURN_FALSE;
    1013             :                 }
    1014             :         }
    1015             : skip_phar:
    1016          58 :         PHAR_G(orig_is_link)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1017          58 :         return;
    1018             : }
    1019             : /* }}} */
    1020             : 
    1021             : /* {{{ proto array lstat(string filename)
    1022             :    Give information about a file or symbolic link */
    1023          46 : PharFileFunction(phar_lstat, FS_LSTAT, orig_lstat)
    1024             : /* }}} */
    1025             : 
    1026             : /* {{{ proto array stat(string filename)
    1027             :    Give information about a file */
    1028         128 : PharFileFunction(phar_stat, FS_STAT, orig_stat)
    1029             : /* }}} */
    1030             : 
    1031             : /* {{{ void phar_intercept_functions(TSRMLS_D) */
    1032          15 : void phar_intercept_functions(TSRMLS_D)
    1033             : {
    1034          15 :         if (!PHAR_G(request_init)) {
    1035          10 :                 PHAR_G(cwd) = NULL;
    1036          10 :                 PHAR_G(cwd_len) = 0;
    1037             :         }
    1038          15 :         PHAR_G(intercepted) = 1;
    1039          15 : }
    1040             : /* }}} */
    1041             : 
    1042             : /* {{{ void phar_release_functions(TSRMLS_D) */
    1043         553 : void phar_release_functions(TSRMLS_D)
    1044             : {
    1045         553 :         PHAR_G(intercepted) = 0;
    1046         553 : }
    1047             : /* }}} */
    1048             : 
    1049             : /* {{{ void phar_intercept_functions_init(TSRMLS_D) */
    1050             : #define PHAR_INTERCEPT(func) \
    1051             :         PHAR_G(orig_##func) = NULL; \
    1052             :         if (NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \
    1053             :                 PHAR_G(orig_##func) = orig->internal_function.handler; \
    1054             :                 orig->internal_function.handler = phar_##func; \
    1055             :         }
    1056             : 
    1057       20423 : void phar_intercept_functions_init(TSRMLS_D)
    1058             : {
    1059             :         zend_function *orig;
    1060             : 
    1061       40846 :         PHAR_INTERCEPT(fopen);
    1062       40846 :         PHAR_INTERCEPT(file_get_contents);
    1063       40846 :         PHAR_INTERCEPT(is_file);
    1064       40846 :         PHAR_INTERCEPT(is_link);
    1065       40846 :         PHAR_INTERCEPT(is_dir);
    1066       40846 :         PHAR_INTERCEPT(opendir);
    1067       40846 :         PHAR_INTERCEPT(file_exists);
    1068       40846 :         PHAR_INTERCEPT(fileperms);
    1069       40846 :         PHAR_INTERCEPT(fileinode);
    1070       40846 :         PHAR_INTERCEPT(filesize);
    1071       40846 :         PHAR_INTERCEPT(fileowner);
    1072       40846 :         PHAR_INTERCEPT(filegroup);
    1073       40846 :         PHAR_INTERCEPT(fileatime);
    1074       40846 :         PHAR_INTERCEPT(filemtime);
    1075       40846 :         PHAR_INTERCEPT(filectime);
    1076       40846 :         PHAR_INTERCEPT(filetype);
    1077       40846 :         PHAR_INTERCEPT(is_writable);
    1078       40846 :         PHAR_INTERCEPT(is_readable);
    1079       40846 :         PHAR_INTERCEPT(is_executable);
    1080       40846 :         PHAR_INTERCEPT(lstat);
    1081       40846 :         PHAR_INTERCEPT(stat);
    1082       40846 :         PHAR_INTERCEPT(readfile);
    1083       20423 :         PHAR_G(intercepted) = 0;
    1084       20423 : }
    1085             : /* }}} */
    1086             : 
    1087             : /* {{{ void phar_intercept_functions_shutdown(TSRMLS_D) */
    1088             : #define PHAR_RELEASE(func) \
    1089             :         if (PHAR_G(orig_##func) && NULL != (orig = zend_hash_str_find_ptr(CG(function_table), #func, sizeof(#func)-1))) { \
    1090             :                 orig->internal_function.handler = PHAR_G(orig_##func); \
    1091             :         } \
    1092             :         PHAR_G(orig_##func) = NULL;
    1093             : 
    1094       20457 : void phar_intercept_functions_shutdown(TSRMLS_D)
    1095             : {
    1096             :         zend_function *orig;
    1097             : 
    1098       40914 :         PHAR_RELEASE(fopen);
    1099       40914 :         PHAR_RELEASE(file_get_contents);
    1100       40914 :         PHAR_RELEASE(is_file);
    1101       40914 :         PHAR_RELEASE(is_dir);
    1102       40914 :         PHAR_RELEASE(opendir);
    1103       40914 :         PHAR_RELEASE(file_exists);
    1104       40914 :         PHAR_RELEASE(fileperms);
    1105       40914 :         PHAR_RELEASE(fileinode);
    1106       40914 :         PHAR_RELEASE(filesize);
    1107       40914 :         PHAR_RELEASE(fileowner);
    1108       40914 :         PHAR_RELEASE(filegroup);
    1109       40914 :         PHAR_RELEASE(fileatime);
    1110       40914 :         PHAR_RELEASE(filemtime);
    1111       40914 :         PHAR_RELEASE(filectime);
    1112       40914 :         PHAR_RELEASE(filetype);
    1113       40914 :         PHAR_RELEASE(is_writable);
    1114       40914 :         PHAR_RELEASE(is_readable);
    1115       40914 :         PHAR_RELEASE(is_executable);
    1116       40914 :         PHAR_RELEASE(lstat);
    1117       40914 :         PHAR_RELEASE(stat);
    1118       40914 :         PHAR_RELEASE(readfile);
    1119       20457 :         PHAR_G(intercepted) = 0;
    1120       20457 : }
    1121             : /* }}} */
    1122             : 
    1123             : static struct _phar_orig_functions {
    1124             :         void        (*orig_fopen)(INTERNAL_FUNCTION_PARAMETERS);
    1125             :         void        (*orig_file_get_contents)(INTERNAL_FUNCTION_PARAMETERS);
    1126             :         void        (*orig_is_file)(INTERNAL_FUNCTION_PARAMETERS);
    1127             :         void        (*orig_is_link)(INTERNAL_FUNCTION_PARAMETERS);
    1128             :         void        (*orig_is_dir)(INTERNAL_FUNCTION_PARAMETERS);
    1129             :         void        (*orig_opendir)(INTERNAL_FUNCTION_PARAMETERS);
    1130             :         void        (*orig_file_exists)(INTERNAL_FUNCTION_PARAMETERS);
    1131             :         void        (*orig_fileperms)(INTERNAL_FUNCTION_PARAMETERS);
    1132             :         void        (*orig_fileinode)(INTERNAL_FUNCTION_PARAMETERS);
    1133             :         void        (*orig_filesize)(INTERNAL_FUNCTION_PARAMETERS);
    1134             :         void        (*orig_fileowner)(INTERNAL_FUNCTION_PARAMETERS);
    1135             :         void        (*orig_filegroup)(INTERNAL_FUNCTION_PARAMETERS);
    1136             :         void        (*orig_fileatime)(INTERNAL_FUNCTION_PARAMETERS);
    1137             :         void        (*orig_filemtime)(INTERNAL_FUNCTION_PARAMETERS);
    1138             :         void        (*orig_filectime)(INTERNAL_FUNCTION_PARAMETERS);
    1139             :         void        (*orig_filetype)(INTERNAL_FUNCTION_PARAMETERS);
    1140             :         void        (*orig_is_writable)(INTERNAL_FUNCTION_PARAMETERS);
    1141             :         void        (*orig_is_readable)(INTERNAL_FUNCTION_PARAMETERS);
    1142             :         void        (*orig_is_executable)(INTERNAL_FUNCTION_PARAMETERS);
    1143             :         void        (*orig_lstat)(INTERNAL_FUNCTION_PARAMETERS);
    1144             :         void        (*orig_readfile)(INTERNAL_FUNCTION_PARAMETERS);
    1145             :         void        (*orig_stat)(INTERNAL_FUNCTION_PARAMETERS);
    1146             : } phar_orig_functions = {NULL};
    1147             : 
    1148       20423 : void phar_save_orig_functions(TSRMLS_D) /* {{{ */
    1149             : {
    1150       20423 :         phar_orig_functions.orig_fopen             = PHAR_G(orig_fopen);
    1151       20423 :         phar_orig_functions.orig_file_get_contents = PHAR_G(orig_file_get_contents);
    1152       20423 :         phar_orig_functions.orig_is_file           = PHAR_G(orig_is_file);
    1153       20423 :         phar_orig_functions.orig_is_link           = PHAR_G(orig_is_link);
    1154       20423 :         phar_orig_functions.orig_is_dir            = PHAR_G(orig_is_dir);
    1155       20423 :         phar_orig_functions.orig_opendir           = PHAR_G(orig_opendir);
    1156       20423 :         phar_orig_functions.orig_file_exists       = PHAR_G(orig_file_exists);
    1157       20423 :         phar_orig_functions.orig_fileperms         = PHAR_G(orig_fileperms);
    1158       20423 :         phar_orig_functions.orig_fileinode         = PHAR_G(orig_fileinode);
    1159       20423 :         phar_orig_functions.orig_filesize          = PHAR_G(orig_filesize);
    1160       20423 :         phar_orig_functions.orig_fileowner         = PHAR_G(orig_fileowner);
    1161       20423 :         phar_orig_functions.orig_filegroup         = PHAR_G(orig_filegroup);
    1162       20423 :         phar_orig_functions.orig_fileatime         = PHAR_G(orig_fileatime);
    1163       20423 :         phar_orig_functions.orig_filemtime         = PHAR_G(orig_filemtime);
    1164       20423 :         phar_orig_functions.orig_filectime         = PHAR_G(orig_filectime);
    1165       20423 :         phar_orig_functions.orig_filetype          = PHAR_G(orig_filetype);
    1166       20423 :         phar_orig_functions.orig_is_writable       = PHAR_G(orig_is_writable);
    1167       20423 :         phar_orig_functions.orig_is_readable       = PHAR_G(orig_is_readable);
    1168       20423 :         phar_orig_functions.orig_is_executable     = PHAR_G(orig_is_executable);
    1169       20423 :         phar_orig_functions.orig_lstat             = PHAR_G(orig_lstat);
    1170       20423 :         phar_orig_functions.orig_readfile          = PHAR_G(orig_readfile);
    1171       20423 :         phar_orig_functions.orig_stat              = PHAR_G(orig_stat);
    1172       20423 : }
    1173             : /* }}} */
    1174             : 
    1175       20423 : void phar_restore_orig_functions(TSRMLS_D) /* {{{ */
    1176             : {
    1177       20423 :         PHAR_G(orig_fopen)             = phar_orig_functions.orig_fopen;
    1178       20423 :         PHAR_G(orig_file_get_contents) = phar_orig_functions.orig_file_get_contents;
    1179       20423 :         PHAR_G(orig_is_file)           = phar_orig_functions.orig_is_file;
    1180       20423 :         PHAR_G(orig_is_link)           = phar_orig_functions.orig_is_link;
    1181       20423 :         PHAR_G(orig_is_dir)            = phar_orig_functions.orig_is_dir;
    1182       20423 :         PHAR_G(orig_opendir)           = phar_orig_functions.orig_opendir;
    1183       20423 :         PHAR_G(orig_file_exists)       = phar_orig_functions.orig_file_exists;
    1184       20423 :         PHAR_G(orig_fileperms)         = phar_orig_functions.orig_fileperms;
    1185       20423 :         PHAR_G(orig_fileinode)         = phar_orig_functions.orig_fileinode;
    1186       20423 :         PHAR_G(orig_filesize)          = phar_orig_functions.orig_filesize;
    1187       20423 :         PHAR_G(orig_fileowner)         = phar_orig_functions.orig_fileowner;
    1188       20423 :         PHAR_G(orig_filegroup)         = phar_orig_functions.orig_filegroup;
    1189       20423 :         PHAR_G(orig_fileatime)         = phar_orig_functions.orig_fileatime;
    1190       20423 :         PHAR_G(orig_filemtime)         = phar_orig_functions.orig_filemtime;
    1191       20423 :         PHAR_G(orig_filectime)         = phar_orig_functions.orig_filectime;
    1192       20423 :         PHAR_G(orig_filetype)          = phar_orig_functions.orig_filetype;
    1193       20423 :         PHAR_G(orig_is_writable)       = phar_orig_functions.orig_is_writable;
    1194       20423 :         PHAR_G(orig_is_readable)       = phar_orig_functions.orig_is_readable;
    1195       20423 :         PHAR_G(orig_is_executable)     = phar_orig_functions.orig_is_executable;
    1196       20423 :         PHAR_G(orig_lstat)             = phar_orig_functions.orig_lstat;
    1197       20423 :         PHAR_G(orig_readfile)          = phar_orig_functions.orig_readfile;
    1198       20423 :         PHAR_G(orig_stat)              = phar_orig_functions.orig_stat;
    1199       20423 : }
    1200             : /* }}} */
    1201             : 
    1202             : /*
    1203             :  * Local variables:
    1204             :  * tab-width: 4
    1205             :  * c-basic-offset: 4
    1206             :  * End:
    1207             :  * vim600: noet sw=4 ts=4 fdm=marker
    1208             :  * vim<600: noet sw=4 ts=4
    1209             :  */
    1210             : 

Generated by: LCOV version 1.10

Generated at Thu, 30 Oct 2014 07:41:37 +0000 (29 hours ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.