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

LTP GCOV extension - code coverage report
Current view: directory - phar - func_interceptors.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 611
Code covered: 88.9 % Executed lines: 543
Legend: not executed executed

       1                 : /*
       2                 :   +----------------------------------------------------------------------+
       3                 :   | phar php single-file executable PHP extension                        |
       4                 :   +----------------------------------------------------------------------+
       5                 :   | Copyright (c) 2005-2009 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: func_interceptors.c 280454 2009-05-13 15:55:12Z kalle $ */
      20                 : 
      21                 : #include "phar_internal.h"
      22                 : 
      23                 : #define PHAR_FUNC(name) \
      24                 :         static PHP_NAMED_FUNCTION(name)
      25                 : 
      26                 : PHAR_FUNC(phar_opendir) /* {{{ */
      27            3099 : {
      28                 :         char *filename;
      29                 :         int filename_len;
      30            3099 :         zval *zcontext = NULL;
      31                 : 
      32            3099 :         if (!PHAR_G(intercepted)) {
      33            3091 :                 goto skip_phar;
      34                 :         }
      35                 : 
      36               8 :         if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
      37                 :                 && !cached_phars.arBuckets) {
      38               1 :                 goto skip_phar;
      39                 :         }
      40                 : 
      41               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|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 = 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            3095 : skip_phar:
      89            3095 :         PHAR_G(orig_opendir)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
      90            3095 :         return;
      91                 : }
      92                 : /* }}} */
      93                 : 
      94                 : PHAR_FUNC(phar_file_get_contents) /* {{{ */
      95            2311 : {
      96                 :         char *filename;
      97                 :         int filename_len;
      98                 :         char *contents;
      99            2311 :         zend_bool use_include_path = 0;
     100                 :         php_stream *stream;
     101                 :         int len;
     102            2311 :         long offset = -1;
     103            2311 :         long maxlen = PHP_STREAM_COPY_ALL;
     104            2311 :         zval *zcontext = NULL;
     105                 : 
     106            2311 :         if (!PHAR_G(intercepted)) {
     107            2296 :                 goto skip_phar;
     108                 :         }
     109                 : 
     110              15 :         if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     111                 :                 && !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, "s|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 = 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               1 : 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              10 : 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_MAJOR_VERSION < 6
     207               7 :                                 if (PG(magic_quotes_runtime)) {
     208                 :                                         int newlen;
     209               1 :                                         contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free source string */
     210               1 :                                         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            2300 : skip_phar:
     225            2300 :         PHAR_G(orig_file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     226            2300 :         return;
     227                 : }
     228                 : /* }}} */
     229                 : 
     230                 : PHAR_FUNC(phar_readfile) /* {{{ */
     231             466 : {
     232                 :         char *filename;
     233                 :         int filename_len;
     234             466 :         int size = 0;
     235             466 :         zend_bool use_include_path = 0;
     236             466 :         zval *zcontext = NULL;
     237                 :         php_stream *stream;
     238                 : 
     239             466 :         if (!PHAR_G(intercepted)) {
     240             456 :                 goto skip_phar;
     241                 :         }
     242                 : 
     243              10 :         if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     244                 :                 && !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, "s|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 = 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               1 : 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             460 : skip_phar:
     320             460 :         PHAR_G(orig_readfile)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     321             460 :         return;
     322                 : 
     323                 : }
     324                 : /* }}} */
     325                 : 
     326                 : PHAR_FUNC(phar_fopen) /* {{{ */
     327           22117 : {
     328                 :         char *filename, *mode;
     329                 :         int filename_len, mode_len;
     330           22117 :         zend_bool use_include_path = 0;
     331           22117 :         zval *zcontext = NULL;
     332                 :         php_stream *stream;
     333                 : 
     334           22117 :         if (!PHAR_G(intercepted)) {
     335           22106 :                 goto skip_phar;
     336                 :         }
     337                 : 
     338              11 :         if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     339                 :                 && !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, "ss|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 = 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               1 : 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           22113 : skip_phar:
     418           22113 :         PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     419           22112 :         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                 : static void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value TSRMLS_DC)
     443              19 : {
     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                 : 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              27 : {
     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 = 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              22 : 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               2 : 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 Occured */
     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              19 : 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              19 : 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               4 : 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, "s", &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            6786 : 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           12072 : PharFileFunction(phar_filesize, FS_SIZE, orig_filesize)
     838                 : /* }}} */
     839                 : 
     840                 : /* {{{ proto int fileowner(string filename)
     841                 :    Get file owner */
     842              81 : PharFileFunction(phar_fileowner, FS_OWNER, orig_fileowner)
     843                 : /* }}} */
     844                 : 
     845                 : /* {{{ proto int filegroup(string filename)
     846                 :    Get file group */
     847              52 : 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             569 : 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             695 : 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             614 : 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            3249 : 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           59005 : PharFileFunction(phar_is_dir, FS_IS_DIR, orig_is_dir)
     893                 : /* }}} */
     894                 : 
     895                 : PHAR_FUNC(phar_is_file) /* {{{ */
     896             972 : {
     897                 :         char *filename;
     898                 :         int filename_len;
     899                 : 
     900             972 :         if (!PHAR_G(intercepted)) {
     901             964 :                 goto skip_phar;
     902                 :         }
     903                 : 
     904               8 :         if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     905                 :                 && !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, "s", &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 = 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               4 : 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             967 : skip_phar:
     957             967 :         PHAR_G(orig_is_file)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
     958             967 :         return;
     959                 : }
     960                 : /* }}} */
     961                 : 
     962                 : PHAR_FUNC(phar_is_link) /* {{{ */
     963              72 : {
     964                 :         char *filename;
     965                 :         int filename_len;
     966                 : 
     967              72 :         if (!PHAR_G(intercepted)) {
     968              65 :                 goto skip_phar;
     969                 :         }
     970                 : 
     971               7 :         if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
     972                 :                 && !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, "s", &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 = 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               3 : 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              67 : skip_phar:
    1022              67 :         PHAR_G(orig_is_link)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1023              67 :         return;
    1024                 : }
    1025                 : /* }}} */
    1026                 : 
    1027                 : /* {{{ proto array lstat(string filename)
    1028                 :    Give information about a file or symbolic link */
    1029              47 : PharFileFunction(phar_lstat, FS_LSTAT, orig_lstat)
    1030                 : /* }}} */
    1031                 : 
    1032                 : /* {{{ proto array stat(string filename)
    1033                 :    Give information about a file */
    1034             126 : PharFileFunction(phar_stat, FS_STAT, orig_stat)
    1035                 : /* }}} */
    1036                 : 
    1037                 : /* {{{ void phar_intercept_functions(TSRMLS_D) */
    1038                 : void phar_intercept_functions(TSRMLS_D)
    1039              17 : {
    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                 : void phar_release_functions(TSRMLS_D)
    1050             552 : {
    1051             552 :         PHAR_G(intercepted) = 0;
    1052             552 : }
    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                 : void phar_intercept_functions_init(TSRMLS_D)
    1064           17633 : {
    1065                 :         zend_function *orig;
    1066                 : 
    1067           17633 :         PHAR_INTERCEPT(fopen);
    1068           17633 :         PHAR_INTERCEPT(file_get_contents);
    1069           17633 :         PHAR_INTERCEPT(is_file);
    1070           17633 :         PHAR_INTERCEPT(is_link);
    1071           17633 :         PHAR_INTERCEPT(is_dir);
    1072           17633 :         PHAR_INTERCEPT(opendir);
    1073           17633 :         PHAR_INTERCEPT(file_exists);
    1074           17633 :         PHAR_INTERCEPT(fileperms);
    1075           17633 :         PHAR_INTERCEPT(fileinode);
    1076           17633 :         PHAR_INTERCEPT(filesize);
    1077           17633 :         PHAR_INTERCEPT(fileowner);
    1078           17633 :         PHAR_INTERCEPT(filegroup);
    1079           17633 :         PHAR_INTERCEPT(fileatime);
    1080           17633 :         PHAR_INTERCEPT(filemtime);
    1081           17633 :         PHAR_INTERCEPT(filectime);
    1082           17633 :         PHAR_INTERCEPT(filetype);
    1083           17633 :         PHAR_INTERCEPT(is_writable);
    1084           17633 :         PHAR_INTERCEPT(is_readable);
    1085           17633 :         PHAR_INTERCEPT(is_executable);
    1086           17633 :         PHAR_INTERCEPT(lstat);
    1087           17633 :         PHAR_INTERCEPT(stat);
    1088           17633 :         PHAR_INTERCEPT(readfile);
    1089           17633 :         PHAR_G(intercepted) = 0;
    1090           17633 : }
    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                 : void phar_intercept_functions_shutdown(TSRMLS_D)
    1101           17665 : {
    1102                 :         zend_function *orig;
    1103                 : 
    1104           17665 :         PHAR_RELEASE(fopen);
    1105           17665 :         PHAR_RELEASE(file_get_contents);
    1106           17665 :         PHAR_RELEASE(is_file);
    1107           17665 :         PHAR_RELEASE(is_dir);
    1108           17665 :         PHAR_RELEASE(opendir);
    1109           17665 :         PHAR_RELEASE(file_exists);
    1110           17665 :         PHAR_RELEASE(fileperms);
    1111           17665 :         PHAR_RELEASE(fileinode);
    1112           17665 :         PHAR_RELEASE(filesize);
    1113           17665 :         PHAR_RELEASE(fileowner);
    1114           17665 :         PHAR_RELEASE(filegroup);
    1115           17665 :         PHAR_RELEASE(fileatime);
    1116           17665 :         PHAR_RELEASE(filemtime);
    1117           17665 :         PHAR_RELEASE(filectime);
    1118           17665 :         PHAR_RELEASE(filetype);
    1119           17665 :         PHAR_RELEASE(is_writable);
    1120           17665 :         PHAR_RELEASE(is_readable);
    1121           17665 :         PHAR_RELEASE(is_executable);
    1122           17665 :         PHAR_RELEASE(lstat);
    1123           17665 :         PHAR_RELEASE(stat);
    1124           17665 :         PHAR_RELEASE(readfile);
    1125           17665 :         PHAR_G(intercepted) = 0;
    1126           17665 : }
    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                 : void phar_save_orig_functions(TSRMLS_D) /* {{{ */
    1155           17633 : {
    1156           17633 :         phar_orig_functions.orig_fopen             = PHAR_G(orig_fopen);
    1157           17633 :         phar_orig_functions.orig_file_get_contents = PHAR_G(orig_file_get_contents);
    1158           17633 :         phar_orig_functions.orig_is_file           = PHAR_G(orig_is_file);
    1159           17633 :         phar_orig_functions.orig_is_link           = PHAR_G(orig_is_link);
    1160           17633 :         phar_orig_functions.orig_is_dir            = PHAR_G(orig_is_dir);
    1161           17633 :         phar_orig_functions.orig_opendir           = PHAR_G(orig_opendir);
    1162           17633 :         phar_orig_functions.orig_file_exists       = PHAR_G(orig_file_exists);
    1163           17633 :         phar_orig_functions.orig_fileperms         = PHAR_G(orig_fileperms);
    1164           17633 :         phar_orig_functions.orig_fileinode         = PHAR_G(orig_fileinode);
    1165           17633 :         phar_orig_functions.orig_filesize          = PHAR_G(orig_filesize);
    1166           17633 :         phar_orig_functions.orig_fileowner         = PHAR_G(orig_fileowner);
    1167           17633 :         phar_orig_functions.orig_filegroup         = PHAR_G(orig_filegroup);
    1168           17633 :         phar_orig_functions.orig_fileatime         = PHAR_G(orig_fileatime);
    1169           17633 :         phar_orig_functions.orig_filemtime         = PHAR_G(orig_filemtime);
    1170           17633 :         phar_orig_functions.orig_filectime         = PHAR_G(orig_filectime);
    1171           17633 :         phar_orig_functions.orig_filetype          = PHAR_G(orig_filetype);
    1172           17633 :         phar_orig_functions.orig_is_writable       = PHAR_G(orig_is_writable);
    1173           17633 :         phar_orig_functions.orig_is_readable       = PHAR_G(orig_is_readable);
    1174           17633 :         phar_orig_functions.orig_is_executable     = PHAR_G(orig_is_executable);
    1175           17633 :         phar_orig_functions.orig_lstat             = PHAR_G(orig_lstat);
    1176           17633 :         phar_orig_functions.orig_readfile          = PHAR_G(orig_readfile);
    1177           17633 :         phar_orig_functions.orig_stat              = PHAR_G(orig_stat);
    1178           17633 : }
    1179                 : /* }}} */
    1180                 : 
    1181                 : void phar_restore_orig_functions(TSRMLS_D) /* {{{ */
    1182           17633 : {
    1183           17633 :         PHAR_G(orig_fopen)             = phar_orig_functions.orig_fopen;
    1184           17633 :         PHAR_G(orig_file_get_contents) = phar_orig_functions.orig_file_get_contents;
    1185           17633 :         PHAR_G(orig_is_file)           = phar_orig_functions.orig_is_file;
    1186           17633 :         PHAR_G(orig_is_link)           = phar_orig_functions.orig_is_link;
    1187           17633 :         PHAR_G(orig_is_dir)            = phar_orig_functions.orig_is_dir;
    1188           17633 :         PHAR_G(orig_opendir)           = phar_orig_functions.orig_opendir;
    1189           17633 :         PHAR_G(orig_file_exists)       = phar_orig_functions.orig_file_exists;
    1190           17633 :         PHAR_G(orig_fileperms)         = phar_orig_functions.orig_fileperms;
    1191           17633 :         PHAR_G(orig_fileinode)         = phar_orig_functions.orig_fileinode;
    1192           17633 :         PHAR_G(orig_filesize)          = phar_orig_functions.orig_filesize;
    1193           17633 :         PHAR_G(orig_fileowner)         = phar_orig_functions.orig_fileowner;
    1194           17633 :         PHAR_G(orig_filegroup)         = phar_orig_functions.orig_filegroup;
    1195           17633 :         PHAR_G(orig_fileatime)         = phar_orig_functions.orig_fileatime;
    1196           17633 :         PHAR_G(orig_filemtime)         = phar_orig_functions.orig_filemtime;
    1197           17633 :         PHAR_G(orig_filectime)         = phar_orig_functions.orig_filectime;
    1198           17633 :         PHAR_G(orig_filetype)          = phar_orig_functions.orig_filetype;
    1199           17633 :         PHAR_G(orig_is_writable)       = phar_orig_functions.orig_is_writable;
    1200           17633 :         PHAR_G(orig_is_readable)       = phar_orig_functions.orig_is_readable;
    1201           17633 :         PHAR_G(orig_is_executable)     = phar_orig_functions.orig_is_executable;
    1202           17633 :         PHAR_G(orig_lstat)             = phar_orig_functions.orig_lstat;
    1203           17633 :         PHAR_G(orig_readfile)          = phar_orig_functions.orig_readfile;
    1204           17633 :         PHAR_G(orig_stat)              = phar_orig_functions.orig_stat;
    1205           17633 : }
    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: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:06 +0000 (3 days ago)

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