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 178 72.5 %
Date: 2014-04-06 Functions: 7 10 70.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             :    | 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             : typedef struct php_stream_input { /* {{{ */
      67             :         php_stream **body_ptr;
      68             :         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 TSRMLS_DC) /* {{{ */
      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 TSRMLS_DC) /* {{{ */
      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) < input->position + count) {
      84             :                 /* read requested data from SAPI */
      85           7 :                 int read_bytes = sapi_read_post_block(buf, count TSRMLS_CC);
      86             : 
      87           7 :                 if (read_bytes > 0) {
      88           7 :                         php_stream_seek(*input->body_ptr, 0, SEEK_END);
      89           7 :                         php_stream_write(*input->body_ptr, buf, read_bytes);
      90             :                 }
      91             :         }
      92             : 
      93          34 :         php_stream_seek(*input->body_ptr, input->position, SEEK_SET);
      94          34 :         read = php_stream_read(*input->body_ptr, 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 TSRMLS_DC) /* {{{ */
     107             : {
     108          17 :         efree(stream->abstract);
     109          17 :         stream->abstract = NULL;
     110             : 
     111          17 :         return 0;
     112             : }
     113             : /* }}} */
     114             : 
     115          17 : static int php_stream_input_flush(php_stream *stream TSRMLS_DC) /* {{{ */
     116             : {
     117          17 :         return -1;
     118             : }
     119             : /* }}} */
     120             : 
     121           0 : static int php_stream_input_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC) /* {{{ */
     122             : {
     123           0 :         php_stream_input_t *input = stream->abstract;
     124             : 
     125           0 :         if (*input->body_ptr) {
     126           0 :                 int sought = php_stream_seek(*input->body_ptr, offset, whence);
     127           0 :                 *newoffset = (*input->body_ptr)->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 TSRMLS_DC) /* {{{ */
     148             : {
     149             :         char *p, *token;
     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) TSRMLS_CC))) {
     157           4 :                                 php_stream_filter_append(&stream->readfilters, temp_filter);
     158             :                         } else {
     159           0 :                                 php_error_docref(NULL TSRMLS_CC, 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) TSRMLS_CC))) {
     164           0 :                                 php_stream_filter_append(&stream->writefilters, temp_filter);
     165             :                         } else {
     166           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create filter (%s)", p);
     167             :                         }
     168             :                 }
     169           4 :                 p = php_strtok_r(NULL, "|", &token);
     170             :         }
     171           1 : }
     172             : /* }}} */
     173             : 
     174       62104 : php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *path, const char *mode, int options,
     175             :                                                                          char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */
     176             : {
     177       62104 :         int fd = -1;
     178       62104 :         int mode_rw = 0;
     179       62104 :         php_stream * stream = NULL;
     180             :         char *p, *token, *pathdup;
     181             :         long max_memory;
     182       62104 :         FILE *file = NULL;
     183             : 
     184       62104 :         if (!strncasecmp(path, "php://", 6)) {
     185       62104 :                 path += 6;
     186             :         }
     187             : 
     188       62104 :         if (!strncasecmp(path, "temp", 4)) {
     189          24 :                 path += 4;
     190          24 :                 max_memory = PHP_STREAM_MAX_MEM;
     191          24 :                 if (!strncasecmp(path, "/maxmemory:", 11)) {
     192           1 :                         path += 11;
     193           1 :                         max_memory = strtol(path, NULL, 10);
     194           1 :                         if (max_memory < 0) {
     195           0 :                                 php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Max memory must be >= 0");
     196           0 :                                 return NULL;
     197             :                         }
     198             :                 }
     199          24 :                 if (strpbrk(mode, "wa+")) {
     200          22 :                         mode_rw = TEMP_STREAM_DEFAULT;
     201             :                 } else {
     202           2 :                         mode_rw = TEMP_STREAM_READONLY;
     203             :                 }
     204          24 :                 return php_stream_temp_create(mode_rw, max_memory);
     205             :         }
     206             : 
     207       62080 :         if (!strcasecmp(path, "memory")) {
     208          37 :                 if (strpbrk(mode, "wa+")) {
     209          35 :                         mode_rw = TEMP_STREAM_DEFAULT;
     210             :                 } else {
     211           2 :                         mode_rw = TEMP_STREAM_READONLY;
     212             :                 }
     213          37 :                 return php_stream_memory_create(mode_rw);
     214             :         }
     215             : 
     216       62043 :         if (!strcasecmp(path, "output")) {
     217           1 :                 return php_stream_alloc(&php_stream_output_ops, NULL, 0, "wb");
     218             :         }
     219             : 
     220       62042 :         if (!strcasecmp(path, "input")) {
     221             :                 php_stream_input_t *input;
     222             : 
     223          17 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     224           0 :                         if (options & REPORT_ERRORS) {
     225           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration");
     226             :                         }
     227           0 :                         return NULL;
     228             :                 }
     229             : 
     230          17 :                 input = ecalloc(1, sizeof(*input));
     231          17 :                 if (*(input->body_ptr = &SG(request_info).request_body)) {
     232          10 :                         php_stream_rewind(*input->body_ptr);
     233             :                 } else {
     234           7 :                         *input->body_ptr = php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE);
     235             :                 }
     236             : 
     237          17 :                 return php_stream_alloc(&php_stream_input_ops, input, 0, "rb");
     238             :         }
     239             : 
     240       62025 :         if (!strcasecmp(path, "stdin")) {
     241       20672 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     242           0 :                         if (options & REPORT_ERRORS) {
     243           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration");
     244             :                         }
     245           0 :                         return NULL;
     246             :                 }
     247       20672 :                 if (!strcmp(sapi_module.name, "cli")) {
     248             :                         static int cli_in = 0;
     249       20672 :                         fd = STDIN_FILENO;
     250       20672 :                         if (cli_in) {
     251           3 :                                 fd = dup(fd);
     252             :                         } else {
     253       20669 :                                 cli_in = 1;
     254       20669 :                                 file = stdin;
     255             :                         }
     256             :                 } else {
     257           0 :                         fd = dup(STDIN_FILENO);
     258             :                 }
     259       41353 :         } else if (!strcasecmp(path, "stdout")) {
     260       20676 :                 if (!strcmp(sapi_module.name, "cli")) {
     261             :                         static int cli_out = 0;
     262       20676 :                         fd = STDOUT_FILENO;
     263       20676 :                         if (cli_out++) {
     264           7 :                                 fd = dup(fd);
     265             :                         } else {
     266       20669 :                                 cli_out = 1;
     267       20669 :                                 file = stdout;
     268             :                         }
     269             :                 } else {
     270           0 :                         fd = dup(STDOUT_FILENO);
     271             :                 }
     272       20677 :         } else if (!strcasecmp(path, "stderr")) {
     273       20669 :                 if (!strcmp(sapi_module.name, "cli")) {
     274             :                         static int cli_err = 0;
     275       20669 :                         fd = STDERR_FILENO;
     276       20669 :                         if (cli_err++) {
     277           0 :                                 fd = dup(fd);
     278             :                         } else {
     279       20669 :                                 cli_err = 1;
     280       20669 :                                 file = stderr;
     281             :                         }
     282             :                 } else {
     283           0 :                         fd = dup(STDERR_FILENO);
     284             :                 }
     285           8 :         } else if (!strncasecmp(path, "fd/", 3)) {
     286             :                 const char *start;
     287             :                 char       *end;
     288             :                 long       fildes_ori;
     289             :                 int                dtablesize;
     290             : 
     291           6 :                 if (strcmp(sapi_module.name, "cli")) {
     292           0 :                         if (options & REPORT_ERRORS) {
     293           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Direct access to file descriptors is only available from command-line PHP");
     294             :                         }
     295           0 :                         return NULL;
     296             :                 }
     297             : 
     298           6 :                 if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) {
     299           0 :                         if (options & REPORT_ERRORS) {
     300           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration");
     301             :                         }
     302           0 :                         return NULL;
     303             :                 }
     304             : 
     305           6 :                 start = &path[3];
     306           6 :                 fildes_ori = strtol(start, &end, 10);
     307           6 :                 if (end == start || *end != '\0') {
     308           2 :                         php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
     309             :                                 "php://fd/ stream must be specified in the form php://fd/<orig fd>");
     310           2 :                         return NULL;
     311             :                 }
     312             : 
     313             : #if HAVE_UNISTD_H
     314           4 :                 dtablesize = getdtablesize();
     315             : #else
     316             :                 dtablesize = INT_MAX;
     317             : #endif
     318             : 
     319           4 :                 if (fildes_ori < 0 || fildes_ori >= dtablesize) {
     320           1 :                         php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
     321             :                                 "The file descriptors must be non-negative numbers smaller than %d", dtablesize);
     322           1 :                         return NULL;
     323             :                 }
     324             :                 
     325           3 :                 fd = dup(fildes_ori);
     326           3 :                 if (fd == -1) {
     327           1 :                         php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
     328             :                                 "Error duping file descriptor %ld; possibly it doesn't exist: "
     329             :                                 "[%d]: %s", fildes_ori, errno, strerror(errno));
     330           1 :                         return NULL;
     331             :                 }
     332           2 :         } else if (!strncasecmp(path, "filter/", 7)) {
     333             :                 /* Save time/memory when chain isn't specified */
     334           1 :                 if (strchr(mode, 'r') || strchr(mode, '+')) {
     335           1 :                         mode_rw |= PHP_STREAM_FILTER_READ;
     336             :                 }
     337           1 :                 if (strchr(mode, 'w') || strchr(mode, '+') || strchr(mode, 'a')) {
     338           0 :                         mode_rw |= PHP_STREAM_FILTER_WRITE;
     339             :                 }
     340           1 :                 pathdup = estrndup(path + 6, strlen(path + 6));
     341           1 :                 p = strstr(pathdup, "/resource=");
     342           1 :                 if (!p) {
     343           0 :                         php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "No URL resource specified");
     344           0 :                         efree(pathdup);
     345           0 :                         return NULL;
     346             :                 }
     347           1 :                 if (!(stream = php_stream_open_wrapper(p + 10, mode, options, opened_path))) {
     348           0 :                         efree(pathdup);
     349           0 :                         return NULL;
     350             :                 }
     351             : 
     352           1 :                 *p = '\0';
     353             : 
     354           1 :                 p = php_strtok_r(pathdup + 1, "/", &token);
     355           3 :                 while (p) {
     356           1 :                         if (!strncasecmp(p, "read=", 5)) {
     357           1 :                                 php_stream_apply_filter_list(stream, p + 5, 1, 0 TSRMLS_CC);
     358           0 :                         } else if (!strncasecmp(p, "write=", 6)) {
     359           0 :                                 php_stream_apply_filter_list(stream, p + 6, 0, 1 TSRMLS_CC);
     360             :                         } else {
     361           0 :                                 php_stream_apply_filter_list(stream, p, mode_rw & PHP_STREAM_FILTER_READ, mode_rw & PHP_STREAM_FILTER_WRITE TSRMLS_CC);
     362             :                         }
     363           1 :                         p = php_strtok_r(NULL, "/", &token);
     364             :                 }
     365           1 :                 efree(pathdup);
     366             : 
     367           1 :                 return stream;
     368             :         } else {
     369             :                 /* invalid php://thingy */
     370           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid php:// URL specified");
     371           1 :                 return NULL;
     372             :         }
     373             : 
     374             :         /* must be stdin, stderr or stdout */
     375       62019 :         if (fd == -1)   {
     376             :                 /* failed to dup */
     377           0 :                 return NULL;
     378             :         }
     379             : 
     380             : #if defined(S_IFSOCK) && !defined(WIN32) && !defined(__BEOS__)
     381             :         do {
     382             :                 struct stat st;
     383       62019 :                 memset(&st, 0, sizeof(st));
     384       62019 :                 if (fstat(fd, &st) == 0 && (st.st_mode & S_IFMT) == S_IFSOCK) {
     385           0 :                         stream = php_stream_sock_open_from_socket(fd, NULL);
     386           0 :                         if (stream) {
     387           0 :                                 stream->ops = &php_stream_socket_ops;
     388           0 :                                 return stream;
     389             :                         }
     390             :                 }
     391             :         } while (0);
     392             : #endif
     393             : 
     394       62019 :         if (file) {
     395       62007 :                 stream = php_stream_fopen_from_file(file, mode);
     396             :         } else {
     397          12 :                 stream = php_stream_fopen_from_fd(fd, mode, NULL);
     398          12 :                 if (stream == NULL) {
     399           0 :                         close(fd);
     400             :                 }
     401             :         }
     402             : 
     403       62019 :         return stream;
     404             : }
     405             : /* }}} */
     406             : 
     407             : static php_stream_wrapper_ops php_stdio_wops = {
     408             :         php_stream_url_wrap_php,
     409             :         NULL, /* close */
     410             :         NULL, /* fstat */
     411             :         NULL, /* stat */
     412             :         NULL, /* opendir */
     413             :         "PHP",
     414             :         NULL, /* unlink */
     415             :         NULL, /* rename */
     416             :         NULL, /* mkdir */
     417             :         NULL  /* rmdir */
     418             : };
     419             : 
     420             : php_stream_wrapper php_stream_php_wrapper =     {
     421             :         &php_stdio_wops,
     422             :         NULL,
     423             :         0, /* is_url */
     424             : };
     425             : 
     426             : 
     427             : /*
     428             :  * Local variables:
     429             :  * tab-width: 4
     430             :  * c-basic-offset: 4
     431             :  * End:
     432             :  * vim600: sw=4 ts=4 fdm=marker
     433             :  * vim<600: sw=4 ts=4
     434             :  */

Generated by: LCOV version 1.10

Generated at Sun, 06 Apr 2014 17:31:11 +0000 (9 days ago)

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