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_2/main - fopen_wrappers.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 250
Code covered: 58.8 % Executed lines: 147
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 275506 2009-02-10 16:14:27Z iliaa $ */
      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                 : /* {{{ php_check_specific_open_basedir
      83                 :         When open_basedir is not NULL, check if the given filename is located in
      84                 :         open_basedir. Returns -1 if error or not in the open_basedir, else 0.
      85                 :         When open_basedir is NULL, always return 0.
      86                 : */
      87                 : PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path TSRMLS_DC)
      88            1135 : {
      89                 :         char resolved_name[MAXPATHLEN];
      90                 :         char resolved_basedir[MAXPATHLEN];
      91                 :         char local_open_basedir[MAXPATHLEN];
      92                 :         char path_tmp[MAXPATHLEN];
      93                 :         char *path_file;
      94                 :         int resolved_basedir_len;
      95                 :         int resolved_name_len;
      96                 :         int path_len;
      97            1135 :         int nesting_level = 0;
      98                 : 
      99                 :         /* Special case basedir==".": Use script-directory */
     100            1135 :         if (strcmp(basedir, ".") || !VCWD_GETCWD(local_open_basedir, MAXPATHLEN)) {
     101                 :                 /* Else use the unmodified path */
     102               9 :                 strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir));
     103                 :         }
     104                 : 
     105            1135 :         path_len = strlen(path);
     106            1135 :         if (path_len > (MAXPATHLEN - 1)) {
     107                 :                 /* empty and too long paths are invalid */
     108               0 :                 return -1;
     109                 :         }
     110                 : 
     111                 :         /* normalize and expand path */
     112            1135 :         if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
     113               1 :                 return -1;
     114                 :         }
     115                 : 
     116            1134 :         path_len = strlen(resolved_name);
     117            1134 :         memcpy(path_tmp, resolved_name, path_len + 1); /* safe */
     118                 : 
     119            2687 :         while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) {
     120                 : #ifdef HAVE_SYMLINK
     121             419 :                 if (nesting_level == 0) {
     122                 :                         int ret;
     123                 :                         char buf[MAXPATHLEN];
     124                 : 
     125             419 :                         ret = readlink(path_tmp, buf, MAXPATHLEN - 1);
     126             419 :                         if (ret < 0) {
     127                 :                                 /* not a broken symlink, move along.. */
     128                 :                         } else {
     129                 :                                 /* put the real path into the path buffer */
     130               0 :                                 memcpy(path_tmp, buf, ret);
     131               0 :                                 path_tmp[ret] = '\0';
     132                 :                         }
     133                 :                 }
     134                 : #endif
     135                 : 
     136                 : #if defined(PHP_WIN32) || defined(NETWARE)
     137                 :                 path_file = strrchr(path_tmp, DEFAULT_SLASH);
     138                 :                 if (!path_file) {
     139                 :                         path_file = strrchr(path_tmp, '/');
     140                 :                 }
     141                 : #else
     142             419 :                 path_file = strrchr(path_tmp, DEFAULT_SLASH);
     143                 : #endif
     144             419 :                 if (!path_file) {
     145                 :                         /* none of the path components exist. definitely not in open_basedir.. */
     146               0 :                         return -1;
     147                 :                 } else {
     148             419 :                         path_len = path_file - path_tmp + 1;
     149                 : #if defined(PHP_WIN32) || defined(NETWARE)
     150                 :                         if (path_len > 1 && path_tmp[path_len - 2] == ':') {
     151                 :                                 if (path_len != 3) {
     152                 :                                         return -1;
     153                 :                                 } 
     154                 :                                 /* this is c:\ */
     155                 :                                 path_tmp[path_len] = '\0';
     156                 :                         } else {
     157                 :                                 path_tmp[path_len - 1] = '\0';
     158                 :                         }
     159                 : #else
     160             419 :                         path_tmp[path_len - 1] = '\0';
     161                 : #endif
     162                 :                 }
     163             419 :                 nesting_level++;
     164                 :         }
     165                 : 
     166                 :         /* Resolve open_basedir to resolved_basedir */
     167            1134 :         if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) {
     168                 :                 /* Handler for basedirs that end with a / */
     169            1134 :                 resolved_basedir_len = strlen(resolved_basedir);
     170            1134 :                 if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) {
     171               8 :                         if (resolved_basedir[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) {
     172               7 :                                 resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR;
     173               7 :                                 resolved_basedir[++resolved_basedir_len] = '\0';
     174                 :                         }
     175                 :                 }
     176                 : 
     177            1134 :                 resolved_name_len = strlen(resolved_name);
     178            1134 :                 if (path_tmp[path_len - 1] == PHP_DIR_SEPARATOR) {
     179              32 :                         if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
     180               0 :                                 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
     181               0 :                                 resolved_name[++resolved_name_len] = '\0';
     182                 :                         }
     183                 :                 }
     184                 : 
     185                 :                 /* Check the path */
     186                 : #if defined(PHP_WIN32) || defined(NETWARE)
     187                 :                 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
     188                 : #else
     189            1134 :                 if (strncmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
     190                 : #endif
     191                 :                         /* File is in the right directory */
     192             748 :                         return 0;
     193                 :                 } else {
     194                 :                         /* /openbasedir/ and /openbasedir are the same directory */
     195             386 :                         if (resolved_basedir_len == (resolved_name_len + 1) && resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
     196                 : #if defined(PHP_WIN32) || defined(NETWARE)
     197                 :                                 if (strncasecmp(resolved_basedir, resolved_name, resolved_name_len) == 0) {
     198                 : #else
     199               5 :                                 if (strncmp(resolved_basedir, resolved_name, resolved_name_len) == 0) {
     200                 : #endif
     201               5 :                                         return 0;
     202                 :                                 }
     203                 :                         }
     204             381 :                         return -1;
     205                 :                 }
     206                 :         } else {
     207                 :                 /* Unable to resolve the real path, return -1 */
     208               0 :                 return -1;
     209                 :         }
     210                 : }
     211                 : /* }}} */
     212                 : 
     213                 : PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC)
     214          331149 : {
     215          331149 :         return php_check_open_basedir_ex(path, 1 TSRMLS_CC);
     216                 : }
     217                 : 
     218                 : /* {{{ php_check_open_basedir
     219                 :  */
     220                 : PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC)
     221          403108 : {
     222                 :         /* Only check when open_basedir is available */
     223          403108 :         if (PG(open_basedir) && *PG(open_basedir)) {
     224                 :                 char *pathbuf;
     225                 :                 char *ptr;
     226                 :                 char *end;
     227                 : 
     228            1135 :                 pathbuf = estrdup(PG(open_basedir));
     229                 : 
     230            1135 :                 ptr = pathbuf;
     231                 : 
     232            2652 :                 while (ptr && *ptr) {
     233            1135 :                         end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
     234            1135 :                         if (end != NULL) {
     235               0 :                                 *end = '\0';
     236               0 :                                 end++;
     237                 :                         }
     238                 : 
     239            1135 :                         if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) {
     240             753 :                                 efree(pathbuf);
     241             753 :                                 return 0;
     242                 :                         }
     243                 : 
     244             382 :                         ptr = end;
     245                 :                 }
     246             382 :                 if (warn) {
     247             316 :                         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));
     248                 :                 }
     249             382 :                 efree(pathbuf);
     250             382 :                 errno = EPERM; /* we deny permission to open it */
     251             382 :                 return -1;
     252                 :         }
     253                 : 
     254                 :         /* Nothing to check... */
     255          401973 :         return 0;
     256                 : }
     257                 : /* }}} */
     258                 : 
     259                 : /* {{{ php_check_safe_mode_include_dir
     260                 :  */
     261                 : PHPAPI int php_check_safe_mode_include_dir(const char *path TSRMLS_DC)
     262            1580 : {
     263            1580 :         if (PG(safe_mode)) {
     264               0 :                 if (PG(safe_mode_include_dir) && *PG(safe_mode_include_dir)) {
     265                 :                         char *pathbuf;
     266                 :                         char *ptr;
     267                 :                         char *end;
     268                 :                         char resolved_name[MAXPATHLEN];
     269                 : 
     270                 :                         /* Resolve the real path into resolved_name */
     271               0 :                         if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
     272               0 :                                 return -1;
     273                 :                         }
     274               0 :                         pathbuf = estrdup(PG(safe_mode_include_dir));
     275               0 :                         ptr = pathbuf;
     276                 : 
     277               0 :                         while (ptr && *ptr) {
     278               0 :                                 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
     279               0 :                                 if (end != NULL) {
     280               0 :                                         *end = '\0';
     281               0 :                                         end++;
     282                 :                                 }
     283                 : 
     284                 :                                 /* Check the path */
     285                 : #ifdef PHP_WIN32
     286                 :                                 if (strncasecmp(ptr, resolved_name, strlen(ptr)) == 0)
     287                 : #else
     288               0 :                                 if (strncmp(ptr, resolved_name, strlen(ptr)) == 0)
     289                 : #endif
     290                 :                                 {
     291                 :                                         /* File is in the right directory */
     292               0 :                                         efree(pathbuf);
     293               0 :                                         return 0;
     294                 :                                 }
     295                 : 
     296               0 :                                 ptr = end;
     297                 :                         }
     298               0 :                         efree(pathbuf);
     299                 :                 }
     300               0 :                 return -1;
     301                 :         }
     302                 : 
     303                 :         /* Nothing to check... */
     304            1580 :         return 0;
     305                 : }
     306                 : /* }}} */
     307                 : 
     308                 : /* {{{ php_fopen_and_set_opened_path
     309                 :  */
     310                 : static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, char **opened_path TSRMLS_DC)
     311           54018 : {
     312                 :         FILE *fp;
     313                 : 
     314           54018 :         if (php_check_open_basedir((char *)path TSRMLS_CC)) {
     315               0 :                 return NULL;
     316                 :         }
     317           54018 :         fp = VCWD_FOPEN(path, mode);
     318           54018 :         if (fp && opened_path) {
     319           13467 :                 *opened_path = expand_filepath(path, NULL TSRMLS_CC);
     320                 :         }
     321           54018 :         return fp;
     322                 : }
     323                 : /* }}} */
     324                 : 
     325                 : /* {{{ php_fopen_primary_script
     326                 :  */
     327                 : PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC)
     328              95 : {
     329                 :         FILE *fp;
     330                 : #ifndef PHP_WIN32
     331                 :         struct stat st;
     332                 : #endif
     333                 :         char *path_info, *filename;
     334                 :         int length;
     335                 : 
     336              95 :         filename = SG(request_info).path_translated;
     337              95 :         path_info = SG(request_info).request_uri;
     338                 : #if HAVE_PWD_H
     339              95 :         if (PG(user_dir) && *PG(user_dir) && path_info && '/' == path_info[0] && '~' == path_info[1]) {
     340               0 :                 char *s = strchr(path_info + 2, '/');
     341                 : 
     342               0 :                 filename = NULL;        /* discard the original filename, it must not be used */
     343               0 :                 if (s) {                        /* if there is no path name after the file, do not bother */
     344                 :                         char user[32];                  /* to try open the directory */
     345                 :                         struct passwd *pw;
     346                 : #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
     347                 :                         struct passwd pwstruc;
     348                 :                         long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
     349                 :                         char *pwbuf;
     350                 : 
     351                 :                         if (pwbuflen < 1) {
     352                 :                                 return FAILURE;
     353                 :                         }
     354                 : 
     355                 :                         pwbuf = emalloc(pwbuflen);
     356                 : #endif
     357               0 :                         length = s - (path_info + 2);
     358               0 :                         if (length > (int)sizeof(user) - 1) {
     359               0 :                                 length = sizeof(user) - 1;
     360                 :                         }
     361               0 :                         memcpy(user, path_info + 2, length);
     362               0 :                         user[length] = '\0';
     363                 : #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
     364                 :                         if (getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw)) {
     365                 :                                 efree(pwbuf);
     366                 :                                 return FAILURE;
     367                 :                         }
     368                 : #else
     369               0 :                         pw = getpwnam(user);
     370                 : #endif
     371               0 :                         if (pw && pw->pw_dir) {
     372               0 :                                 spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */
     373               0 :                                 STR_FREE(SG(request_info).path_translated);
     374               0 :                                 SG(request_info).path_translated = filename;
     375                 :                         }
     376                 : #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
     377                 :                         efree(pwbuf);
     378                 : #endif
     379                 :                 }
     380                 :         } else
     381                 : #endif
     382              95 :         if (PG(doc_root) && path_info) {
     383               0 :                 length = strlen(PG(doc_root));
     384               0 :                 if (IS_ABSOLUTE_PATH(PG(doc_root), length)) {
     385               0 :                         filename = emalloc(length + strlen(path_info) + 2);
     386               0 :                         if (filename) {
     387               0 :                                 memcpy(filename, PG(doc_root), length);
     388               0 :                                 if (!IS_SLASH(filename[length - 1])) {  /* length is never 0 */
     389               0 :                                         filename[length++] = PHP_DIR_SEPARATOR;
     390                 :                                 }
     391               0 :                                 if (IS_SLASH(path_info[0])) {
     392               0 :                                         length--;
     393                 :                                 }
     394               0 :                                 strcpy(filename + length, path_info);
     395               0 :                                 STR_FREE(SG(request_info).path_translated);
     396               0 :                                 SG(request_info).path_translated = filename;
     397                 :                         }
     398                 :                 }
     399                 :         } /* if doc_root && path_info */
     400                 : 
     401              95 :         if (!filename) {
     402                 :                 /* we have to free SG(request_info).path_translated here because
     403                 :                  * php_destroy_request_info assumes that it will get
     404                 :                  * freed when the include_names hash is emptied, but
     405                 :                  * we're not adding it in this case */
     406               0 :                 STR_FREE(SG(request_info).path_translated);
     407               0 :                 SG(request_info).path_translated = NULL;
     408               0 :                 return FAILURE;
     409                 :         }
     410              95 :         fp = VCWD_FOPEN(filename, "rb");
     411                 : 
     412                 : #ifndef PHP_WIN32
     413                 :         /* refuse to open anything that is not a regular file */
     414              95 :         if (fp && (0 > fstat(fileno(fp), &st) || !S_ISREG(st.st_mode))) {
     415               0 :                 fclose(fp);
     416               0 :                 fp = NULL;
     417                 :         }
     418                 : #endif
     419                 : 
     420              95 :         if (!fp) {
     421               7 :                 STR_FREE(SG(request_info).path_translated);     /* for same reason as above */
     422               7 :                 SG(request_info).path_translated = NULL;
     423               7 :                 return FAILURE;
     424                 :         }
     425                 : 
     426              88 :         file_handle->opened_path = expand_filepath(filename, NULL TSRMLS_CC);
     427                 : 
     428              88 :         if (!(SG(options) & SAPI_OPTION_NO_CHDIR)) {
     429              68 :                 VCWD_CHDIR_FILE(filename);
     430                 :         }
     431              88 :         SG(request_info).path_translated = filename;
     432                 : 
     433              88 :         file_handle->filename = SG(request_info).path_translated;
     434              88 :         file_handle->free_filename = 0;
     435              88 :         file_handle->handle.fp = fp;
     436              88 :         file_handle->type = ZEND_HANDLE_FP;
     437                 : 
     438              88 :         return SUCCESS;
     439                 : }
     440                 : /* }}} */
     441                 : 
     442                 : /* {{{ php_fopen_with_path
     443                 :  * Tries to open a file with a PATH-style list of directories.
     444                 :  * If the filename starts with "." or "/", the path is ignored.
     445                 :  */
     446                 : PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC)
     447           26934 : {
     448                 :         char *pathbuf, *ptr, *end;
     449                 :         char *exec_fname;
     450                 :         char trypath[MAXPATHLEN];
     451                 :         struct stat sb;
     452                 :         FILE *fp;
     453                 :         int path_length;
     454                 :         int filename_length;
     455                 :         int exec_fname_length;
     456                 : 
     457           26934 :         if (opened_path) {
     458           26934 :                 *opened_path = NULL;
     459                 :         }
     460                 : 
     461           26934 :         if (!filename) {
     462               0 :                 return NULL;
     463                 :         }
     464                 : 
     465           26934 :         filename_length = strlen(filename);
     466                 : 
     467                 :         /* Relative path open */
     468           26934 :         if (*filename == '.') {
     469               0 :                 if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) {
     470               0 :                         return NULL;
     471                 :                 }
     472               0 :                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     473                 :         }
     474                 : 
     475                 :         /*
     476                 :          * files in safe_mode_include_dir (or subdir) are excluded from
     477                 :          * safe mode GID/UID checks
     478                 :          */
     479                 : 
     480                 :         /* Absolute path open */
     481           26934 :         if (IS_ABSOLUTE_PATH(filename, filename_length)) {
     482               0 :                 if (php_check_safe_mode_include_dir(filename TSRMLS_CC) == 0) {
     483                 :                         /* filename is in safe_mode_include_dir (or subdir) */
     484               0 :                         return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     485                 :                 }
     486               0 :                 if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) {
     487               0 :                         return NULL;
     488                 :                 }
     489               0 :                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     490                 :         }
     491                 : 
     492           26934 :         if (!path || (path && !*path)) {
     493               0 :                 if (PG(safe_mode) && (!php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))) {
     494               0 :                         return NULL;
     495                 :                 }
     496               0 :                 return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC);
     497                 :         }
     498                 : 
     499                 :         /* check in provided path */
     500                 :         /* append the calling scripts' current working directory
     501                 :          * as a fall back case
     502                 :          */
     503           26934 :         if (zend_is_executing(TSRMLS_C)) {
     504               0 :                 exec_fname = zend_get_executed_filename(TSRMLS_C);
     505               0 :                 exec_fname_length = strlen(exec_fname);
     506               0 :                 path_length = strlen(path);
     507                 : 
     508               0 :                 while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
     509               0 :                 if ((exec_fname && exec_fname[0] == '[') || exec_fname_length <= 0) {
     510                 :                         /* [no active file] or no path */
     511               0 :                         pathbuf = estrdup(path);
     512                 :                 } else {
     513               0 :                         pathbuf = (char *) emalloc(exec_fname_length + path_length + 1 + 1);
     514               0 :                         memcpy(pathbuf, path, path_length);
     515               0 :                         pathbuf[path_length] = DEFAULT_DIR_SEPARATOR;
     516               0 :                         memcpy(pathbuf + path_length + 1, exec_fname, exec_fname_length);
     517               0 :                         pathbuf[path_length + exec_fname_length + 1] = '\0';
     518                 :                 }
     519                 :         } else {
     520           26934 :                 pathbuf = estrdup(path);
     521                 :         }
     522                 : 
     523           26934 :         ptr = pathbuf;
     524                 : 
     525           94419 :         while (ptr && *ptr) {
     526           54018 :                 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
     527           54018 :                 if (end != NULL) {
     528           27084 :                         *end = '\0';
     529           27084 :                         end++;
     530                 :                 }
     531           54018 :                 if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) {
     532               0 :                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN);
     533                 :                 }
     534           54018 :                 if (PG(safe_mode)) {
     535               0 :                         if (VCWD_STAT(trypath, &sb) == 0) {
     536                 :                                 /* file exists ... check permission */
     537               0 :                                 if (php_check_safe_mode_include_dir(trypath TSRMLS_CC) == 0 ||
     538                 :                                         php_checkuid(trypath, mode, CHECKUID_CHECK_MODE_PARAM)
     539                 :                                 ) {
     540                 :                                         /* UID ok, or trypath is in safe_mode_include_dir */
     541               0 :                                         fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC);
     542                 :                                 } else {
     543               0 :                                         fp = NULL;
     544                 :                                 }
     545               0 :                                 efree(pathbuf);
     546               0 :                                 return fp;
     547                 :                         }
     548                 :                 }
     549           54018 :                 fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC);
     550           54018 :                 if (fp) {
     551           13467 :                         efree(pathbuf);
     552           13467 :                         return fp;
     553                 :                 }
     554           40551 :                 ptr = end;
     555                 :         } /* end provided path */
     556                 : 
     557           13467 :         efree(pathbuf);
     558           13467 :         return NULL;
     559                 : }
     560                 : /* }}} */
     561                 : 
     562                 : /* {{{ php_strip_url_passwd
     563                 :  */
     564                 : PHPAPI char *php_strip_url_passwd(char *url)
     565             391 : {
     566                 :         register char *p, *url_start;
     567                 : 
     568             391 :         if (url == NULL) {
     569               0 :                 return "";
     570                 :         }
     571                 : 
     572             391 :         p = url;
     573                 : 
     574           13191 :         while (*p) {
     575           12440 :                 if (*p == ':' && *(p + 1) == '/' && *(p + 2) == '/') {
     576                 :                         /* found protocol */
     577              31 :                         url_start = p = p + 3;
     578                 : 
     579             763 :                         while (*p) {
     580             701 :                                 if (*p == '@') {
     581                 :                                         int i;
     582                 : 
     583               0 :                                         for (i = 0; i < 3 && url_start < p; i++, url_start++) {
     584               0 :                                                 *url_start = '.';
     585                 :                                         }
     586               0 :                                         for (; *p; p++) {
     587               0 :                                                 *url_start++ = *p;
     588                 :                                         }
     589               0 :                                         *url_start=0;
     590               0 :                                         break;
     591                 :                                 }
     592             701 :                                 p++;
     593                 :                         }
     594              31 :                         return url;
     595                 :                 }
     596           12409 :                 p++;
     597                 :         }
     598             360 :         return url;
     599                 : }
     600                 : /* }}} */
     601                 : 
     602                 : /* {{{ expand_filepath
     603                 :  */
     604                 : PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC)
     605           76645 : {
     606           76645 :         return expand_filepath_ex(filepath, real_path, NULL, 0 TSRMLS_CC);
     607                 : }
     608                 : /* }}} */
     609                 : 
     610                 : /* {{{ expand_filepath_ex
     611                 :  */
     612                 : PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC)
     613           76812 : {
     614                 :         cwd_state new_state;
     615                 :         char cwd[MAXPATHLEN];
     616                 :         int copy_len;
     617                 : 
     618           76812 :         if (!filepath[0]) {
     619              14 :                 return NULL;
     620           76798 :         } else if (IS_ABSOLUTE_PATH(filepath, strlen(filepath))) {
     621           73217 :                 cwd[0] = '\0';
     622                 :         } else {
     623            3581 :                 const char *iam = SG(request_info).path_translated;
     624                 :                 const char *result;
     625            3581 :                 if (relative_to) {
     626              32 :                         if (relative_to_len > MAXPATHLEN-1U) {
     627               0 :                                 return NULL;
     628                 :                         }
     629              32 :                         result = relative_to;
     630              32 :                         memcpy(cwd, relative_to, relative_to_len+1U);
     631                 :                 } else {
     632            3549 :                         result = VCWD_GETCWD(cwd, MAXPATHLEN);
     633                 :                 }
     634                 : 
     635            3581 :                 if (!result && (iam != filepath)) {
     636               0 :                         int fdtest = -1;
     637                 : 
     638               0 :                         fdtest = VCWD_OPEN(filepath, O_RDONLY);
     639               0 :                         if (fdtest != -1) {
     640                 :                                 /* return a relative file path if for any reason
     641                 :                                  * we cannot cannot getcwd() and the requested,
     642                 :                                  * relatively referenced file is accessible */
     643               0 :                                 copy_len = strlen(filepath) > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : strlen(filepath);
     644               0 :                                 real_path = estrndup(filepath, copy_len);
     645               0 :                                 close(fdtest);
     646               0 :                                 return real_path;
     647                 :                         } else {
     648               0 :                                 cwd[0] = '\0';
     649                 :                         }
     650            3581 :                 } else if (!result) {
     651               0 :                         cwd[0] = '\0';
     652                 :                 }
     653                 :         }
     654                 : 
     655           76798 :         new_state.cwd = strdup(cwd);
     656           76798 :         new_state.cwd_length = strlen(cwd);
     657                 : 
     658           76798 :         if (virtual_file_ex(&new_state, filepath, NULL, CWD_FILEPATH)) {
     659               2 :                 free(new_state.cwd);
     660               2 :                 return NULL;
     661                 :         }
     662                 : 
     663           76796 :         if (real_path) {
     664           16334 :                 copy_len = new_state.cwd_length > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : new_state.cwd_length;
     665           16334 :                 memcpy(real_path, new_state.cwd, copy_len);
     666           16334 :                 real_path[copy_len] = '\0';
     667                 :         } else {
     668           60462 :                 real_path = estrndup(new_state.cwd, new_state.cwd_length);
     669                 :         }
     670           76796 :         free(new_state.cwd);
     671                 : 
     672           76796 :         return real_path;
     673                 : }
     674                 : /* }}} */
     675                 : 
     676                 : /*
     677                 :  * Local variables:
     678                 :  * tab-width: 4
     679                 :  * c-basic-offset: 4
     680                 :  * End:
     681                 :  * vim600: sw=4 ts=4 fdm=marker
     682                 :  * vim<600: sw=4 ts=4
     683                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:28 +0000 (5 days ago)

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