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

Generated by: LCOV version 1.10

Generated at Fri, 24 Oct 2014 05:21:53 +0000 (15 hours ago)

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