]> granicus.if.org Git - php/commitdiff
- PHP_VERSION_ID exists only in newer PHPs (5.1+)
authorMarcus Boerger <helly@php.net>
Sun, 4 Feb 2007 20:10:03 +0000 (20:10 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 4 Feb 2007 20:10:03 +0000 (20:10 +0000)
- Improve error checking

ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/phar_path_check.c
ext/phar/phar_path_check.re
ext/phar/tests/phar_offset_get_error.phpt [new file with mode: 0755]

index ec248f9e6e0b5e2aa6b7de9f94cbae0b43508e07..670891ea61edf4d78c8b734628da213e6c2fa312 100644 (file)
@@ -235,14 +235,22 @@ static int phar_get_archive(phar_archive_data **archive, char *fname, int fname_
 /**
  * retrieve information on a file contained within a phar, or null if it ain't there
  */
-phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len TSRMLS_DC) /* {{{ */
+phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len, char **error TSRMLS_DC) /* {{{ */
 {
+       const char *pcr_error;
        phar_entry_info *entry;
 
-       if (path && *path == '/') {
-               path++;
-               path_len--;
+       if (error) {
+               *error = NULL;
+       }
+
+       if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
+               if (error) {
+                       spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
+               }
+               return NULL;
        }
+
        if (!&phar->manifest.arBuckets) {
                return NULL;
        }
@@ -257,7 +265,7 @@ phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int pa
 }
 /* }}} */
 
-#if PHP_VERSION_ID < 50202
+#if defined(PHP_VERSION_ID) && PHP_VERSION_ID < 50202
 typedef struct {
        char        *data;
        size_t      fpos;
@@ -297,7 +305,7 @@ static int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len
        if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error TSRMLS_CC)) {
                return FAILURE;
        }
-       if ((entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC)) == NULL) {
+       if ((entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) ? NULL : error TSRMLS_CC)) == NULL) {
                if (for_create && !PHAR_G(readonly)) {
                        return SUCCESS;
                }
@@ -328,7 +336,9 @@ static int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len
        if (entry->fp) {
                /* make a copy */
                if (for_trunc) {
-#if PHP_VERSION_ID < 50202
+#if PHP_VERSION_ID >= 50202
+                       php_stream_truncate_set_size(entry->fp, 0);
+#else
                        if (php_stream_is(entry->fp, PHP_STREAM_IS_TEMP)) {
                                if (php_stream_is(*(php_stream**)entry->fp->abstract, PHP_STREAM_IS_MEMORY)) {
                                        php_stream *inner = *(php_stream**)entry->fp->abstract;
@@ -355,8 +365,6 @@ static int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len
                                }
                                return FAILURE;
                        }
-#else
-                       php_stream_truncate_set_size(entry->fp, 0);
 #endif
                        entry->is_modified = 1;
                        phar->is_modified = 1;
@@ -434,16 +442,8 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
        phar_archive_data *phar;
        phar_entry_info *entry, etemp;
        phar_entry_data *ret;
-       phar_path_check_result res;
        const char *pcr_error;
 
-       if ((res = phar_path_check(path, &path_len, &pcr_error)) > pcr_is_ok) {
-               if (error) {
-                       spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
-               }
-               return NULL;
-       }
-
        if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error TSRMLS_CC)) {
                return NULL;
        }
@@ -454,6 +454,13 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
                return ret;
        }
 
+       if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
+               if (error) {
+                       spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
+               }
+               return NULL;
+       }
+
        /* create a new phar data holder */
        ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
 
@@ -471,7 +478,11 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
        etemp.phar = phar;
        zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), NULL);
        /* retrieve the phar manifest copy */
-       entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC);
+       entry = phar_get_entry_info(phar, path, path_len, error TSRMLS_CC);
+       
+       if (!entry) {
+               //return NULL;
+       }
 
        phar->refcount++;
        ret->phar = phar;
index 8bbb4ee7f81aee6a2011135b25d89b6f3423d51f..a172686f6353c1381a80418d7d3f2b594819cdd0 100755 (executable)
@@ -252,7 +252,7 @@ static int    phar_dir_stat( php_stream *stream, php_stream_statbuf *ssb TSRMLS_
 int phar_archive_delref(phar_archive_data *phar TSRMLS_DC);
 int phar_entry_delref(phar_entry_data *idata TSRMLS_DC);
 
-phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len TSRMLS_DC);
+phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len, char **error TSRMLS_DC);
 phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char **error TSRMLS_DC);
 int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC);
 int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len TSRMLS_DC);
@@ -268,7 +268,7 @@ typedef enum {
        pcr_err_empty_entry
 } phar_path_check_result;
 
-phar_path_check_result phar_path_check(const char *p, int *len, const char **error);
+phar_path_check_result phar_path_check(char **p, int *len, const char **error);
 
 END_EXTERN_C()
 
index f3c78d61dabbdb9a72ab7f4108a9c205bfbc00df..21dd3653898453aa901df1690329c8d11bedc2d3 100755 (executable)
@@ -520,7 +520,7 @@ PHP_METHOD(Phar, offsetExists)
  */
 PHP_METHOD(Phar, offsetGet)
 {
-       char *fname;
+       char *fname, *error;
        int fname_len;
        zval *zfname;
        PHAR_ARCHIVE_OBJECT();
@@ -529,8 +529,8 @@ PHP_METHOD(Phar, offsetGet)
                return;
        }
        
-       if (!phar_get_entry_info(phar_obj->arc.archive, fname, fname_len TSRMLS_CC)) {
-               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist", fname);
+       if (!phar_get_entry_info(phar_obj->arc.archive, fname, fname_len, &error TSRMLS_CC)) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist%s%s", fname, error?", ":"", error?error:"");
        } else {
                fname_len = spprintf(&fname, 0, "phar://%s/%s", phar_obj->arc.archive->fname, fname);
                MAKE_STD_ZVAL(zfname);
@@ -769,10 +769,10 @@ PHP_METHOD(PharFileInfo, __construct)
                return;
        }
 
-       if ((entry_info = phar_get_entry_info(phar_data, entry, entry_len TSRMLS_CC)) == NULL) {
+       if ((entry_info = phar_get_entry_info(phar_data, entry, entry_len, &error TSRMLS_CC)) == NULL) {
                efree(arch);
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
-                       "Cannot access phar file entry '%s' in archive '%s'", entry, arch);
+                       "Cannot access phar file entry '%s' in archive '%s'%s%s", entry, arch, error?", ":"", error?error:"");
                efree(entry);
                return;
        }
index fba3a5bd329c9c155f32164b8ff0e0d1a57c240b..50c3a46e05afb1e00a9fb30ae6bc42e2742185d8 100755 (executable)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.11.0 on Sun Feb  4 11:21:09 2007 */
+/* Generated by re2c 0.11.0 on Sun Feb  4 14:40:54 2007 */
 #line 1 "ext/phar/phar_path_check.re"
 /*
   +----------------------------------------------------------------------+
@@ -22,9 +22,9 @@
 
 #include "phar_internal.h"
 
-phar_path_check_result phar_path_check(const char *s, int *len, const char **error)
+phar_path_check_result phar_path_check(char **s, int *len, const char **error)
 {
-       const unsigned char *p = (const unsigned char*)s;
+       const unsigned char *p = (const unsigned char*)*s;
        const unsigned char *m;
 #define YYCTYPE         unsigned char
 #define YYCURSOR        p
@@ -69,7 +69,7 @@ yy3:
                if(yych <= '.') goto yy16;
                if(yych <= '/') goto yy17;
 yy4:
-#line 77 "ext/phar/phar_path_check.re"
+#line 78 "ext/phar/phar_path_check.re"
                {
                        goto loop;
                }
@@ -94,10 +94,10 @@ yy9:
                ++YYCURSOR;
 #line 62 "ext/phar/phar_path_check.re"
                {
-                       if (*s == '/') {
-                               s++;
+                       if (**s == '/') {
+                               (*s)++;
                        }
-                       *len = (p - (const unsigned char*)s) -1;
+                       *len = (p - (const unsigned char*)*s) -1;
                        *error = NULL;
                        return pcr_use_query;
                }
@@ -106,13 +106,14 @@ yy11:
                ++YYCURSOR;
 #line 70 "ext/phar/phar_path_check.re"
                {
-                       if (*s == '/') {
-                               s++;
+                       if (**s == '/') {
+                               (*s)++;
+                               (*len)--;
                        }
                        *error = NULL;
                        return pcr_is_ok;
                }
-#line 116 "ext/phar/phar_path_check.c"
+#line 117 "ext/phar/phar_path_check.c"
 yy13:
                yych = *++YYCURSOR;
                goto yy4;
@@ -123,7 +124,7 @@ yy14:
                        *error = "empty entry";
                        return pcr_err_empty_entry;
                }
-#line 127 "ext/phar/phar_path_check.c"
+#line 128 "ext/phar/phar_path_check.c"
 yy16:
                yych = *++YYCURSOR;
                if(yych <= 0x00) goto yy20;
@@ -138,7 +139,7 @@ yy17:
                        *error = "double slash";
                        return pcr_err_double_slash;
                }
-#line 142 "ext/phar/phar_path_check.c"
+#line 143 "ext/phar/phar_path_check.c"
 yy19:
                yych = *++YYCURSOR;
                if(yych <= 0x00) goto yy22;
@@ -151,7 +152,7 @@ yy20:
                        *error = "current directory reference";
                        return pcr_err_curr_dir;
                }
-#line 155 "ext/phar/phar_path_check.c"
+#line 156 "ext/phar/phar_path_check.c"
 yy22:
                ++YYCURSOR;
 #line 42 "ext/phar/phar_path_check.re"
@@ -159,9 +160,9 @@ yy22:
                        *error = "upper directory reference";
                        return pcr_err_up_dir;
                }
-#line 163 "ext/phar/phar_path_check.c"
+#line 164 "ext/phar/phar_path_check.c"
        }
 }
-#line 80 "ext/phar/phar_path_check.re"
+#line 81 "ext/phar/phar_path_check.re"
 
 }
index 9f1e7efda3c35f1d85c0aba2b4f4146100a61fbc..1caac5c108d2eac2781c05d8c5f940f727e8635d 100755 (executable)
@@ -20,9 +20,9 @@
 
 #include "phar_internal.h"
 
-phar_path_check_result phar_path_check(const char *s, int *len, const char **error)
+phar_path_check_result phar_path_check(char **s, int *len, const char **error)
 {
-       const unsigned char *p = (const unsigned char*)s;
+       const unsigned char *p = (const unsigned char*)*s;
        const unsigned char *m;
 #define YYCTYPE         unsigned char
 #define YYCURSOR        p
@@ -60,16 +60,17 @@ ANY = .;
                        return pcr_err_star;
                }
 "?"    {
-                       if (*s == '/') {
-                               s++;
+                       if (**s == '/') {
+                               (*s)++;
                        }
-                       *len = (p - (const unsigned char*)s) -1;
+                       *len = (p - (const unsigned char*)*s) -1;
                        *error = NULL;
                        return pcr_use_query;
                }
 END {
-                       if (*s == '/') {
-                               s++;
+                       if (**s == '/') {
+                               (*s)++;
+                               (*len)--;
                        }
                        *error = NULL;
                        return pcr_is_ok;
diff --git a/ext/phar/tests/phar_offset_get_error.phpt b/ext/phar/tests/phar_offset_get_error.phpt
new file mode 100755 (executable)
index 0000000..75d5e0a
--- /dev/null
@@ -0,0 +1,37 @@
+--TEST--
+Phar: ignore filenames starting with / on offsetSet
+--SKIPIF--
+<?php if (!extension_loaded("phar")) print "skip"; ?>
+<?php if (!extension_loaded("spl")) print "skip SPL not available"; ?>
+--INI--
+phar.readonly=0
+phar.require_hash=1
+--FILE--
+<?php
+
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://'.$fname;
+$iname = '/file.txt';
+$ename = '/error/';
+
+$p = new Phar($fname);
+$p[$iname] = "foobar\n";
+
+try
+{
+       $p[$ename] = "foobar\n";
+}
+catch(Exception $e)
+{
+       echo $e->getMessage() . "\n";
+}
+
+include($pname . $iname);
+?>
+===DONE===
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECT--
+Entry /error/ does not exist and cannot be created: phar error: invalid path "/error/" contains empty entry
+foobar
+===DONE===