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: 116 140 82.9 %
Date: 2014-04-10 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Thu, 10 Apr 2014 08:54:00 +0000 (7 days ago)

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