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: 129 180 71.7 %
Date: 2015-08-29 Functions: 6 10 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2015 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           9 : static size_t php_stream_output_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
      35             : {
      36           9 :         PHPWRITE(buf, count);
      37           9 :         return count;
      38             : }
      39             : /* }}} */
      40             : 
      41           0 : static size_t php_stream_output_read(php_stream *stream, char *buf, size_t count) /* {{{ */
      42             : {
      43           0 :         stream->eof = 1;
      44           0 :         return 0;
      45             : }
      46             : /* }}} */
      47             : 
      48           2 : static int php_stream_output_close(php_stream *stream, int close_handle) /* {{{ */
      49             : {
      50           2 :         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             : typedef struct php_stream_input { /* {{{ */
      67             :         php_stream *body;
      68             :         zend_off_t position;
      69             : } php_stream_input_t;
      70             : /* }}} */
      71             : 
      72           0 : static size_t php_stream_input_write(php_stream *stream, const char *buf, size_t count) /* {{{ */
      73             : {
      74           0 :         return -1;
      75             : }
      76             : /* }}} */
      77             : 
      78          34 : static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count) /* {{{ */
      79             : {
      80          34 :         php_stream_input_t *input = stream->abstract;
      81             :         size_t read;
      82             : 
      83          34 :         if (!SG(post_read) && SG(read_post_bytes) < (int64_t)(input->position + count)) {
      84             :                 /* read requested data from SAPI */
      85           7 :                 size_t read_bytes = sapi_read_post_block(buf, count);
      86             : 
      87           7 :                 if (read_bytes > 0) {
      88           7 :                         php_stream_seek(input->body, 0, SEEK_END);
      89           7 :                         php_stream_write(input->body, buf, read_bytes);
      90             :                 }
      91             :         }
      92             : 
      93          34 :         php_stream_seek(input->body, input->position, SEEK_SET);
      94          34 :         read = php_stream_read(input->body, buf, count);
      95             : 
      96          50 :         if (!read || read == (size_t) -1) {
      97          16 :                 stream->eof = 1;
      98             :         } else {
      99          18 :                 input->position += read;
     100             :         }
     101             : 
     102          34 :         return read;
     103             : }
     104             : /* }}} */
     105             : 
     106          17 : static int php_stream_input_close(php_stream *stream, int close_handle) /* {{{ */
     107             : {
     108          17 :         efree(stream->abstract);
     109          17 :         stream->abstract = NULL;
     110             : 
     111          17 :         return 0;
     112             : }
     113             : /* }}} */
     114             : 
     115           0 : static int php_stream_input_flush(php_stream *stream) /* {{{ */
     116             : {
     117           0 :         return -1;
     118             : }
     119             : /* }}} */
     120             : 
     121           0 : static int php_stream_input_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) /* {{{ */
     122             : {
     123           0 :         php_stream_input_t *input = stream->abstract;
     124             : 
     125           0 :         if (input->body) {
     126           0 :                 int sought = php_stream_seek(input->body, offset, whence);
     127           0 :                 *newoffset = (input->body)->position;
     128           0 :                 return sought;
     129             :         }
     130             : 
     131           0 :         return -1;
     132             : }
     133             : /* }}} */
     134             : 
     135             : php_stream_ops php_stream_input_ops = {
     136             :         php_stream_input_write,
     137             :         php_stream_input_read,
     138             :         php_stream_input_close,
     139             :         php_stream_input_flush,
     140             :         "Input",
     141             :         php_stream_input_seek,
     142             :         NULL, /* cast */
     143             :         NULL, /* stat */
     144             :         NULL  /* set_option */
     145             : };
     146             : 
     147           1 : static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, int read_chain, int write_chain) /* {{{ */
     148             : {
     149           1 :         char *p, *token = NULL;
     150             :         php_stream_filter *temp_filter;
     151             : 
     152           1 :         p = php_strtok_r(filterlist, "|", &token);
     153           6 :         while (p) {
     154           4 :                 php_url_decode(p, strlen(p));
     155           4 :                 if (read_chain) {
     156           4 :                         if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream)))) {
     157           4 :                                 php_stream_filter_append(&stream->readfilters, temp_filter);
     158             :                         } else {
     159           0 :                                 php_error_docref(NULL, E_WARNING, "Unable to create filter (%s)", p);
     160             :                         }
     161             :                 }
     162           4 :                 if (write_chain) {
     163           0 :                         if ((temp_filter = php_stream_filter_create(p, NULL, php_stream_is_persistent(stream)))) {
     164           0 :                                 php_stream_filter_append(&stream->writefilters, temp_filter);
     165             :                         } else {
     166           0 :                                 php_error_docref(NULL, E_WARNING, "Unable to create filter (%s)", p);
     167             :                         }
     168             :                 }
     169           4 :                 p = php_strtok_r(NULL, "|", &token);
     170             :         }
     171           1 : }
     172             : /* }}} */
     173             : 
     174       62552 : php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *path, const char *mode, int options,
     175             :                                                                          zend_string **opened_path, php_stream_context *context STREAMS_DC) /* {{{ */
     176             : {
     177       62552 :         int fd = -1;
     178       62552 :         int mode_rw = 0;
     179       62552 :         php_stream * stream = NULL;
     180             :         char *p, *token, *pathdup;
     181             :         zend_long max_memory;
     182       62552 :         FILE *file = NULL;
     183             : #ifdef PHP_WIN32
     184             :         int pipe_requested = 0;
     185             : #endif
     186             : 
     187       62552 :         if (!strncasecmp(path, "php://", 6)) {
     188       62552 :                 path += 6;
     189             :         }
     190             : 
     191       62552 :         if (!strncasecmp(path, "temp", 4)) {
     192          26 :                 path += 4;
     193          26 :                 max_memory = PHP_STREAM_MAX_MEM;
     194          26 :                 if (!strncasecmp(path, "/maxmemory:", 11)) {
     195           1 :                         path += 11;
     196           1 :                         max_memory = ZEND_STRTOL(path, NULL, 10);
     197           1 :                         if (max_memory < 0) {
     198           0 :                                 php_error_docref(NULL, E_RECOVERABLE_ERROR, "Max memory must be >= 0");
     199           0 :                                 return NULL;
     200             :                         }
     201             :                 }
     202          26 :                 if (strpbrk(mode, "wa+")) {
     203          24 :                         mode_rw = TEMP_STREAM_DEFAULT;
     204             :                 } else {
     205           2 :                         mode_rw = TEMP_STREAM_READONLY;
     206             :                 }
     207          26 :                 return php_stream_temp_create(mode_rw, max_memory);
     208             :         }
     209             : 
     210       62526 :         if (!strcasecmp(path, "memory")) {
     211          37 :                 if (strpbrk(mode, "wa+")) {
     212          35 :                         mode_rw = TEMP_STREAM_DEFAULT;
     213             :                 } else {
     214           2 :                         mode_rw = TEMP_STREAM_READONLY;
     215             :                 }
     216          37 :                 return php_stream_memory_create(mode_rw);
     217             :         }
     218             : 
     219       62489 :         if (!strcasecmp(path, "output")) {
     220           2 :                 return php_stream_alloc(&php_stream_output_ops, NULL, 0, "wb");
     221             :         }
     222             : 
     223       62487 :         if (!strcasecmp(path, "input")) {
     224             :                 php_stream_input_t *input;
     225             : 
     226          17 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     227           0 :                         if (options & REPORT_ERRORS) {
     228           0 :                                 php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration");
     229             :                         }
     230           0 :                         return NULL;
     231             :                 }
     232             : 
     233          17 :                 input = ecalloc(1, sizeof(*input));
     234          17 :                 if ((input->body = SG(request_info).request_body)) {
     235          10 :                         php_stream_rewind(input->body);
     236             :                 } else {
     237           7 :                         input->body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
     238           7 :                         SG(request_info).request_body = input->body;
     239             :                 }
     240             : 
     241          17 :                 return php_stream_alloc(&php_stream_input_ops, input, 0, "rb");
     242             :         }
     243             : 
     244       62470 :         if (!strcasecmp(path, "stdin")) {
     245       20822 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     246           0 :                         if (options & REPORT_ERRORS) {
     247           0 :                                 php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration");
     248             :                         }
     249           0 :                         return NULL;
     250             :                 }
     251       20822 :                 if (!strcmp(sapi_module.name, "cli")) {
     252             :                         static int cli_in = 0;
     253       20822 :                         fd = STDIN_FILENO;
     254       20822 :                         if (cli_in) {
     255           6 :                                 fd = dup(fd);
     256             :                         } else {
     257       20816 :                                 cli_in = 1;
     258       20816 :                                 file = stdin;
     259             :                         }
     260             :                 } else {
     261           0 :                         fd = dup(STDIN_FILENO);
     262             :                 }
     263             : #ifdef PHP_WIN32
     264             :                 pipe_requested = 1;
     265             : #endif
     266       41648 :         } else if (!strcasecmp(path, "stdout")) {
     267       20824 :                 if (!strcmp(sapi_module.name, "cli")) {
     268             :                         static int cli_out = 0;
     269       20824 :                         fd = STDOUT_FILENO;
     270       20824 :                         if (cli_out++) {
     271           8 :                                 fd = dup(fd);
     272             :                         } else {
     273       20816 :                                 cli_out = 1;
     274       20816 :                                 file = stdout;
     275             :                         }
     276             :                 } else {
     277           0 :                         fd = dup(STDOUT_FILENO);
     278             :                 }
     279             : #ifdef PHP_WIN32
     280             :                 pipe_requested = 1;
     281             : #endif
     282       20824 :         } else if (!strcasecmp(path, "stderr")) {
     283       20816 :                 if (!strcmp(sapi_module.name, "cli")) {
     284             :                         static int cli_err = 0;
     285       20816 :                         fd = STDERR_FILENO;
     286       20816 :                         if (cli_err++) {
     287           0 :                                 fd = dup(fd);
     288             :                         } else {
     289       20816 :                                 cli_err = 1;
     290       20816 :                                 file = stderr;
     291             :                         }
     292             :                 } else {
     293           0 :                         fd = dup(STDERR_FILENO);
     294             :                 }
     295             : #ifdef PHP_WIN32
     296             :                 pipe_requested = 1;
     297             : #endif
     298           8 :         } else if (!strncasecmp(path, "fd/", 3)) {
     299             :                 const char *start;
     300             :                 char       *end;
     301             :                 zend_long  fildes_ori;
     302             :                 int                dtablesize;
     303             : 
     304           6 :                 if (strcmp(sapi_module.name, "cli")) {
     305           0 :                         if (options & REPORT_ERRORS) {
     306           0 :                                 php_error_docref(NULL, E_WARNING, "Direct access to file descriptors is only available from command-line PHP");
     307             :                         }
     308           0 :                         return NULL;
     309             :                 }
     310             : 
     311           6 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     312           0 :                         if (options & REPORT_ERRORS) {
     313           0 :                                 php_error_docref(NULL, E_WARNING, "URL file-access is disabled in the server configuration");
     314             :                         }
     315           0 :                         return NULL;
     316             :                 }
     317             : 
     318           6 :                 start = &path[3];
     319           6 :                 fildes_ori = ZEND_STRTOL(start, &end, 10);
     320           6 :                 if (end == start || *end != '\0') {
     321           2 :                         php_stream_wrapper_log_error(wrapper, options,
     322             :                                 "php://fd/ stream must be specified in the form php://fd/<orig fd>");
     323           2 :                         return NULL;
     324             :                 }
     325             : 
     326             : #if HAVE_UNISTD_H
     327           4 :                 dtablesize = getdtablesize();
     328             : #else
     329             :                 dtablesize = INT_MAX;
     330             : #endif
     331             : 
     332           4 :                 if (fildes_ori < 0 || fildes_ori >= dtablesize) {
     333           1 :                         php_stream_wrapper_log_error(wrapper, options,
     334             :                                 "The file descriptors must be non-negative numbers smaller than %d", dtablesize);
     335           1 :                         return NULL;
     336             :                 }
     337             : 
     338           3 :                 fd = dup((int)fildes_ori);
     339           3 :                 if (fd == -1) {
     340           1 :                         php_stream_wrapper_log_error(wrapper, options,
     341             :                                 "Error duping file descriptor " ZEND_LONG_FMT "; possibly it doesn't exist: "
     342             :                                 "[%d]: %s", fildes_ori, errno, strerror(errno));
     343           1 :                         return NULL;
     344             :                 }
     345           2 :         } else if (!strncasecmp(path, "filter/", 7)) {
     346             :                 /* Save time/memory when chain isn't specified */
     347           1 :                 if (strchr(mode, 'r') || strchr(mode, '+')) {
     348           1 :                         mode_rw |= PHP_STREAM_FILTER_READ;
     349             :                 }
     350           1 :                 if (strchr(mode, 'w') || strchr(mode, '+') || strchr(mode, 'a')) {
     351           0 :                         mode_rw |= PHP_STREAM_FILTER_WRITE;
     352             :                 }
     353           1 :                 pathdup = estrndup(path + 6, strlen(path + 6));
     354           1 :                 p = strstr(pathdup, "/resource=");
     355           1 :                 if (!p) {
     356           0 :                         php_error_docref(NULL, E_RECOVERABLE_ERROR, "No URL resource specified");
     357           0 :                         efree(pathdup);
     358           0 :                         return NULL;
     359             :                 }
     360             : 
     361           1 :                 if (!(stream = php_stream_open_wrapper(p + 10, mode, options, opened_path))) {
     362           0 :                         efree(pathdup);
     363           0 :                         return NULL;
     364             :                 }
     365             : 
     366           1 :                 *p = '\0';
     367             : 
     368           1 :                 p = php_strtok_r(pathdup + 1, "/", &token);
     369           3 :                 while (p) {
     370           1 :                         if (!strncasecmp(p, "read=", 5)) {
     371           1 :                                 php_stream_apply_filter_list(stream, p + 5, 1, 0);
     372           0 :                         } else if (!strncasecmp(p, "write=", 6)) {
     373           0 :                                 php_stream_apply_filter_list(stream, p + 6, 0, 1);
     374             :                         } else {
     375           0 :                                 php_stream_apply_filter_list(stream, p, mode_rw & PHP_STREAM_FILTER_READ, mode_rw & PHP_STREAM_FILTER_WRITE);
     376             :                         }
     377           1 :                         p = php_strtok_r(NULL, "/", &token);
     378             :                 }
     379           1 :                 efree(pathdup);
     380             : 
     381           1 :                 return stream;
     382             :         } else {
     383             :                 /* invalid php://thingy */
     384           1 :                 php_error_docref(NULL, E_WARNING, "Invalid php:// URL specified");
     385           1 :                 return NULL;
     386             :         }
     387             : 
     388             :         /* must be stdin, stderr or stdout */
     389       62464 :         if (fd == -1)   {
     390             :                 /* failed to dup */
     391           0 :                 return NULL;
     392             :         }
     393             : 
     394             : #if defined(S_IFSOCK) && !defined(WIN32) && !defined(__BEOS__)
     395             :         do {
     396             :                 zend_stat_t st;
     397       62464 :                 memset(&st, 0, sizeof(st));
     398       62464 :                 if (zend_fstat(fd, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) {
     399           0 :                         stream = php_stream_sock_open_from_socket(fd, NULL);
     400           0 :                         if (stream) {
     401           0 :                                 stream->ops = &php_stream_socket_ops;
     402           0 :                                 return stream;
     403             :                         }
     404             :                 }
     405             :         } while (0);
     406             : #endif
     407             : 
     408       62464 :         if (file) {
     409       62448 :                 stream = php_stream_fopen_from_file(file, mode);
     410             :         } else {
     411          16 :                 stream = php_stream_fopen_from_fd(fd, mode, NULL);
     412          16 :                 if (stream == NULL) {
     413           0 :                         close(fd);
     414             :                 }
     415             :         }
     416             : 
     417             : #ifdef PHP_WIN32
     418             :         if (pipe_requested && stream && context) {
     419             :                 zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking");
     420             :                 if (blocking_pipes) {
     421             :                         convert_to_long(blocking_pipes);
     422             :                         php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, Z_LVAL_P(blocking_pipes), NULL);
     423             :                 }
     424             :         }
     425             : #endif
     426       62464 :         return stream;
     427             : }
     428             : /* }}} */
     429             : 
     430             : static php_stream_wrapper_ops php_stdio_wops = {
     431             :         php_stream_url_wrap_php,
     432             :         NULL, /* close */
     433             :         NULL, /* fstat */
     434             :         NULL, /* stat */
     435             :         NULL, /* opendir */
     436             :         "PHP",
     437             :         NULL, /* unlink */
     438             :         NULL, /* rename */
     439             :         NULL, /* mkdir */
     440             :         NULL  /* rmdir */
     441             : };
     442             : 
     443             : PHPAPI php_stream_wrapper php_stream_php_wrapper =      {
     444             :         &php_stdio_wops,
     445             :         NULL,
     446             :         0, /* is_url */
     447             : };
     448             : 
     449             : 
     450             : /*
     451             :  * Local variables:
     452             :  * tab-width: 4
     453             :  * c-basic-offset: 4
     454             :  * End:
     455             :  * vim600: sw=4 ts=4 fdm=marker
     456             :  * vim<600: sw=4 ts=4
     457             :  */

Generated by: LCOV version 1.10

Generated at Sat, 29 Aug 2015 10:22:25 +0000 (2 days ago)

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