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

LCOV - code coverage report
Current view: top level - ext/standard - php_fopen_wrapper.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 123 173 71.1 %
Date: 2014-04-18 Functions: 7 9 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2013 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@php.net>                             |
      16             :    |          Jim Winstead <jimw@php.net>                                 |
      17             :    |          Hartmut Holzgraefe <hholzgra@php.net>                       |
      18             :    +----------------------------------------------------------------------+
      19             :  */
      20             : /* $Id$ */
      21             : 
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #if HAVE_UNISTD_H
      25             : #include <unistd.h>
      26             : #endif
      27             : 
      28             : #include "php.h"
      29             : #include "php_globals.h"
      30             : #include "php_standard.h"
      31             : #include "php_fopen_wrappers.h"
      32             : #include "SAPI.h"
      33             : 
      34           8 : static size_t php_stream_output_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) /* {{{ */
      35             : {
      36           8 :         PHPWRITE(buf, count);
      37           8 :         return count;
      38             : }
      39             : /* }}} */
      40             : 
      41           0 : static size_t php_stream_output_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */
      42             : {
      43           0 :         stream->eof = 1;
      44           0 :         return 0;
      45             : }
      46             : /* }}} */
      47             : 
      48           1 : static int php_stream_output_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */
      49             : {
      50           1 :         return 0;
      51             : }
      52             : /* }}} */
      53             : 
      54             : php_stream_ops php_stream_output_ops = {
      55             :         php_stream_output_write,
      56             :         php_stream_output_read,
      57             :         php_stream_output_close,
      58             :         NULL, /* flush */
      59             :         "Output",
      60             :         NULL, /* seek */
      61             :         NULL, /* cast */
      62             :         NULL, /* stat */
      63             :         NULL  /* set_option */
      64             : };
      65             : 
      66           0 : static size_t php_stream_input_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) /* {{{ */
      67             : {
      68           0 :         return -1;
      69             : }
      70             : /* }}} */
      71             : 
      72           2 : static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */
      73             : {
      74           2 :         off_t *position = (off_t*)stream->abstract;
      75           2 :         size_t read_bytes = 0;
      76             : 
      77           2 :         if (!stream->eof) {
      78           1 :                 if (SG(request_info).raw_post_data) { /* data has already been read by a post handler */
      79           1 :                         read_bytes = SG(request_info).raw_post_data_length - *position;
      80           1 :                         if (read_bytes <= count) {
      81           1 :                                 stream->eof = 1;
      82             :                         } else {
      83           0 :                                 read_bytes = count;
      84             :                         }
      85           1 :                         if (read_bytes) {
      86           1 :                                 memcpy(buf, SG(request_info).raw_post_data + *position, read_bytes);
      87             :                         }
      88           0 :                 } else if (sapi_module.read_post) {
      89           0 :                         read_bytes = sapi_module.read_post(buf, count TSRMLS_CC);
      90           0 :                         if (read_bytes <= 0) {
      91           0 :                                 stream->eof = 1;
      92           0 :                                 read_bytes = 0;
      93             :                         }
      94             :                         /* Increment SG(read_post_bytes) only when something was actually read. */
      95           0 :                         SG(read_post_bytes) += read_bytes;
      96             :                 } else {
      97           0 :                         stream->eof = 1;
      98             :                 }
      99             :         }
     100             : 
     101           2 :         *position += read_bytes;
     102             : 
     103           2 :         return read_bytes;
     104             : }
     105             : /* }}} */
     106             : 
     107           3 : static int php_stream_input_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */
     108             : {
     109           3 :         efree(stream->abstract);
     110             : 
     111           3 :         return 0;
     112             : }
     113             : /* }}} */
     114             : 
     115           3 : static int php_stream_input_flush(php_stream *stream TSRMLS_DC) /* {{{ */
     116             : {
     117           3 :         return -1;
     118             : }
     119             : /* }}} */
     120             : 
     121             : php_stream_ops php_stream_input_ops = {
     122             :         php_stream_input_write,
     123             :         php_stream_input_read,
     124             :         php_stream_input_close,
     125             :         php_stream_input_flush,
     126             :         "Input",
     127             :         NULL, /* seek */
     128             :         NULL, /* cast */
     129             :         NULL, /* stat */
     130             :         NULL  /* set_option */
     131             : };
     132             : 
     133           1 : static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, int read_chain, int write_chain TSRMLS_DC) /* {{{ */
     134             : {
     135             :         char *p, *token;
     136             :         php_stream_filter *temp_filter;
     137             : 
     138           1 :         p = php_strtok_r(filterlist, "|", &token);
     139           6 :         while (p) {
     140           4 :                 php_url_decode(p, strlen(p));
     141           4 :                 if (read_chain) {
     142           4 :                         if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream) TSRMLS_CC))) {
     143           4 :                                 php_stream_filter_append(&stream->readfilters, temp_filter);
     144             :                         } else {
     145           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create filter (%s)", p);
     146             :                         }
     147             :                 }
     148           4 :                 if (write_chain) {
     149           0 :                         if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream) TSRMLS_CC))) {
     150           0 :                                 php_stream_filter_append(&stream->writefilters, temp_filter);
     151             :                         } else {
     152           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create filter (%s)", p);
     153             :                         }
     154             :                 }
     155           4 :                 p = php_strtok_r(NULL, "|", &token);
     156             :         }
     157           1 : }
     158             : /* }}} */
     159             : 
     160       56875 : php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */
     161             : {
     162       56875 :         int fd = -1;
     163       56875 :         int mode_rw = 0;
     164       56875 :         php_stream * stream = NULL;
     165             :         char *p, *token, *pathdup;
     166             :         long max_memory;
     167       56875 :         FILE *file = NULL;
     168             : 
     169       56875 :         if (!strncasecmp(path, "php://", 6)) {
     170       56875 :                 path += 6;
     171             :         }
     172             : 
     173       56875 :         if (!strncasecmp(path, "temp", 4)) {
     174          15 :                 path += 4;
     175          15 :                 max_memory = PHP_STREAM_MAX_MEM;
     176          15 :                 if (!strncasecmp(path, "/maxmemory:", 11)) {
     177           1 :                         path += 11;
     178           1 :                         max_memory = strtol(path, NULL, 10);
     179           1 :                         if (max_memory < 0) {
     180           0 :                                 php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Max memory must be >= 0");
     181           0 :                                 return NULL;
     182             :                         }
     183             :                 }
     184          15 :                 if (strpbrk(mode, "wa+")) {
     185          13 :                         mode_rw = TEMP_STREAM_DEFAULT;
     186             :                 } else {
     187           2 :                         mode_rw = TEMP_STREAM_READONLY;
     188             :                 }
     189          15 :                 return php_stream_temp_create(mode_rw, max_memory);
     190             :         }
     191             : 
     192       56860 :         if (!strcasecmp(path, "memory")) {
     193          39 :                 if (strpbrk(mode, "wa+")) {
     194          37 :                         mode_rw = TEMP_STREAM_DEFAULT;
     195             :                 } else {
     196           2 :                         mode_rw = TEMP_STREAM_READONLY;
     197             :                 }
     198          39 :                 return php_stream_memory_create(mode_rw);
     199             :         }
     200             : 
     201       56821 :         if (!strcasecmp(path, "output")) {
     202           1 :                 return php_stream_alloc(&php_stream_output_ops, NULL, 0, "wb");
     203             :         }
     204             : 
     205       56820 :         if (!strcasecmp(path, "input")) {
     206           3 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     207           0 :                         if (options & REPORT_ERRORS) {
     208           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration");
     209             :                         }
     210           0 :                         return NULL;
     211             :                 }
     212           3 :                 return php_stream_alloc(&php_stream_input_ops, ecalloc(1, sizeof(off_t)), 0, "rb");
     213             :         }
     214             : 
     215       56817 :         if (!strcasecmp(path, "stdin")) {
     216       18936 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     217           0 :                         if (options & REPORT_ERRORS) {
     218           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration");
     219             :                         }
     220           0 :                         return NULL;
     221             :                 }
     222       18936 :                 if (!strcmp(sapi_module.name, "cli")) {
     223             :                         static int cli_in = 0;
     224       18936 :                         fd = STDIN_FILENO;
     225       18936 :                         if (cli_in) {
     226           3 :                                 fd = dup(fd);
     227             :                         } else {
     228       18933 :                                 cli_in = 1;
     229       18933 :                                 file = stdin;
     230             :                         }
     231             :                 } else {
     232           0 :                         fd = dup(STDIN_FILENO);
     233             :                 }
     234       37881 :         } else if (!strcasecmp(path, "stdout")) {
     235       18940 :                 if (!strcmp(sapi_module.name, "cli")) {
     236             :                         static int cli_out = 0;
     237       18940 :                         fd = STDOUT_FILENO;
     238       18940 :                         if (cli_out++) {
     239           7 :                                 fd = dup(fd);
     240             :                         } else {
     241       18933 :                                 cli_out = 1;
     242       18933 :                                 file = stdout;
     243             :                         }
     244             :                 } else {
     245           0 :                         fd = dup(STDOUT_FILENO);
     246             :                 }
     247       18941 :         } else if (!strcasecmp(path, "stderr")) {
     248       18933 :                 if (!strcmp(sapi_module.name, "cli")) {
     249             :                         static int cli_err = 0;
     250       18933 :                         fd = STDERR_FILENO;
     251       18933 :                         if (cli_err++) {
     252           0 :                                 fd = dup(fd);
     253             :                         } else {
     254       18933 :                                 cli_err = 1;
     255       18933 :                                 file = stderr;
     256             :                         }
     257             :                 } else {
     258           0 :                         fd = dup(STDERR_FILENO);
     259             :                 }
     260           8 :         } else if (!strncasecmp(path, "fd/", 3)) {
     261             :                 char       *start,
     262             :                                    *end;
     263             :                 long       fildes_ori;
     264             :                 int                dtablesize;
     265             : 
     266           6 :                 if (strcmp(sapi_module.name, "cli")) {
     267           0 :                         if (options & REPORT_ERRORS) {
     268           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Direct access to file descriptors is only available from command-line PHP");
     269             :                         }
     270           0 :                         return NULL;
     271             :                 }
     272             : 
     273           6 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     274           0 :                         if (options & REPORT_ERRORS) {
     275           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration");
     276             :                         }
     277           0 :                         return NULL;
     278             :                 }
     279             : 
     280           6 :                 start = &path[3];
     281           6 :                 fildes_ori = strtol(start, &end, 10);
     282           6 :                 if (end == start || *end != '\0') {
     283           2 :                         php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
     284             :                                 "php://fd/ stream must be specified in the form php://fd/<orig fd>");
     285           2 :                         return NULL;
     286             :                 }
     287             : 
     288             : #if HAVE_UNISTD_H
     289           4 :                 dtablesize = getdtablesize();
     290             : #else
     291             :                 dtablesize = INT_MAX;
     292             : #endif
     293             : 
     294           4 :                 if (fildes_ori < 0 || fildes_ori >= dtablesize) {
     295           1 :                         php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
     296             :                                 "The file descriptors must be non-negative numbers smaller than %d", dtablesize);
     297           1 :                         return NULL;
     298             :                 }
     299             :                 
     300           3 :                 fd = dup(fildes_ori);
     301           3 :                 if (fd == -1) {
     302           1 :                         php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
     303             :                                 "Error duping file descriptor %ld; possibly it doesn't exist: "
     304             :                                 "[%d]: %s", fildes_ori, errno, strerror(errno));
     305           1 :                         return NULL;
     306             :                 }
     307           2 :         } else if (!strncasecmp(path, "filter/", 7)) {
     308             :                 /* Save time/memory when chain isn't specified */
     309           1 :                 if (strchr(mode, 'r') || strchr(mode, '+')) {
     310           1 :                         mode_rw |= PHP_STREAM_FILTER_READ;
     311             :                 }
     312           1 :                 if (strchr(mode, 'w') || strchr(mode, '+') || strchr(mode, 'a')) {
     313           0 :                         mode_rw |= PHP_STREAM_FILTER_WRITE;
     314             :                 }
     315           1 :                 pathdup = estrndup(path + 6, strlen(path + 6));
     316           1 :                 p = strstr(pathdup, "/resource=");
     317           1 :                 if (!p) {
     318           0 :                         php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "No URL resource specified");
     319           0 :                         efree(pathdup);
     320           0 :                         return NULL;
     321             :                 }
     322           1 :                 if (!(stream = php_stream_open_wrapper(p + 10, mode, options, opened_path))) {
     323           0 :                         efree(pathdup);
     324           0 :                         return NULL;
     325             :                 }
     326             : 
     327           1 :                 *p = '\0';
     328             : 
     329           1 :                 p = php_strtok_r(pathdup + 1, "/", &token);
     330           3 :                 while (p) {
     331           1 :                         if (!strncasecmp(p, "read=", 5)) {
     332           1 :                                 php_stream_apply_filter_list(stream, p + 5, 1, 0 TSRMLS_CC);
     333           0 :                         } else if (!strncasecmp(p, "write=", 6)) {
     334           0 :                                 php_stream_apply_filter_list(stream, p + 6, 0, 1 TSRMLS_CC);
     335             :                         } else {
     336           0 :                                 php_stream_apply_filter_list(stream, p, mode_rw & PHP_STREAM_FILTER_READ, mode_rw & PHP_STREAM_FILTER_WRITE TSRMLS_CC);
     337             :                         }
     338           1 :                         p = php_strtok_r(NULL, "/", &token);
     339             :                 }
     340           1 :                 efree(pathdup);
     341             : 
     342           1 :                 return stream;
     343             :         } else {
     344             :                 /* invalid php://thingy */
     345           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid php:// URL specified");
     346           1 :                 return NULL;
     347             :         }
     348             : 
     349             :         /* must be stdin, stderr or stdout */
     350       56811 :         if (fd == -1)   {
     351             :                 /* failed to dup */
     352           0 :                 return NULL;
     353             :         }
     354             : 
     355             : #if defined(S_IFSOCK) && !defined(WIN32) && !defined(__BEOS__)
     356             :         do {
     357             :                 struct stat st;
     358       56811 :                 memset(&st, 0, sizeof(st));
     359       56811 :                 if (fstat(fd, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) {
     360           0 :                         stream = php_stream_sock_open_from_socket(fd, NULL);
     361           0 :                         if (stream) {
     362           0 :                                 stream->ops = &php_stream_socket_ops;
     363           0 :                                 return stream;
     364             :                         }
     365             :                 }
     366             :         } while (0);
     367             : #endif
     368             : 
     369       56811 :         if (file) {
     370       56799 :                 stream = php_stream_fopen_from_file(file, mode);
     371             :         } else {
     372          12 :                 stream = php_stream_fopen_from_fd(fd, mode, NULL);
     373          12 :                 if (stream == NULL) {
     374           0 :                         close(fd);
     375             :                 }
     376             :         }
     377             : 
     378       56811 :         return stream;
     379             : }
     380             : /* }}} */
     381             : 
     382             : static php_stream_wrapper_ops php_stdio_wops = {
     383             :         php_stream_url_wrap_php,
     384             :         NULL, /* close */
     385             :         NULL, /* fstat */
     386             :         NULL, /* stat */
     387             :         NULL, /* opendir */
     388             :         "PHP",
     389             :         NULL, /* unlink */
     390             :         NULL, /* rename */
     391             :         NULL, /* mkdir */
     392             :         NULL  /* rmdir */
     393             : };
     394             : 
     395             : php_stream_wrapper php_stream_php_wrapper =     {
     396             :         &php_stdio_wops,
     397             :         NULL,
     398             :         0, /* is_url */
     399             : };
     400             : 
     401             : 
     402             : /*
     403             :  * Local variables:
     404             :  * tab-width: 4
     405             :  * c-basic-offset: 4
     406             :  * End:
     407             :  * vim600: sw=4 ts=4 fdm=marker
     408             :  * vim<600: sw=4 ts=4
     409             :  */

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:37 +0000 (5 days ago)

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