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/zip - zip_stream.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 114 135 84.4 %
Date: 2014-12-13 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       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: Piere-Alain Joye <pierre@php.net>                            |
      16             :   +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : /* $Id$ */
      20             : #ifdef HAVE_CONFIG_H
      21             : #   include "config.h"
      22             : #endif
      23             : #include "php.h"
      24             : #if HAVE_ZIP
      25             : #if defined(ZEND_ENGINE_2) || defined(ZEND_ENGINE_3)
      26             : 
      27             : #include "php_streams.h"
      28             : #include "ext/standard/file.h"
      29             : #include "ext/standard/php_string.h"
      30             : #include "fopen_wrappers.h"
      31             : #include "php_zip.h"
      32             : 
      33             : #include "ext/standard/url.h"
      34             : 
      35             : struct php_zip_stream_data_t {
      36             :         struct zip *za;
      37             :         struct zip_file *zf;
      38             :         size_t cursor;
      39             :         php_stream *stream;
      40             : };
      41             : 
      42             : #define STREAM_DATA_FROM_STREAM() \
      43             :         struct php_zip_stream_data_t *self = (struct php_zip_stream_data_t *) stream->abstract;
      44             : 
      45             : 
      46             : /* {{{ php_zip_ops_read */
      47         117 : static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
      48             : {
      49         117 :         ssize_t n = 0;
      50         117 :         STREAM_DATA_FROM_STREAM();
      51             : 
      52         117 :         if (self->za && self->zf) {
      53         117 :                 n = zip_fread(self->zf, buf, count);
      54         117 :                 if (n < 0) {
      55             :                         int ze, se;
      56           1 :                         zip_file_error_get(self->zf, &ze, &se);
      57           1 :                         stream->eof = 1;
      58           1 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zip stream error: %s", zip_file_strerror(self->zf));
      59           1 :                         return 0;
      60             :                 }
      61             :                 /* cast count to signed value to avoid possibly negative n
      62             :                  * being cast to unsigned value */
      63         125 :                 if (n == 0 || n < (ssize_t)count) {
      64           9 :                         stream->eof = 1;
      65             :                 } else {
      66         107 :                         self->cursor += n;
      67             :                 }
      68             :         }
      69         116 :         return (n < 1 ? 0 : (size_t)n);
      70             : }
      71             : /* }}} */
      72             : 
      73             : /* {{{ php_zip_ops_write */
      74           0 : static size_t php_zip_ops_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
      75             : {
      76           0 :         if (!stream) {
      77           0 :                 return 0;
      78             :         }
      79             : 
      80           0 :         return count;
      81             : }
      82             : /* }}} */
      83             : 
      84             : /* {{{ php_zip_ops_close */
      85           9 : static int php_zip_ops_close(php_stream *stream, int close_handle TSRMLS_DC)
      86             : {
      87           9 :         STREAM_DATA_FROM_STREAM();
      88           9 :         if (close_handle) {
      89           9 :                 if (self->zf) {
      90           9 :                         zip_fclose(self->zf);
      91           9 :                         self->zf = NULL;
      92             :                 }
      93             : 
      94           9 :                 if (self->za) {
      95           9 :                         zip_close(self->za);
      96           9 :                         self->za = NULL;
      97             :                 }
      98             :         }
      99           9 :         efree(self);
     100           9 :         stream->abstract = NULL;
     101           9 :         return EOF;
     102             : }
     103             : /* }}} */
     104             : 
     105             : /* {{{ php_zip_ops_flush */
     106          10 : static int php_zip_ops_flush(php_stream *stream TSRMLS_DC)
     107             : {
     108          10 :         if (!stream) {
     109           0 :                 return 0;
     110             :         }
     111             : 
     112          10 :         return 0;
     113             : }
     114             : /* }}} */
     115             : 
     116           5 : static int php_zip_ops_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) /* {{{ */
     117             : {
     118             :         struct zip_stat sb;
     119           5 :         const char *path = stream->orig_path;
     120           5 :         int path_len = strlen(stream->orig_path);
     121             :         char file_dirname[MAXPATHLEN];
     122             :         struct zip *za;
     123             :         char *fragment;
     124             :         int fragment_len;
     125             :         int err;
     126             :         zend_string *file_basename;
     127             : 
     128           5 :         fragment = strchr(path, '#');
     129           5 :         if (!fragment) {
     130           1 :                 return -1;
     131             :         }
     132             : 
     133             : 
     134           4 :         if (strncasecmp("zip://", path, 6) == 0) {
     135           4 :                 path += 6;
     136             :         }
     137             : 
     138           4 :         fragment_len = strlen(fragment);
     139             : 
     140           4 :         if (fragment_len < 1) {
     141           0 :                 return -1;
     142             :         }
     143           4 :         path_len = strlen(path);
     144           4 :         if (path_len >= MAXPATHLEN) {
     145           0 :                 return -1;
     146             :         }
     147             : 
     148           4 :         memcpy(file_dirname, path, path_len - fragment_len);
     149           4 :         file_dirname[path_len - fragment_len] = '\0';
     150             : 
     151           4 :         file_basename = php_basename((char *)path, path_len - fragment_len, NULL, 0 TSRMLS_CC);
     152           4 :         fragment++;
     153             : 
     154           4 :         if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname)) {
     155             :                 zend_string_release(file_basename);
     156           0 :                 return -1;
     157             :         }
     158             : 
     159           4 :         za = zip_open(file_dirname, ZIP_CREATE, &err);
     160           4 :         if (za) {
     161           4 :                 memset(ssb, 0, sizeof(php_stream_statbuf));
     162           4 :                 if (zip_stat(za, fragment, ZIP_FL_NOCASE, &sb) != 0) {
     163             :                         zend_string_release(file_basename);
     164           0 :                         return -1;
     165             :                 }
     166           4 :                 zip_close(za);
     167             : 
     168           4 :                 if (path[path_len-1] != '/') {
     169           3 :                         ssb->sb.st_size = sb.size;
     170           3 :                         ssb->sb.st_mode |= S_IFREG; /* regular file */
     171             :                 } else {
     172           1 :                         ssb->sb.st_size = 0;
     173           1 :                         ssb->sb.st_mode |= S_IFDIR; /* regular directory */
     174             :                 }
     175             : 
     176           4 :                 ssb->sb.st_mtime = sb.mtime;
     177           4 :                 ssb->sb.st_atime = sb.mtime;
     178           4 :                 ssb->sb.st_ctime = sb.mtime;
     179           4 :                 ssb->sb.st_nlink = 1;
     180           4 :                 ssb->sb.st_rdev = -1;
     181             : #ifndef PHP_WIN32
     182           4 :                 ssb->sb.st_blksize = -1;
     183           4 :                 ssb->sb.st_blocks = -1;
     184             : #endif
     185           4 :                 ssb->sb.st_ino = -1;
     186             :         }
     187             :         zend_string_release(file_basename);
     188           4 :         return 0;
     189             : }
     190             : /* }}} */
     191             : 
     192             : php_stream_ops php_stream_zipio_ops = {
     193             :         php_zip_ops_write, php_zip_ops_read,
     194             :         php_zip_ops_close, php_zip_ops_flush,
     195             :         "zip",
     196             :         NULL, /* seek */
     197             :         NULL, /* cast */
     198             :         php_zip_ops_stat, /* stat */
     199             :         NULL  /* set_option */
     200             : };
     201             : 
     202             : /* {{{ php_stream_zip_open */
     203           4 : php_stream *php_stream_zip_open(const char *filename, const char *path, const char *mode STREAMS_DC TSRMLS_DC)
     204             : {
     205           4 :         struct zip_file *zf = NULL;
     206           4 :         int err = 0;
     207             : 
     208           4 :         php_stream *stream = NULL;
     209             :         struct php_zip_stream_data_t *self;
     210             :         struct zip *stream_za;
     211             : 
     212           4 :         if (strncmp(mode,"r", strlen("r")) != 0) {
     213           0 :                 return NULL;
     214             :         }
     215             : 
     216           4 :         if (filename) {
     217           4 :                 if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
     218           0 :                         return NULL;
     219             :                 }
     220             : 
     221             :                 /* duplicate to make the stream za independent (esp. for MSHUTDOWN) */
     222           4 :                 stream_za = zip_open(filename, ZIP_CREATE, &err);
     223           4 :                 if (!stream_za) {
     224           0 :                         return NULL;
     225             :                 }
     226             : 
     227           4 :                 zf = zip_fopen(stream_za, path, 0);
     228           4 :                 if (zf) {
     229           4 :                         self = emalloc(sizeof(*self));
     230             : 
     231           4 :                         self->za = stream_za;
     232           4 :                         self->zf = zf; 
     233           4 :                         self->stream = NULL;
     234           4 :                         self->cursor = 0;
     235           4 :                         stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode);
     236           4 :                         stream->orig_path = estrdup(path);
     237             :                 } else {
     238           0 :                         zip_close(stream_za);
     239             :                 }
     240             :         }
     241             : 
     242           4 :         if (!stream) {
     243           0 :                 return NULL;
     244             :         } else {
     245           4 :                 return stream;
     246             :         }
     247             : 
     248             : }
     249             : /* }}} */
     250             : 
     251             : /* {{{ php_stream_zip_opener */
     252           5 : php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper,
     253             :                                                                                         const char *path,
     254             :                                                                                         const char *mode,
     255             :                                                                                         int options,
     256             :                                                                                         char **opened_path,
     257             :                                                                                         php_stream_context *context STREAMS_DC TSRMLS_DC)
     258             : {
     259             :         int path_len;
     260             : 
     261             :         zend_string *file_basename;
     262             :         char file_dirname[MAXPATHLEN];
     263             : 
     264             :         struct zip *za;
     265           5 :         struct zip_file *zf = NULL;
     266             :         char *fragment;
     267             :         int fragment_len;
     268             :         int err;
     269             : 
     270           5 :         php_stream *stream = NULL;
     271             :         struct php_zip_stream_data_t *self;
     272             : 
     273           5 :         fragment = strchr(path, '#');
     274           5 :         if (!fragment) {
     275           0 :                 return NULL;
     276             :         }
     277             : 
     278           5 :         if (strncasecmp("zip://", path, 6) == 0) {
     279           5 :                 path += 6;
     280             :         }
     281             : 
     282           5 :         fragment_len = strlen(fragment);
     283             : 
     284           5 :         if (fragment_len < 1) {
     285           0 :                 return NULL;
     286             :         }
     287           5 :         path_len = strlen(path);
     288           5 :         if (path_len >= MAXPATHLEN || mode[0] != 'r') {
     289           0 :                 return NULL;
     290             :         }
     291             : 
     292           5 :         memcpy(file_dirname, path, path_len - fragment_len);
     293           5 :         file_dirname[path_len - fragment_len] = '\0';
     294             : 
     295           5 :         file_basename = php_basename(path, path_len - fragment_len, NULL, 0 TSRMLS_CC);
     296           5 :         fragment++;
     297             : 
     298           5 :         if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname)) {
     299             :                 zend_string_release(file_basename);
     300           0 :                 return NULL;
     301             :         }
     302             : 
     303           5 :         za = zip_open(file_dirname, ZIP_CREATE, &err);
     304           5 :         if (za) {
     305           5 :                 zf = zip_fopen(za, fragment, 0);
     306           5 :                 if (zf) {
     307           5 :                         self = emalloc(sizeof(*self));
     308             : 
     309           5 :                         self->za = za;
     310           5 :                         self->zf = zf; 
     311           5 :                         self->stream = NULL;
     312           5 :                         self->cursor = 0;
     313           5 :                         stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode);
     314             : 
     315           5 :                         if (opened_path) {
     316           0 :                                 *opened_path = estrdup(path);
     317             :                         }
     318             :                 } else {
     319           0 :                         zip_close(za);
     320             :                 }
     321             :         }
     322             : 
     323             :         zend_string_release(file_basename);
     324             : 
     325           5 :         if (!stream) {
     326           0 :                 return NULL;
     327             :         } else {
     328           5 :                 return stream;
     329             :         }
     330             : }
     331             : /* }}} */
     332             : 
     333             : static php_stream_wrapper_ops zip_stream_wops = {
     334             :         php_stream_zip_opener,
     335             :         NULL,   /* close */
     336             :         NULL,   /* fstat */
     337             :         NULL,   /* stat */
     338             :         NULL,   /* opendir */
     339             :         "zip wrapper",
     340             :         NULL,   /* unlink */
     341             :         NULL,   /* rename */
     342             :         NULL,   /* mkdir */
     343             :         NULL    /* rmdir */
     344             : };
     345             : 
     346             : php_stream_wrapper php_stream_zip_wrapper = {
     347             :         &zip_stream_wops,
     348             :         NULL,
     349             :         0 /* is_url */
     350             : };
     351             : #endif /* defined(ZEND_ENGINE_2) || defined(ZEND_ENGINE_3) */
     352             : #endif /* HAVE_ZIP */

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:25 +0000 (8 days ago)

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