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 - var/php_gcov/PHP_5_3/main - fopen_wrappers.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 346
Code covered: 68.8 % Executed lines: 238
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-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: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
      16                 :    |          Jim Winstead <jimw@php.net>                                 |
      17                 :    +----------------------------------------------------------------------+
      18                 :  */
      19                 : 
      20                 : /* $Id: fopen_wrappers.c 288246 2009-09-10 16:19:42Z jani $ */
      21                 : 
      22                 : /* {{{ includes
      23                 :  */
      24                 : #include "php.h"
      25                 : #include "php_globals.h"
      26                 : #include "SAPI.h"
      27                 : 
      28                 : #include <stdio.h>
      29                 : #include <stdlib.h>
      30                 : #include <errno.h>
      31                 : #include <sys/types.h>
      32                 : #include <sys/stat.h>
      33                 : #include <fcntl.h>
      34                 : 
      35                 : #ifdef PHP_WIN32
      36                 : #define O_RDONLY _O_RDONLY
      37                 : #include "win32/param.h"
      38                 : #else
      39                 : #include <sys/param.h>
      40                 : #endif
      41                 : 
      42                 : #include "safe_mode.h"
      43                 : #include "ext/standard/head.h"
      44                 : #include "ext/standard/php_standard.h"
      45                 : #include "zend_compile.h"
      46                 : #include "php_network.h"
      47                 : 
      48                 : #if HAVE_PWD_H
      49                 : #include <pwd.h>
      50                 : #endif
      51                 : 
      52                 : #include <sys/types.h>
      53                 : #if HAVE_SYS_SOCKET_H
      54                 : #include <sys/socket.h>
      55                 : #endif
      56                 : 
      57                 : #ifndef S_ISREG
      58                 : #define S_ISREG(mode)   (((mode) & S_IFMT) == S_IFREG)
      59                 : #endif
      60                 : 
      61                 : #ifdef PHP_WIN32
      62                 : #include <winsock2.h>
      63                 : #elif defined(NETWARE) && defined(USE_WINSOCK)
      64                 : #include <novsock2.h>
      65                 : #else
      66                 : #include <netinet/in.h>
      67                 : #include <netdb.h>
      68                 : #if HAVE_ARPA_INET_H
      69                 : #include <arpa/inet.h>
      70                 : #endif
      71                 : #endif
      72                 : 
      73                 : #if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
      74                 : #undef AF_UNIX
      75                 : #endif
      76                 : 
      77                 : #if defined(AF_UNIX)
      78                 : #include <sys/un.h>
      79                 : #endif
      80                 : /* }}} */
      81                 : 
      82                 : /* {{{ OnUpdateBaseDir
      83                 : Allows any change to open_basedir setting in during Startup and Shutdown events,
      84                 : or a tightening during activation/runtime/deactivation */
      85                 : PHPAPI ZEND_INI_MH(OnUpdateBaseDir)
      86           17636 : {
      87                 :         char **p, *pathbuf, *ptr, *end;
      88                 : #ifndef ZTS
      89           17636 :         char *base = (char *) mh_arg2;
      90                 : #else
      91                 :         char *base = (char *) ts_resource(*((int *) mh_arg2));
      92                 : #endif
      93                 : 
      94           17636 :         p = (char **) (base + (size_t) mh_arg1);
      95                 : 
      96           17636 :         if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) {
      97                 :                 /* We're in a PHP_INI_SYSTEM context, no restrictions */
      98           17634 :                 *p = new_value;
      99           17634 :                 return SUCCESS;
     100                 :         }
     101                 : 
     102                 :         /* Otherwise we're in runtime */
     103               2 :         if (!*p || !**p) {
     104                 :                 /* open_basedir not set yet, go ahead and give it a value */
     105               0 :                 *p = new_value;
     106               0 :                 return SUCCESS;
     107                 :         }
     108                 : 
     109                 :         /* Shortcut: When we have a open_basedir and someone tries to unset, we know it'll fail */
     110               2 :         if (!new_value || !*new_value) {
     111               0 :                 return FAILURE;
     112                 :         }
     113                 : 
     114                 :         /* Is the proposed open_basedir at least as restrictive as the current setting? */
     115               2 :         ptr = pathbuf = estrdup(new_value);
     116               5 :         while (ptr && *ptr) {
     117               2 :                 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
     118               2 :                 if (end != NULL) {
     119               0 :                         *end = '\0';
     120               0 :                         end++;
     121                 :                 }
     122               2 :                 if (php_check_open_basedir_ex(ptr, 0 TSRMLS_CC) != 0) {
     123                 :                         /* At least one portion of this open_basedir is less restrictive than the prior one, FAIL */
     124               1 :                         efree(pathbuf);
     125               1 :                         return FAILURE;
     126                 :                 }
     127               1 :                 ptr = end;
     128                 :         }
     129               1 :         efree(pathbuf);
     130                 : 
     131                 :         /* Everything checks out, set it */
     132               1 :         *p = new_value;
     133                 : 
     134               1 :         return SUCCESS;
     135                 : }
     136                 : /* }}} */
     137                 : 
     138                 : /* {{{ php_check_specific_open_basedir
     139                 :         When open_basedir is not NULL, check if the given filename is located in
     140                 :         open_basedir. Returns -1 if error or not in the open_basedir, else 0.
     141                 :         When open_basedir is NULL, always return 0.
     142                 : */
     143                 : PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path TSRMLS_DC)
     144            1058 : {
     145                 :         char resolved_name[MAXPATHLEN];
     146                 :         char resolved_basedir[MAXPATHLEN];
     147                 :         char local_open_basedir[MAXPATHLEN];
     148                 :         char path_tmp[MAXPATHLEN];
     149                 :         char *path_file;
     150                 :         int resolved_basedir_len;
     151                 :         int resolved_name_len;
     152                 :         int path_len;
     153            1058 :         int nesting_level = 0;
     154                 : 
     155                 :         /* Special case basedir==".": Use script-directory */
     156            1058 :         if (strcmp(basedir, ".") || !VCWD_GETCWD(local_open_basedir, MAXPATHLEN)) {
     157                 :                 /* Else use the unmodified path */
     158               4 :                 strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir));
     159                 :         }
     160                 : 
     161            1058 :         path_len = strlen(path);
     162            1058 :         if (path_len > (MAXPATHLEN - 1)) {
     163                 :                 /* empty and too long paths are invalid */
     164               0 :                 return -1;
     165                 :         }
     166                 : 
     167                 :         /* normalize and expand path */
     168            1058 :         if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
     169               1 :                 return -1;
     170                 :         }
     171                 : 
     172            1057 :         path_len = strlen(resolved_name);
     173            1057 :         memcpy(path_tmp, resolved_name, path_len + 1); /* safe */
     174                 : 
     175            2444 :         while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) {
     176                 : #ifdef HAVE_SYMLINK
     177             330 :                 if (nesting_level == 0) {
     178                 :                         int ret;
     179                 :                         char buf[MAXPATHLEN];
     180                 : 
     181             330 :                         ret = readlink(path_tmp, buf, MAXPATHLEN - 1);
     182             330 :                         if (ret < 0) {
     183                 :                                 /* not a broken symlink, move along.. */
     184                 :                         } else {
     185                 :                                 /* put the real path into the path buffer */
     186               0 :                                 memcpy(path_tmp, buf, ret);
     187               0 :                                 path_tmp[ret] = '\0';
     188                 :                         }
     189                 :                 }
     190                 : #endif
     191                 : 
     192                 : #if defined(PHP_WIN32) || defined(NETWARE)
     193                 :                 path_file = strrchr(path_tmp, DEFAULT_SLASH);
     194                 :                 if (!path_file) {
     195                 :                         path_file = strrchr(path_tmp, '/');
     196                 :                 }
     197                 : #else
     198             330 :                 path_file = strrchr(path_tmp, DEFAULT_SLASH);
     199                 : #endif
     200             330 :                 if (!path_file) {
     201                 :                         /* none of the path components exist. definitely not in open_basedir.. */
     202               0 :                         return -1;
     203                 :                 } else {
     204             330 :                         path_len = path_file - path_tmp + 1;
     205                 : #if defined(PHP_WIN32) || defined(NETWARE)
     206                 :                         if (path_len > 1 && path_tmp[path_len - 2] == ':') {
     207                 :                                 if (path_len != 3) {
     208                 :                                         return -1;
     209                 :                                 } 
     210                 :                                 /* this is c:\ */
     211                 :                                 path_tmp[path_len] = '\0';
     212                 :                         } else {
     213                 :                                 path_tmp[path_len - 1] = '\0';
     214                 :                         }
     215                 : #else
     216             330 :                         path_tmp[path_len - 1] = '\0';
     217                 : #endif
     218                 :                 }
     219             330 :                 nesting_level++;
     220                 :         }
     221                 : 
     222                 :         /* Resolve open_basedir to resolved_basedir */
     223            1057 :         if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) {
     224                 :                 /* Handler for basedirs that end with a / */
     225            1057 :                 resolved_basedir_len = strlen(resolved_basedir);
     226            1057 :                 if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) {
     227               1 :                         if (resolved_basedir[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) {
     228               0 :                                 resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR;
     229               0 :                                 resolved_basedir[++resolved_basedir_len] = '\0';
     230                 :                         }
     231                 :                 }
     232                 : 
     233            1057 :                 resolved_name_len = strlen(resolved_name);
     234            1057 :                 if (path_tmp[path_len - 1] == PHP_DIR_SEPARATOR) {
     235              68 :                         if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
     236              36 :                                 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
     237              36 :                                 resolved_name[++resolved_name_len] = '\0';
     238                 :                         }
     239                 :                 }
     240                 : 
     241                 :                 /* Check the path */
     242                 : #if defined(PHP_WIN32) || defined(NETWARE)
     243                 :                 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
     244                 : #else
     245            1057 :                 if (strncmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
     246                 : #endif
     247                 :                         /* File is in the right directory */
     248             728 :                         return 0;
     249                 :                 } else {
     250                 :                         /* /openbasedir/ and /openbasedir are the same directory */
     251             329 :                         if (resolved_basedir_len == (resolved_name_len + 1) && resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
     252                 : #if defined(PHP_WIN32) || defined(NETWARE)
     253                 :                                 if (strncasecmp(resolved_basedir, resolved_name, resolved_name_len) == 0) {
     254                 : #else
     255               0 :                                 if (strncmp(resolved_basedir, resolved_name, resolved_name_len) == 0) {
     256                 : #endif
     257               0 :                                         return 0;
     258                 :                                 }
     259                 :                         }
     260             329 :                         return -1;
     261                 :                 }
     262                 :         } else {
     263                 :                 /* Unable to resolve the real path, return -1 */
     264               0 :                 return -1;
     265                 :         }
     266                 : }
     267                 : /* }}} */
     268                 : 
     269                 : PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC)
     270          451717 : {
     271          451717 :         return php_check_open_basedir_ex(path, 1 TSRMLS_CC);
     272                 : }
     273                 : 
     274                 : /* {{{ php_check_open_basedir
     275                 :  */
     276                 : PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
     277          534909 : {
     278                 :         /* Only check when open_basedir is available */
     279          534909 :         if (PG(open_basedir) && *PG(open_basedir)) {
     280                 :                 char *pathbuf;
     281                 :                 char *ptr;
     282                 :                 char *end;
     283                 : 
     284            1058 :                 pathbuf = estrdup(PG(open_basedir));
     285                 : 
     286            1058 :                 ptr = pathbuf;
     287                 : 
     288            2446 :                 while (ptr && *ptr) {
     289            1058 :                         end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
     290            1058 :                         if (end != NULL) {
     291               0 :                                 *end = '\0';
     292               0 :                                 end++;
     293                 :                         }
     294                 : 
     295            1058 :                         if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) {
     296             728 :                                 efree(pathbuf);
     297             728 :                                 return 0;
     298                 :                         }
     299                 : 
     300             330 :                         ptr = end;
     301                 :                 }
     302             330 :                 if (warn) {
     303             311 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)", path, PG(open_basedir));
     304                 :                 }
     305             330 :                 efree(pathbuf);
     306             330 :                 errno = EPERM; /* we deny permission to open it */
     307             330 :                 return -1;
     308                 :         }
     309                 : 
     310                 :         /* Nothing to check... */
     311          533851 :         return 0;
     312                 : }
     313                 : /* }}} */
     314                 : 
     315                 : /* {{{ php_check_safe_mode_include_dir
     316                 :  */
     317                 : PHPAPI int php_check_safe_mode_include_dir(const char *path TSRMLS_DC)
     318           69493 : {
     319           69493 :         if (PG(safe_mode)) {
     320               2 :                 if (PG(safe_mode_include_dir) && *PG(safe_mode_include_dir)) {
     321                 :                         char *pathbuf;
     322                 :                         char *ptr;
     323                 :                         char *end;
     324                 :                         char resolved_name[MAXPATHLEN];
     325                 : 
     326                 :                         /* Resolve the real path into resolved_name */
     327               0 :                         if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
     328               0 :                                 return -1;
     329                 :                         }
     330               0 :                         pathbuf = estrdup(PG(safe_mode_include_dir));
     331               0 :                         ptr = pathbuf;
     332                 : 
     333               0 :                         while (ptr && *ptr) {
     334               0 :                                 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
     335               0 :                                 if (end != NULL) {
     336               0 :                                         *end = '\0';
     337               0 :                                         end++;
     338                 :                                 }
     339                 : 
     340                 :                                 /* Check the path */
     341                 : #ifdef PHP_WIN32
     342                 :                                 if (strncasecmp(ptr, resolved_name, strlen(ptr)) == 0)
     343                 : #else
     344               0 :                                 if (strncmp(ptr, resolved_name, strlen(ptr)) == 0)
     345                 : #endif
     346                 :                                 {
     347                 :                                         /* File is in the right directory */
     348               0 :                                         efree(pathbuf);
     349               0 :                                         return 0;
     350                 :                                 }
     351                 : 
     352               0 :                                 ptr = end;
     353                 :                         }
     354               0 :                         efree(pathbuf);
     355                 :                 }
     356               2 :                 return -1;
     357                 :         }
     358                 : 
     359                 :         /* Nothing to check... */
     360           69491 :         return 0;
     361                 : }
     362                 : /* }}} */
     363                 : 
     364                 : /* {{{ php_fopen_and_set_opened_path
     365                 :  */
     366                 : static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, char **opened_path TSRMLS_DC)
     367           70644 : {
     368                 :         FILE *fp;
     369                 : 
     370           70644 :         if (php_check_open_basedir((char *)path TSRMLS_CC)) {
     371               0 :                 return NULL;
     372                 :         }
     373           70644 :         fp = VCWD_FOPEN(path, mode);
     374           70644 :         if (fp && opened_path) {
     375           17519 :                 *opened_path = expand_filepath(path, NULL TSRMLS_CC);
     376                 :         }
     377           70644 :         return fp;
     378                 : }
     379                 : /* }}} */
     380                 : 
     381                 : /* {{{ php_fopen_primary_script
     382                 :  */
     383                 : PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC)
     384             315 : {
     385                 :         FILE *fp;
     386                 : #ifndef PHP_WIN32
     387                 :         struct stat st;
     388                 : #endif
     389                 :         char *path_info, *filename;
     390                 :         int length;
     391                 : 
     392             315 :         filename = SG(request_info).path_translated;
     393             315 :         path_info = SG(request_info).request_uri;
     394                 : #if HAVE_PWD_H
     395             315 :         if (PG(user_dir) && *PG(user_dir) && path_info && '/' == path_info[0] && '~' == path_info[1]) {
     396               0 :                 char *s = strchr(path_info + 2, '/');
     397                 : 
     398               0 :                 filename = NULL;        /* discard the original filename, it must not be used */
     399               0 :                 if (s) {                        /* if there is no path name after the file, do not bother */
     400                 :                         char user[32];                  /* to try open the directory */
     401                 :                         struct passwd *pw;
     402                 : #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
     403                 :                         struct passwd pwstruc;
     404                 :                         long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
     405                 :                         char *pwbuf;
     406                 : 
     407                 :                         if (pwbuflen < 1) {
     408                 :                                 return FAILURE;
     409                 :                         }
     410                 : 
     411                 :                         pwbuf = emalloc(pwbuflen);
     412                 : #endif
     413               0 :                         length = s - (path_info + 2);
     414               0 :                         if (length > (int)sizeof(user) - 1) {
     415               0 :                                 length = sizeof(user) - 1;
     416                 :                         }
     417               0 :                         memcpy(user, path_info + 2, length);
     418               0 :                         user[length] = '\0';
     419                 : #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
     420                 :                         if (getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw)) {
     421                 :                                 efree(pwbuf);
     422                 :                                 return FAILURE;
     423                 :                         }
     424                 : #else
     425               0 :                         pw = getpwnam(user);
     426                 : #endif
     427               0 :                         if (pw && pw->pw_dir) {
     428               0 :                                 spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */
     429               0 :                                 STR_FREE(SG(request_info).path_translated);
     430               0 :                                 SG(request_info).path_translated = filename;
     431                 :                         }
     432                 : #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
     433                 :                         efree(pwbuf);
     434                 : #endif
     435                 :                 }
     436                 :         } else
     437                 : #endif
     438             315 :         if (PG(doc_root) && path_info) {
     439               0 :                 length = strlen(PG(doc_root));
     440               0 :                 if (IS_ABSOLUTE_PATH(PG(doc_root), length)) {
     441               0 :                         filename = emalloc(length + strlen(path_info) + 2);
     442               0 :                         if (filename) {
     443               0 :                                 memcpy(filename, PG(doc_root), length);
     444               0 :                                 if (!IS_SLASH(filename[length - 1])) {  /* length is never 0 */
     445               0 :                                         filename[length++] = PHP_DIR_SEPARATOR;
     446                 :                                 }
     447               0 :                                 if (IS_SLASH(path_info[0])) {
     448               0 :                                         length--;
     449                 :                                 }
     450               0 :                                 strcpy(filename + length, path_info);
     451               0 :                                 STR_FREE(SG(request_info).path_translated);
     452               0 :                                 SG(request_info).path_translated = filename;
     453                 :                         }
     454                 :                 }
     455                 :         } /* if doc_root && path_info */
     456                 : 
     457             315 :         if (filename) {
     458             315 :                 filename = zend_resolve_path(filename, strlen(filename) TSRMLS_CC);
     459                 :         }
     460                 : 
     461             315 :         if (!filename) {
     462                 :                 /* we have to free SG(request_info).path_translated here because
     463                 :                  * php_destroy_request_info assumes that it will get
     464                 :                  * freed when the include_names hash is emptied, but
     465                 :                  * we're not adding it in this case */
     466               7 :                 STR_FREE(SG(request_info).path_translated);
     467               7 :                 SG(request_info).path_translated = NULL;
     468               7 :                 return FAILURE;
     469                 :         }
     470             308 :         fp = VCWD_FOPEN(filename, "rb");
     471                 : 
     472                 : #ifndef PHP_WIN32
     473                 :         /* refuse to open anything that is not a regular file */
     474             308 :         if (fp && (0 > fstat(fileno(fp), &st) || !S_ISREG(st.st_mode))) {
     475               0 :                 fclose(fp);
     476               0 :                 fp = NULL;
     477                 :         }
     478                 : #endif
     479                 : 
     480             308 :         if (!fp) {
     481               0 :                 STR_FREE(SG(request_info).path_translated);     /* for same reason as above */
     482               0 :                 SG(request_info).path_translated = NULL;
     483               0 :                 return FAILURE;
     484                 :         }
     485                 : 
     486             308 :         file_handle->opened_path = expand_filepath(filename, NULL TSRMLS_CC);
     487                 : 
     488             308 :         STR_FREE(SG(request_info).path_translated);     /* for same reason as above */
     489             308 :         SG(request_info).path_translated = filename;
     490                 : 
     491             308 :         file_handle->filename = SG(request_info).path_translated;
     492             308 :         file_handle->free_filename = 0;
     493             308 :         file_handle->handle.fp = fp;
     494             308 :         file_handle->type = ZEND_HANDLE_FP;
     495                 : 
     496             308 :         return SUCCESS;
     497                 : }
     498                 : /* }}} */
     499                 : 
     500                 : /* {{{ php_resolve_path
     501                 :  * Returns the realpath for given filename according to include path
     502                 :  */
     503                 : PHPAPI char *php_resolve_path(const char *filename, int filename_length, const char *path TSRMLS_DC)
     504           14077 : {
     505                 :         char resolved_path[MAXPATHLEN];
     506                 :         char trypath[MAXPATHLEN];
     507                 :         const char *ptr, *end, *p;
     508                 :         char *actual_path;
     509                 :         php_stream_wrapper *wrapper;
     510                 : 
     511           14077 :         if (!filename) {
     512               0 :                 return NULL;
     513                 :         }
     514                 : 
     515                 :         /* Don't resolve paths which contain protocol (except of file://) */
     516           14077 :         for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
     517           14077 :         if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {
     518             285 :                 wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
     519             285 :                 if (wrapper == &php_plain_files_wrapper) {
     520               4 :                         if (tsrm_realpath(actual_path, resolved_path TSRMLS_CC)) {
     521               2 :                                 return estrdup(resolved_path);
     522                 :                         }
     523                 :                 }
     524             283 :                 return NULL;
     525                 :         }
     526                 : 
     527           13792 :         if ((*filename == '.' && 
     528                 :              (IS_SLASH(filename[1]) || 
     529                 :               ((filename[1] == '.') && IS_SLASH(filename[2])))) ||
     530                 :             IS_ABSOLUTE_PATH(filename, filename_length) ||
     531                 :             !path ||
     532                 :             !*path) {
     533            7920 :                 if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) {
     534            7909 :                         return estrdup(resolved_path);
     535                 :                 } else {
     536              11 :                         return NULL;
     537                 :                 }
     538                 :         }
     539                 : 
     540            5872 :         ptr = path;
     541           23330 :         while (ptr && *ptr) {
     542                 :                 /* Check for stream wrapper */
     543           11697 :                 int is_stream_wrapper = 0;
     544                 : 
     545           11697 :                 for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
     546           11697 :                 if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] == '/')) {
     547                 :                         /* .:// or ..:// is not a stream wrapper */
     548              46 :                         if (p[-1] != '.' || p[-2] != '.' || p - 2 != ptr) {
     549              46 :                                 p += 3;
     550              46 :                                 is_stream_wrapper = 1;
     551                 :                         }
     552                 :                 }
     553           11697 :                 end = strchr(p, DEFAULT_DIR_SEPARATOR);
     554           11697 :                 if (end) {
     555            5933 :                         if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) {
     556               0 :                                 ptr = end + 1;
     557               0 :                                 continue;
     558                 :                         }
     559            5933 :                         memcpy(trypath, ptr, end-ptr);
     560            5933 :                         trypath[end-ptr] = '/';
     561            5933 :                         memcpy(trypath+(end-ptr)+1, filename, filename_length+1);
     562            5933 :                         ptr = end+1;
     563                 :                 } else {
     564            5764 :                         int len = strlen(ptr);
     565                 : 
     566            5764 :                         if (len + 1 + filename_length + 1 >= MAXPATHLEN) {
     567               0 :                                 break;
     568                 :                         }
     569            5764 :                         memcpy(trypath, ptr, len);
     570            5764 :                         trypath[len] = '/';
     571            5764 :                         memcpy(trypath+len+1, filename, filename_length+1);
     572            5764 :                         ptr = NULL;
     573                 :                 }
     574           11697 :                 actual_path = trypath;
     575           11697 :                 if (is_stream_wrapper) {
     576              46 :                         wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
     577              46 :                         if (!wrapper) {
     578               0 :                                 continue;
     579              46 :                         } else if (wrapper != &php_plain_files_wrapper) {
     580              46 :                                 if (wrapper->wops->url_stat) {
     581                 :                                         php_stream_statbuf ssb;
     582                 : 
     583              46 :                                         if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) {
     584              33 :                                                 return estrdup(trypath);
     585                 :                                         }
     586                 :                                 }
     587              13 :                                 continue;
     588                 :                         }
     589                 :                 }
     590           11651 :                 if (tsrm_realpath(actual_path, resolved_path TSRMLS_CC)) {
     591              78 :                         return estrdup(resolved_path);
     592                 :                 }
     593                 :         } /* end provided path */
     594                 : 
     595                 :         /* check in calling scripts' current working directory as a fall back case
     596                 :          */
     597            5761 :         if (zend_is_executing(TSRMLS_C)) {
     598            5754 :                 char *exec_fname = zend_get_executed_filename(TSRMLS_C);
     599            5754 :                 int exec_fname_length = strlen(exec_fname);
     600                 : 
     601          136086 :                 while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
     602            5754 :                 if (exec_fname && exec_fname[0] != '[' &&
     603                 :                     exec_fname_length > 0 &&
     604                 :                     exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) {
     605            5754 :                         memcpy(trypath, exec_fname, exec_fname_length + 1);
     606            5754 :                         memcpy(trypath+exec_fname_length + 1, filename, filename_length+1);
     607            5754 :                         actual_path = trypath;
     608                 : 
     609                 :                         /* Check for stream wrapper */
     610            5754 :                         for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
     611            5754 :                         if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && (p[2] == '/')) {
     612               4 :                                 wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
     613               4 :                                 if (!wrapper) {
     614               0 :                                         return NULL;
     615               4 :                                 } else if (wrapper != &php_plain_files_wrapper) {
     616               4 :                                         if (wrapper->wops->url_stat) {
     617                 :                                                 php_stream_statbuf ssb;
     618                 : 
     619               4 :                                                 if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) {
     620               2 :                                                         return estrdup(trypath);
     621                 :                                                 }
     622                 :                                         }
     623               2 :                                         return NULL;
     624                 :                                 }
     625                 :                         }
     626                 : 
     627            5750 :                         if (tsrm_realpath(actual_path, resolved_path TSRMLS_CC)) {
     628            5680 :                                 return estrdup(resolved_path);
     629                 :                         }
     630                 :                 }
     631                 :         }
     632                 : 
     633              77 :         return NULL;
     634                 : }
     635                 : /* }}} */
     636                 : 
     637                 : /* {{{ php_fopen_with_path
     638                 :  * Tries to open a file with a PATH-style list of directories.
     639                 :  * If the filename starts with "." or "/", the path is ignored.
     640                 :  */
     641                 : PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC)
     642           35038 : {
     643                 :         char *pathbuf, *ptr, *end;
     644                 :         char *exec_fname;
     645                 :         char trypath[MAXPATHLEN];
     646                 :         struct stat sb;
     647                 :         FILE *fp;
     648                 :         int path_length;
     649                 :         int filename_length;
     650                 :         int exec_fname_length;
     651                 : 
     652           35038 :         if (opened_path) {
     653           35038 :                 *opened_path = NULL;
     654                 :         }
     655                 : 
     656           35038 :         if (!filename) {
     657               0 :                 return NULL;
     658                 :         }
     659                 : 
     660           35038 :         filename_length = strlen(filename);
     661                 : 
     662                 :         /* Relative path open */
     663           35038 :         if (*filename == '.') {
     664               0 :                 if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) {
     665               0 :                         return NULL;
     666                 :                 }
     667               0 :                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     668                 :         }
     669                 : 
     670                 :         /*
     671                 :          * files in safe_mode_include_dir (or subdir) are excluded from
     672                 :          * safe mode GID/UID checks
     673                 :          */
     674                 : 
     675                 :         /* Absolute path open */
     676           35038 :         if (IS_ABSOLUTE_PATH(filename, filename_length)) {
     677               0 :                 if (php_check_safe_mode_include_dir(filename TSRMLS_CC) == 0) {
     678                 :                         /* filename is in safe_mode_include_dir (or subdir) */
     679               0 :                         return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     680                 :                 }
     681               0 :                 if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) {
     682               0 :                         return NULL;
     683                 :                 }
     684               0 :                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     685                 :         }
     686                 : 
     687           35038 :         if (!path || (path && !*path)) {
     688               0 :                 if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) {
     689               0 :                         return NULL;
     690                 :                 }
     691               0 :                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     692                 :         }
     693                 : 
     694                 :         /* check in provided path */
     695                 :         /* append the calling scripts' current working directory
     696                 :          * as a fall back case
     697                 :          */
     698           35038 :         if (zend_is_executing(TSRMLS_C)) {
     699               0 :                 exec_fname = zend_get_executed_filename(TSRMLS_C);
     700               0 :                 exec_fname_length = strlen(exec_fname);
     701               0 :                 path_length = strlen(path);
     702                 : 
     703               0 :                 while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
     704               0 :                 if ((exec_fname && exec_fname[0] == '[') || exec_fname_length <= 0) {
     705                 :                         /* [no active file] or no path */
     706               0 :                         pathbuf = estrdup(path);
     707                 :                 } else {
     708               0 :                         pathbuf = (char *) emalloc(exec_fname_length + path_length + 1 + 1);
     709               0 :                         memcpy(pathbuf, path, path_length);
     710               0 :                         pathbuf[path_length] = DEFAULT_DIR_SEPARATOR;
     711               0 :                         memcpy(pathbuf + path_length + 1, exec_fname, exec_fname_length);
     712               0 :                         pathbuf[path_length + exec_fname_length + 1] = '\0';
     713                 :                 }
     714                 :         } else {
     715           35038 :                 pathbuf = estrdup(path);
     716                 :         }
     717                 : 
     718           35038 :         ptr = pathbuf;
     719                 : 
     720          123201 :         while (ptr && *ptr) {
     721           70644 :                 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
     722           70644 :                 if (end != NULL) {
     723           35606 :                         *end = '\0';
     724           35606 :                         end++;
     725                 :                 }
     726           70644 :                 if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) {
     727               0 :                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN);
     728                 :                 }
     729           70644 :                 if (PG(safe_mode)) {
     730               0 :                         if (VCWD_STAT(trypath, &sb) == 0) {
     731                 :                                 /* file exists ... check permission */
     732               0 :                                 if (php_check_safe_mode_include_dir(trypath TSRMLS_CC) == 0 ||
     733                 :                                         php_checkuid(trypath, mode, CHECKUID_CHECK_MODE_PARAM)
     734                 :                                 ) {
     735                 :                                         /* UID ok, or trypath is in safe_mode_include_dir */
     736               0 :                                         fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC);
     737                 :                                 } else {
     738               0 :                                         fp = NULL;
     739                 :                                 }
     740               0 :                                 efree(pathbuf);
     741               0 :                                 return fp;
     742                 :                         }
     743                 :                 }
     744           70644 :                 fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC);
     745           70644 :                 if (fp) {
     746           17519 :                         efree(pathbuf);
     747           17519 :                         return fp;
     748                 :                 }
     749           53125 :                 ptr = end;
     750                 :         } /* end provided path */
     751                 : 
     752           17519 :         efree(pathbuf);
     753           17519 :         return NULL;
     754                 : }
     755                 : /* }}} */
     756                 : 
     757                 : /* {{{ php_strip_url_passwd
     758                 :  */
     759                 : PHPAPI char *php_strip_url_passwd(char *url)
     760             471 : {
     761                 :         register char *p, *url_start;
     762                 : 
     763             471 :         if (url == NULL) {
     764               0 :                 return "";
     765                 :         }
     766                 : 
     767             471 :         p = url;
     768                 : 
     769           17073 :         while (*p) {
     770           16256 :                 if (*p == ':' && *(p + 1) == '/' && *(p + 2) == '/') {
     771                 :                         /* found protocol */
     772             125 :                         url_start = p = p + 3;
     773                 : 
     774            6547 :                         while (*p) {
     775            6299 :                                 if (*p == '@') {
     776                 :                                         int i;
     777                 : 
     778               8 :                                         for (i = 0; i < 3 && url_start < p; i++, url_start++) {
     779               6 :                                                 *url_start = '.';
     780                 :                                         }
     781              24 :                                         for (; *p; p++) {
     782              22 :                                                 *url_start++ = *p;
     783                 :                                         }
     784               2 :                                         *url_start=0;
     785               2 :                                         break;
     786                 :                                 }
     787            6297 :                                 p++;
     788                 :                         }
     789             125 :                         return url;
     790                 :                 }
     791           16131 :                 p++;
     792                 :         }
     793             346 :         return url;
     794                 : }
     795                 : /* }}} */
     796                 : 
     797                 : /* {{{ expand_filepath
     798                 :  */
     799                 : PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC)
     800          101729 : {
     801          101729 :         return expand_filepath_ex(filepath, real_path, NULL, 0 TSRMLS_CC);
     802                 : }
     803                 : /* }}} */
     804                 : 
     805                 : /* {{{ expand_filepath_ex
     806                 :  */
     807                 : PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC)
     808          101901 : {
     809                 :         cwd_state new_state;
     810                 :         char cwd[MAXPATHLEN];
     811                 :         int copy_len;
     812                 : 
     813          101901 :         if (!filepath[0]) {
     814              16 :                 return NULL;
     815          101885 :         } else if (IS_ABSOLUTE_PATH(filepath, strlen(filepath))) {
     816          100741 :                 cwd[0] = '\0';
     817                 :         } else {
     818            1144 :                 const char *iam = SG(request_info).path_translated;
     819                 :                 const char *result;
     820            1144 :                 if (relative_to) {
     821              32 :                         if (relative_to_len > MAXPATHLEN-1U) {
     822               0 :                                 return NULL;
     823                 :                         }
     824              32 :                         result = relative_to;
     825              32 :                         memcpy(cwd, relative_to, relative_to_len+1U);
     826                 :                 } else {
     827            1112 :                         result = VCWD_GETCWD(cwd, MAXPATHLEN);
     828                 :                 }
     829                 : 
     830            1144 :                 if (!result && (iam != filepath)) {
     831               0 :                         int fdtest = -1;
     832                 : 
     833               0 :                         fdtest = VCWD_OPEN(filepath, O_RDONLY);
     834               0 :                         if (fdtest != -1) {
     835                 :                                 /* return a relative file path if for any reason
     836                 :                                  * we cannot cannot getcwd() and the requested,
     837                 :                                  * relatively referenced file is accessible */
     838               0 :                                 copy_len = strlen(filepath) > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : strlen(filepath);
     839               0 :                                 real_path = estrndup(filepath, copy_len);
     840               0 :                                 close(fdtest);
     841               0 :                                 return real_path;
     842                 :                         } else {
     843               0 :                                 cwd[0] = '\0';
     844                 :                         }
     845            1144 :                 } else if (!result) {
     846               0 :                         cwd[0] = '\0';
     847                 :                 }
     848                 :         }
     849                 : 
     850          101885 :         new_state.cwd = strdup(cwd);
     851          101885 :         new_state.cwd_length = strlen(cwd);
     852                 : 
     853          101885 :         if (virtual_file_ex(&new_state, filepath, NULL, CWD_FILEPATH)) {
     854               3 :                 free(new_state.cwd);
     855               3 :                 return NULL;
     856                 :         }
     857                 : 
     858          101882 :         if (real_path) {
     859           20027 :                 copy_len = new_state.cwd_length > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : new_state.cwd_length;
     860           20027 :                 memcpy(real_path, new_state.cwd, copy_len);
     861           20027 :                 real_path[copy_len] = '\0';
     862                 :         } else {
     863           81855 :                 real_path = estrndup(new_state.cwd, new_state.cwd_length);
     864                 :         }
     865          101882 :         free(new_state.cwd);
     866                 : 
     867          101882 :         return real_path;
     868                 : }
     869                 : /* }}} */
     870                 : 
     871                 : /*
     872                 :  * Local variables:
     873                 :  * tab-width: 4
     874                 :  * c-basic-offset: 4
     875                 :  * End:
     876                 :  * vim600: sw=4 ts=4 fdm=marker
     877                 :  * vim<600: sw=4 ts=4
     878                 :  */

Generated by: LTP GCOV extension version 1.5

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

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