cellog          Tue Apr 15 03:36:56 2008 UTC

  Added files:                 
    /pecl/phar/tests    readfile.phpt 

  Modified files:              
    /pecl/phar  func_interceptors.c phar_internal.h 
  Log:
  add interception for readfile [DOC]
  
http://cvs.php.net/viewvc.cgi/pecl/phar/func_interceptors.c?r1=1.14&r2=1.15&diff_format=u
Index: pecl/phar/func_interceptors.c
diff -u pecl/phar/func_interceptors.c:1.14 pecl/phar/func_interceptors.c:1.15
--- pecl/phar/func_interceptors.c:1.14  Mon Apr 14 17:31:00 2008
+++ pecl/phar/func_interceptors.c       Tue Apr 15 03:36:56 2008
@@ -16,7 +16,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: func_interceptors.c,v 1.14 2008/04/14 17:31:00 cellog Exp $ */
+/* $Id: func_interceptors.c,v 1.15 2008/04/15 03:36:56 cellog Exp $ */
 
 #include "phar_internal.h"
 
@@ -199,6 +199,83 @@
 }
 /* }}} */
 
+PHAR_FUNC(phar_readfile) /* {{{ */
+{
+       char *filename;
+       int filename_len;
+       int size = 0;
+       zend_bool use_include_path = 0;
+       zval *zcontext = NULL;
+       php_stream *stream;
+
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() 
TSRMLS_CC, "s|br!", &filename, &filename_len, &use_include_path, &zcontext) == 
FAILURE) {
+               goto skip_phar;
+       }
+       if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && 
!strstr(filename, "://"))) {
+               char *arch, *entry, *fname;
+               int arch_len, entry_len, fname_len;
+               php_stream_context *context = NULL;
+               char *name;
+               phar_archive_data **pphar;
+               fname = zend_get_executed_filename(TSRMLS_C);
+
+               if (strncasecmp(fname, "phar://", 7)) {
+                       goto skip_phar;
+               }
+               fname_len = strlen(fname);
+               if (FAILURE == phar_split_fname(fname, fname_len, &arch, 
&arch_len, &entry, &entry_len TSRMLS_CC)) {
+                       goto skip_phar;
+               }
+
+               efree(entry);
+               entry = filename;
+               /* fopen within phar, if :// is not in the url, then prepend 
phar://<archive>/ */
+               entry_len = filename_len;
+               /* retrieving a file defaults to within the current directory, 
so use this if possible */
+               if (FAILURE == (zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), 
arch, arch_len, (void **) &pphar))) {
+                       efree(arch);
+                       goto skip_phar;
+               }
+               if (use_include_path) {
+                       if (!(entry = phar_find_in_include_path(entry, 
entry_len, NULL TSRMLS_CC))) {
+                               /* this file is not in the phar, use the 
original path */
+                               efree(arch);
+                               goto skip_phar;
+                       } else {
+                               name = entry;
+                       }
+               } else {
+                       entry = phar_fix_filepath(estrndup(entry, entry_len), 
&entry_len, 1 TSRMLS_CC);
+                       if (!zend_hash_exists(&((*pphar)->manifest), entry + 1, 
entry_len - 1)) {
+                               /* this file is not in the phar, use the 
original path */
+                               efree(entry);
+                               efree(arch);
+                               goto skip_phar;
+                       }
+                       /* auto-convert to phar:// */
+                       spprintf(&name, 4096, "phar://%s%s", arch, entry);
+                       efree(entry);
+               }
+
+               efree(arch);
+               context = php_stream_context_from_zval(zcontext, 0);
+               stream = php_stream_open_wrapper_ex(name, "rb", 0 | 
REPORT_ERRORS, NULL, context);
+               efree(name);
+               if (stream == NULL) {
+                       RETURN_FALSE;
+               }
+               size = php_stream_passthru(stream);
+               php_stream_close(stream);
+               RETURN_LONG(size);
+       }
+
+skip_phar:
+       PHAR_G(orig_readfile)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+       return;
+
+}
+/* }}} */
+
 PHAR_FUNC(phar_fopen) /* {{{ */
 {
        char *filename, *mode;
@@ -878,6 +955,7 @@
        PHAR_INTERCEPT(is_executable);
        PHAR_INTERCEPT(lstat);
        PHAR_INTERCEPT(stat);
+       PHAR_INTERCEPT(readfile);
 }
 /* }}} */
 
@@ -912,6 +990,7 @@
        PHAR_RELEASE(is_executable);
        PHAR_RELEASE(lstat);
        PHAR_RELEASE(stat);
+       PHAR_RELEASE(readfile);
 }
 /* }}} */
 
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_internal.h?r1=1.100&r2=1.101&diff_format=u
Index: pecl/phar/phar_internal.h
diff -u pecl/phar/phar_internal.h:1.100 pecl/phar/phar_internal.h:1.101
--- pecl/phar/phar_internal.h:1.100     Mon Apr 14 04:47:33 2008
+++ pecl/phar/phar_internal.h   Tue Apr 15 03:36:56 2008
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_internal.h,v 1.100 2008/04/14 04:47:33 cellog Exp $ */
+/* $Id: phar_internal.h,v 1.101 2008/04/15 03:36:56 cellog Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -164,6 +164,7 @@
        void        (*orig_is_readable)(INTERNAL_FUNCTION_PARAMETERS);
        void        (*orig_is_executable)(INTERNAL_FUNCTION_PARAMETERS);
        void        (*orig_lstat)(INTERNAL_FUNCTION_PARAMETERS);
+       void        (*orig_readfile)(INTERNAL_FUNCTION_PARAMETERS);
        void        (*orig_stat)(INTERNAL_FUNCTION_PARAMETERS);
        /* used for includes with . in them inside front controller */
        char*       cwd;

http://cvs.php.net/viewvc.cgi/pecl/phar/tests/readfile.phpt?view=markup&rev=1.1
Index: pecl/phar/tests/readfile.phpt
+++ pecl/phar/tests/readfile.phpt
--TEST--
Phar: test readfile() interception
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip");?>
--INI--
phar.require_hash=1
phar.readonly=0
--FILE--
<?php
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$a = new Phar($fname);
$a['index.php'] = '<?php
readfile("dir/file1.txt");
readfile("file1.txt", true);
?>';
$a['dir/file1.txt'] = 'hi';
$a['dir/file2.txt'] = 'hi2';
$a['dir/file3.txt'] = 'hi3';
$a->setStub('<?php
Phar::interceptFileFuncs();
set_include_path("phar://" . __FILE__ . "/dir" . PATH_SEPARATOR . "phar://" . 
__FILE__);
include "index.php";
__HALT_COMPILER();');
include $fname;
?>
===DONE===
--CLEAN--
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . 
'.phar.php'); ?>
--EXPECT--
hihi===DONE===

Reply via email to