]> granicus.if.org Git - php/commitdiff
add rmdir() support, add rmdir to dir test
authorGreg Beaver <cellog@php.net>
Wed, 9 Jan 2008 03:47:22 +0000 (03:47 +0000)
committerGreg Beaver <cellog@php.net>
Wed, 9 Jan 2008 03:47:22 +0000 (03:47 +0000)
fix *extremely* ancient problem where phar_wrapper_stat always returned success indicating the file existed
rename phar_destroy_manifest to phar_destroy_manifest_entry

ext/phar/dirstream.c
ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/stream.c
ext/phar/tar.c
ext/phar/tests/dir.phpt
ext/phar/zip.c

index d52eb7ca39311ee24e5a68807b286ce464661143..3b20144b058429b4d9926d9ebe5f27d7aa503e53 100644 (file)
@@ -549,13 +549,16 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
 
        /* now for the easy part */
        entry->is_deleted = 1;
+       entry->is_modified = 1;
        phar_flush(phar, 0, 0, &error TSRMLS_CC);
        if (error) {
                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", %s", entry->filename, phar->fname, error);
                zend_hash_del(&phar->manifest, entry->filename, entry->filename_len);
+               php_url_free(resource);
                efree(error);
                return FAILURE;
        }
+       php_url_free(resource);
        return SUCCESS;
 }
 /* }}} */
index 04b89080685c28f8545a1a57477981a1375c1cff..157b6b0fcb721b9867a736ec9b63e46f39315694 100644 (file)
@@ -279,7 +279,7 @@ static void destroy_phar_data(void *pDest) /* {{{ */
 /**
  * destructor for the manifest hash, frees each file's entry
  */
-void destroy_phar_manifest(void *pDest) /* {{{ */
+void destroy_phar_manifest_entry(void *pDest) /* {{{ */
 {
        phar_entry_info *entry = (phar_entry_info *)pDest;
        TSRMLS_FETCH();
@@ -1312,7 +1312,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
 
        /* set up our manifest */
        zend_hash_init(&mydata->manifest, sizeof(phar_entry_info),
-               zend_get_hash_value, destroy_phar_manifest, 0);
+               zend_get_hash_value, destroy_phar_manifest_entry, 0);
        offset = 0;
        for (manifest_index = 0; manifest_index < manifest_count; manifest_index++) {
                if (buffer + 4 > endbuffer) {
@@ -1542,7 +1542,7 @@ int phar_create_or_parse_filename(char *fname, int fname_len, char *alias, int a
                *pphar = mydata;
        }
        zend_hash_init(&mydata->manifest, sizeof(phar_entry_info),
-               zend_get_hash_value, destroy_phar_manifest, 0);
+               zend_get_hash_value, destroy_phar_manifest_entry, 0);
        mydata->fname_len = fname_len;
        mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len);
        mydata->alias_len = alias ? alias_len : fname_len;
@@ -2464,7 +2464,8 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
                        entry->metadata_str.len = 0;
                }
 
-               offset += 4 + entry->filename_len + sizeof(entry_buffer) + entry->metadata_str.len;
+               /* 32 bits for filename length, length of filename, manifest + metadata, and add 1 for trailing / if a directory */
+               offset += 4 + entry->filename_len + sizeof(entry_buffer) + entry->metadata_str.len + (entry->is_dir ? 1 : 0);
 
                /* compress and rehash as necessary */
                if (oldfile && !entry->is_modified) {
@@ -2655,7 +2656,12 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
                        /* remove this from the new phar */
                        continue;
                }
-               phar_set_32(entry_buffer, entry->filename_len);
+               if (entry->is_dir) {
+                       /* add 1 for trailing slash */
+                       phar_set_32(entry_buffer, entry->filename_len + 1);
+               } else {
+                       phar_set_32(entry_buffer, entry->filename_len);
+               }
                if (4 != php_stream_write(newfile, entry_buffer, 4)
                || entry->filename_len != php_stream_write(newfile, entry->filename, entry->filename_len)) {
                        if (closeoldfile) {
@@ -2673,7 +2679,7 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
                        }
                        php_stream_close(newfile);
                        if (error) {
-                               spprintf(error, 0, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", entry->filename, archive->fname);
+                               spprintf(error, 0, "unable to write filename of directory \"%s\" to manifest of new phar \"%s\"", entry->filename, archive->fname);
                        }
                        return EOF;
                }
index 2b7c7b185c2fb149cc710f7d6b0305d83f4c7f95..0b168ac0406f6198234fb28c8522e959d62a9713 100755 (executable)
@@ -307,7 +307,7 @@ int phar_open_loaded(char *fname, int fname_len, char *alias, int alias_len, int
 phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp,
                                      char **error, int for_write TSRMLS_DC);
 int phar_parse_metadata(char **buffer, zval **metadata, int is_zip TSRMLS_DC);
-void destroy_phar_manifest(void *pDest);
+void destroy_phar_manifest_entry(void *pDest);
 
 /* tar functions in tar.c */
 int phar_is_tar(char *buf);
index 52c8442e5bdacd58a19cf2597bf0ac75a304f662..41b51f11f75418dbc2ccab11e6078d020321659a 100644 (file)
@@ -559,20 +559,20 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
        int retval;
 
        if ((resource = phar_open_url(wrapper, url, "r", flags TSRMLS_CC)) == NULL) {
-               return -1;
+               return FAILURE;
        }
 
        /* we must have at the very least phar://alias.phar/internalfile.php */
        if (!resource->scheme || !resource->host || !resource->path) {
                php_url_free(resource);
                php_stream_wrapper_log_error(wrapper, flags TSRMLS_CC, "phar error: invalid url \"%s\"", url);
-               return -1;
+               return FAILURE;
        }
 
        if (strcasecmp("phar", resource->scheme)) {
                php_url_free(resource);
                php_stream_wrapper_log_error(wrapper, flags TSRMLS_CC, "phar error: not a phar url \"%s\"", url);
-               return -1;
+               return FAILURE;
        }
 
        host_len = strlen(resource->host);
@@ -581,7 +581,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
                spprintf(&internal_file, 0, "%s%s", plain_map, resource->path);
                retval = php_stream_stat_path_ex(internal_file, flags, ssb, context);
                if (retval == -1) {
-                       php_stream_wrapper_log_error(wrapper, 0/* TODO:options */ TSRMLS_CC, "phar error: file \"%s\" extracted from \"%s\" could not be opened", internal_file, resource->host);
+                       php_stream_wrapper_log_error(wrapper, 0/* TODO:options */ TSRMLS_CC, "phar error: file \"%s\" extracted from \"%s\" could not be stated", internal_file, resource->host);
                }
                php_url_free(resource);
                efree(internal_file);
@@ -596,7 +596,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
                        php_stream_wrapper_log_error(wrapper, flags TSRMLS_CC, error);
                        efree(error);
                }
-               return 0;
+               return SUCCESS;
        }
        if (error) {
                efree(error);
@@ -605,15 +605,17 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
                /* root directory requested */
                phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC);
                php_url_free(resource);
-               return 0;
+               return SUCCESS;
        }
        if (!phar->manifest.arBuckets) {
                php_url_free(resource);
-               return 0;
+               return SUCCESS;
        }
        /* search through the manifest of files, and if we have an exact match, it's a file */
        if (SUCCESS == zend_hash_find(&phar->manifest, internal_file, strlen(internal_file), (void**)&entry)) {
                phar_dostat(phar, entry, ssb, 0, phar->alias, phar->alias_len TSRMLS_CC);
+               php_url_free(resource);
+               return SUCCESS;
        } else {
                /* search for directory (partial match of a file) */
                zend_hash_internal_pointer_reset(&phar->manifest);
@@ -625,7 +627,8 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
                                        /* directory found, all dirs have the same stat */
                                        if (key[strlen(internal_file)] == '/') {
                                                phar_dostat(phar, NULL, ssb, 1, phar->alias, phar->alias_len TSRMLS_CC);
-                                               break;
+                                               php_url_free(resource);
+                                               return SUCCESS;
                                        }
                                }
                        }
@@ -636,7 +639,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
        }
 
        php_url_free(resource);
-       return 0;
+       return FAILURE;
 }
 /* }}} */
 
index b8594a4e6d532800aa54424e3b2f1b0a036df5ae..d2249b22ea066aff05797b57ddfcda8be359c836 100644 (file)
@@ -170,7 +170,7 @@ int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, i
 
        myphar = (phar_archive_data *) ecalloc(1, sizeof(phar_archive_data));
        zend_hash_init(&myphar->manifest, sizeof(phar_entry_info),
-               zend_get_hash_value, destroy_phar_manifest, 0);
+               zend_get_hash_value, destroy_phar_manifest_entry, 0);
        myphar->is_tar = 1;
 
        entry.is_tar = 1;
index f642d6ddac098c5c8c5ca1e692829c1026bce4ac..c5d9078d25ff790d225cc434339944663771fe37 100644 (file)
@@ -1,5 +1,5 @@
 --TEST--
-Phar: mkdir test
+Phar: mkdir/rmdir test
 --SKIPIF--
 <?php if (!extension_loaded("phar")) die("skip"); ?>
 --INI--
@@ -9,17 +9,33 @@ phar.require_hash=0
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
 $pname = 'phar://' . $fname;
+$fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.1.phar.php';
+$pname2 = 'phar://' . $fname2;
+$fname3 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.2.phar.php';
+$pname3 = 'phar://' . $fname3;
 $phar = new Phar($fname);
 
 $phar['test/'] = '';
 var_dump($phar['test']->isDir());
 var_dump($phar['test/']->isDir());
+copy($fname, $fname2);
 mkdir($pname . '/another/dir/');
 var_dump($phar['another/dir']->isDir());
+rmdir($pname . '/another/dir/');
+copy($fname, $fname3);
+clearstatcache();
+var_dump(file_exists($pname . '/another/dir/'));
+var_dump(file_exists($pname2 . '/test/'));
+var_dump(file_exists($pname3 . '/another/dir/'));
 ?>
 --CLEAN--
 <?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.1.phar.php'); ?>
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.phar.php'); ?>
 --EXPECT--
 bool(true)
 bool(true)
 bool(true)
+bool(false)
+bool(true)
+bool(false)
index a7e212c270e580c88e9260821637ec115824633e..cc26e731409b1f07d1589d4293c78cba90e9c3da 100644 (file)
@@ -113,7 +113,7 @@ int phar_open_zipfile(char *fname, int fname_len, char *alias, int alias_len, ph
        }
        /* set up our manifest */
        zend_hash_init(&mydata->manifest, sizeof(phar_entry_info),
-               zend_get_hash_value, destroy_phar_manifest, 0);
+               zend_get_hash_value, destroy_phar_manifest_entry, 0);
        entry.phar = mydata;
        entry.is_zip = 1;
        /* prevent CRC checking */