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

LCOV - code coverage report
Current view: top level - main - php_open_temporary_file.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 59 74 79.7 %
Date: 2014-08-04 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Author: Zeev Suraski <zeev@zend.com>                                 |
      16             :    +----------------------------------------------------------------------+
      17             :  */
      18             : 
      19             : /* $Id$ */
      20             : 
      21             : #include "php.h"
      22             : 
      23             : #include <errno.h>
      24             : #include <sys/types.h>
      25             : #include <sys/stat.h>
      26             : #include <fcntl.h>
      27             : 
      28             : #ifdef PHP_WIN32
      29             : #define O_RDONLY _O_RDONLY
      30             : #include "win32/param.h"
      31             : #include "win32/winutil.h"
      32             : #elif defined(NETWARE)
      33             : #ifdef USE_WINSOCK
      34             : #include <novsock2.h>
      35             : #else
      36             : #include <sys/socket.h>
      37             : #endif
      38             : #include <sys/param.h>
      39             : #else
      40             : #include <sys/param.h>
      41             : #include <sys/socket.h>
      42             : #include <netinet/in.h>
      43             : #include <netdb.h>
      44             : #if HAVE_ARPA_INET_H
      45             : #include <arpa/inet.h>
      46             : #endif
      47             : #endif
      48             : #ifdef HAVE_SYS_TIME_H
      49             : #include <sys/time.h>
      50             : #endif
      51             : 
      52             : #ifdef HAVE_SYS_FILE_H
      53             : #include <sys/file.h>
      54             : #endif
      55             : 
      56             : #if !defined(P_tmpdir)
      57             : #define P_tmpdir ""
      58             : #endif
      59             : 
      60             : /* {{{ php_do_open_temporary_file */
      61             : 
      62             : /* Loosely based on a tempnam() implementation by UCLA */
      63             : 
      64             : /*
      65             :  * Copyright (c) 1988, 1993
      66             :  *      The Regents of the University of California.  All rights reserved.
      67             :  *
      68             :  * Redistribution and use in source and binary forms, with or without
      69             :  * modification, are permitted provided that the following conditions
      70             :  * are met:
      71             :  * 1. Redistributions of source code must retain the above copyright
      72             :  *    notice, this list of conditions and the following disclaimer.
      73             :  * 2. Redistributions in binary form must reproduce the above copyright
      74             :  *    notice, this list of conditions and the following disclaimer in the
      75             :  *    documentation and/or other materials provided with the distribution.
      76             :  * 3. All advertising materials mentioning features or use of this software
      77             :  *    must display the following acknowledgement:
      78             :  *      This product includes software developed by the University of
      79             :  *      California, Berkeley and its contributors.
      80             :  * 4. Neither the name of the University nor the names of its contributors
      81             :  *    may be used to endorse or promote products derived from this software
      82             :  *    without specific prior written permission.
      83             :  *
      84             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      85             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      86             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      87             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      88             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      89             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      90             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      91             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      92             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      93             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      94             :  * SUCH DAMAGE.
      95             :  */
      96             : 
      97       15283 : static int php_do_open_temporary_file(const char *path, const char *pfx, char **opened_path_p TSRMLS_DC)
      98             : {
      99             :         char *trailing_slash;
     100             :         char *opened_path;
     101             :         char cwd[MAXPATHLEN];
     102             :         cwd_state new_state;
     103       15283 :         int fd = -1;
     104             : #ifndef HAVE_MKSTEMP
     105             :         int open_flags = O_CREAT | O_TRUNC | O_RDWR
     106             : #ifdef PHP_WIN32
     107             :                 | _O_BINARY
     108             : #endif
     109             :                 ;
     110             : #endif
     111             : 
     112       15283 :         if (!path || !path[0]) {
     113           0 :                 return -1;
     114             :         }
     115             : 
     116             : #ifdef PHP_WIN32
     117             :         if (!php_win32_check_trailing_space(pfx, (const int)strlen(pfx))) {
     118             :                 SetLastError(ERROR_INVALID_NAME);
     119             :                 return -1;
     120             :         }
     121             : #endif
     122             : 
     123       15283 :         if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
     124           0 :                 cwd[0] = '\0';
     125             :         }
     126             : 
     127       15283 :         new_state.cwd = estrdup(cwd);
     128       15283 :         new_state.cwd_length = strlen(cwd);
     129             : 
     130       15283 :         if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) {
     131          10 :                 efree(new_state.cwd);
     132          10 :                 return -1;
     133             :         }
     134             : 
     135       15273 :         if (IS_SLASH(new_state.cwd[new_state.cwd_length - 1])) {
     136           0 :                 trailing_slash = "";
     137             :         } else {
     138       15273 :                 trailing_slash = "/";
     139             :         }
     140             : 
     141       15273 :         if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) {
     142           0 :                 efree(opened_path);
     143           0 :                 efree(new_state.cwd);
     144           0 :                 return -1;
     145             :         }
     146             : 
     147             : #ifdef PHP_WIN32
     148             : 
     149             :         if (GetTempFileName(new_state.cwd, pfx, 0, opened_path)) {
     150             :                 /* Some versions of windows set the temp file to be read-only,
     151             :                  * which means that opening it will fail... */
     152             :                 if (VCWD_CHMOD(opened_path, 0600)) {
     153             :                         efree(opened_path);
     154             :                         efree(new_state.cwd);
     155             :                         return -1;
     156             :                 }
     157             :                 fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600);
     158             :         }
     159             : 
     160             : #elif defined(HAVE_MKSTEMP)
     161       15273 :         fd = mkstemp(opened_path);
     162             : #else
     163             :         if (mktemp(opened_path)) {
     164             :                 fd = VCWD_OPEN(opened_path, open_flags);
     165             :         }
     166             : #endif
     167             : 
     168       15657 :         if (fd == -1 || !opened_path_p) {
     169         384 :                 efree(opened_path);
     170             :         } else {
     171       14889 :                 *opened_path_p = opened_path;
     172             :         }
     173       15273 :         efree(new_state.cwd);
     174       15273 :         return fd;
     175             : }
     176             : /* }}} */
     177             : 
     178             : /* Cache the chosen temporary directory. */
     179             : static char* temporary_directory;
     180             : 
     181       21298 : PHPAPI void php_shutdown_temporary_directory(void)
     182             : {
     183       21298 :         if (temporary_directory) {
     184         500 :                 free(temporary_directory);
     185         500 :                 temporary_directory = NULL;
     186             :         }
     187       21298 : }
     188             : 
     189             : /*
     190             :  *  Determine where to place temporary files.
     191             :  */
     192       15433 : PHPAPI const char* php_get_temporary_directory(TSRMLS_D)
     193             : {
     194             :         /* Did we determine the temporary directory already? */
     195       15433 :         if (temporary_directory) {
     196       14933 :                 return temporary_directory;
     197             :         }
     198             : 
     199             :         /* Is there a temporary directory "sys_temp_dir" in .ini defined? */
     200             :         {
     201         500 :                 char *sys_temp_dir = PG(sys_temp_dir);
     202         500 :                 if (sys_temp_dir) {
     203           1 :                         int len = strlen(sys_temp_dir);
     204           1 :                         if (len >= 2 && sys_temp_dir[len - 1] == DEFAULT_SLASH) {
     205           0 :                                 temporary_directory = zend_strndup(sys_temp_dir, len - 1);
     206           0 :                                 return temporary_directory;
     207           1 :                         } else if (len >= 1 && sys_temp_dir[len - 1] != DEFAULT_SLASH) {
     208           1 :                                 temporary_directory = zend_strndup(sys_temp_dir, len);
     209           1 :                                 return temporary_directory;
     210             :                         }
     211             :                 }
     212             :         }
     213             : 
     214             : #ifdef PHP_WIN32
     215             :         /* We can't count on the environment variables TEMP or TMP,
     216             :          * and so must make the Win32 API call to get the default
     217             :          * directory for temporary files.  Note this call checks
     218             :          * the environment values TMP and TEMP (in order) first.
     219             :          */
     220             :         {
     221             :                 char sTemp[MAX_PATH];
     222             :                 DWORD len = GetTempPath(sizeof(sTemp),sTemp);
     223             :                 assert(0 < len);  /* should *never* fail! */
     224             :                 if (sTemp[len - 1] == DEFAULT_SLASH) {
     225             :                         temporary_directory = zend_strndup(sTemp, len - 1);
     226             :                 } else {
     227             :                         temporary_directory = zend_strndup(sTemp, len);
     228             :                 }
     229             :                 return temporary_directory;
     230             :         }
     231             : #else
     232             :         /* On Unix use the (usual) TMPDIR environment variable. */
     233             :         {
     234         499 :                 char* s = getenv("TMPDIR");
     235         499 :                 if (s && *s) {
     236           0 :                         int len = strlen(s);
     237             : 
     238           0 :                         if (s[len - 1] == DEFAULT_SLASH) {
     239           0 :                                 temporary_directory = zend_strndup(s, len - 1);
     240             :                         } else {
     241           0 :                                 temporary_directory = zend_strndup(s, len);
     242             :                         }
     243             : 
     244           0 :                         return temporary_directory;
     245             :                 }
     246             :         }
     247             : #ifdef P_tmpdir
     248             :         /* Use the standard default temporary directory. */
     249             :         if (P_tmpdir) {
     250         499 :                 temporary_directory = strdup(P_tmpdir);
     251         499 :                 return temporary_directory;
     252             :         }
     253             : #endif
     254             :         /* Shouldn't ever(!) end up here ... last ditch default. */
     255             :         temporary_directory = strdup("/tmp");
     256             :         return temporary_directory;
     257             : #endif
     258             : }
     259             : 
     260             : /* {{{ php_open_temporary_file
     261             :  *
     262             :  * Unlike tempnam(), the supplied dir argument takes precedence
     263             :  * over the TMPDIR environment variable
     264             :  * This function should do its best to return a file pointer to a newly created
     265             :  * unique file, on every platform.
     266             :  */
     267       14890 : PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC)
     268             : {
     269             :         int fd;
     270             :         const char *temp_dir;
     271             : 
     272       14890 :         if (!pfx) {
     273           1 :                 pfx = "tmp.";
     274             :         }
     275       14890 :         if (opened_path_p) {
     276       14890 :                 *opened_path_p = NULL;
     277             :         }
     278             : 
     279       14890 :         if (!dir || *dir == '\0') {
     280             : def_tmp:
     281       14540 :                 temp_dir = php_get_temporary_directory(TSRMLS_C);
     282             : 
     283       14540 :                 if (temp_dir && *temp_dir != '\0' && (!open_basedir_check || !php_check_open_basedir(temp_dir TSRMLS_CC))) {
     284       14539 :                         return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC);
     285             :                 } else {
     286           1 :                         return -1;
     287             :                 }
     288             :         }
     289             : 
     290             :         /* Try the directory given as parameter. */
     291         744 :         fd = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC);
     292         744 :         if (fd == -1) {
     293             :                 /* Use default temporary directory. */
     294         394 :                 goto def_tmp;
     295             :         }
     296         350 :         return fd;
     297             : }
     298             : 
     299       14096 : PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC)
     300             : {
     301       14096 :         return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0 TSRMLS_CC);
     302             : }
     303             : 
     304           1 : PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC)
     305             : {
     306             :         FILE *fp;
     307           1 :         int fd = php_open_temporary_fd(dir, pfx, opened_path_p TSRMLS_CC);
     308             : 
     309           1 :         if (fd == -1) {
     310           0 :                 return NULL;
     311             :         }
     312             : 
     313           1 :         fp = fdopen(fd, "r+b");
     314           1 :         if (fp == NULL) {
     315           0 :                 close(fd);
     316             :         }
     317             : 
     318           1 :         return fp;
     319             : }
     320             : /* }}} */
     321             : 
     322             : /*
     323             :  * Local variables:
     324             :  * tab-width: 4
     325             :  * c-basic-offset: 4
     326             :  * End:
     327             :  * vim600: sw=4 ts=4 fdm=marker
     328             :  * vim<600: sw=4 ts=4
     329             :  */

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:19 +0000 (28 days ago)

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