$(srcdir)/phar_path_check.c: $(srcdir)/phar_path_check.re
- $(RE2C) -b -o $(srcdir)/phar_path_check.c $(srcdir)/phar_path_check.re)
+ $(RE2C) -b -o $(srcdir)/phar_path_check.c $(srcdir)/phar_path_check.re
pharcmd: $(builddir)/phar.php $(builddir)/phar.phar
*/
int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, int options, php_stream_context *context TSRMLS_DC) /* {{{ */
{
- phar_entry_info entry;
+ phar_entry_info entry, *e;
phar_archive_data *phar;
char *error;
char *plain_map;
return FAILURE;
}
- if (phar_get_entry_info_dir(phar, resource->path + 1, strlen(resource->path + 1), 1, &error TSRMLS_CC)) {
+ if (e = phar_get_entry_info_dir(phar, resource->path + 1, strlen(resource->path + 1), 1, &error TSRMLS_CC)) {
/* directory exists, or is a subdirectory of an existing file */
+ efree(e->filename);
+ efree(e);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot create directory \"%s\" in phar \"%s\", directory already exists", resource->path+1, resource->host);
php_url_free(resource);
return FAILURE;
*/
int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC) /* {{{ */
{
+ phar_entry_info *entry;
+ phar_archive_data *phar;
+ char *error;
+ char *plain_map;
+ php_url *resource = NULL;
+ uint host_len;
+
+ if ((resource = phar_open_url(wrapper, url, "w", options TSRMLS_CC)) == NULL) {
+ 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, options TSRMLS_CC, "phar error: invalid url \"%s\"", url);
+ return FAILURE;
+ }
+
+ if (strcasecmp("phar", resource->scheme)) {
+ php_url_free(resource);
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: not a phar stream url \"%s\"", url);
+ return FAILURE;
+ }
+
+ host_len = strlen(resource->host);
+ phar_request_initialize(TSRMLS_C);
+ if (zend_hash_find(&(PHAR_GLOBALS->phar_plain_map), resource->host, host_len+1, (void **)&plain_map) == SUCCESS) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: directory \"%s\" cannot be removed in phar \"%s\", phar is extracted in plain map", resource->path+1, resource->host);
+ php_url_free(resource);
+ return FAILURE;
+ }
+
+ if (FAILURE == phar_get_archive(&phar, resource->host, host_len, NULL, 0, &error TSRMLS_CC)) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot remove directory \"%s\" in phar \"%s\", error retrieving phar information: %s", resource->path+1, resource->host, error);
+ efree(error);
+ php_url_free(resource);
+ return FAILURE;
+ }
+
+ if (!(entry = phar_get_entry_info_dir(phar, resource->path + 1, strlen(resource->path + 1), 1, &error TSRMLS_CC))) {
+ if (error) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot remove directory \"%s\" in phar \"%s\", %s", resource->path+1, resource->host, error);
+ efree(error);
+ } else {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: cannot remove directory \"%s\" in phar \"%s\", directory does not exist", resource->path+1, resource->host);
+ }
+ php_url_free(resource);
+ return FAILURE;
+ }
+
+ /* now for the easy part */
+ entry->is_deleted = 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);
+ efree(error);
+ return FAILURE;
+ }
+ return SUCCESS;
}
/* }}} */
/* $Id$ */
BEGIN_EXTERN_C()
-php_stream* phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, int options, php_stream_context *context TSRMLS_DC);
int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_stream_context *context TSRMLS_DC);
#define PHAR_MAIN 1
#include "phar_internal.h"
#include "SAPI.h"
-#include "php_stream_unlink.h"
ZEND_DECLARE_MODULE_GLOBALS(phar)
/* }}} */
/**
* retrieve information on a file or directory contained within a phar, or null if none found
+ * allow_dir is 0 for none, 1 for both empty directories in the phar and temp directories, and 2 for only
+ * valid pre-existing empty directory entries
*/
phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, int path_len, char dir, char **error TSRMLS_DC) /* {{{ */
{
const char *pcr_error;
phar_entry_info *entry;
+ char is_dir = (path[path_len - 1] == '/');
if (error) {
*error = NULL;
if (!&phar->manifest.arBuckets) {
return NULL;
}
+ if (is_dir) {
+ path_len--;
+ }
if (SUCCESS == zend_hash_find(&phar->manifest, path, path_len, (void**)&entry)) {
if (entry->is_deleted) {
/* entry is deleted, but has not been flushed to disk yet */
}
return NULL;
}
+ if (!entry->is_dir && is_dir) {
+ /* user requested a directory, we must return one */
+ if (error) {
+ spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path);
+ }
+ return NULL;
+ }
return entry;
}
- if (dir) {
+ if (dir == 1) {
/* try to find a directory */
HashTable *manifest;
char *key;
* appended, truncated, or read. For read, if the entry is marked unmodified, it is
* assumed that the file pointer, if present, is opened for reading
*/
-int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char **error TSRMLS_DC) /* {{{ */
+int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error TSRMLS_DC) /* {{{ */
{
phar_archive_data *phar;
phar_entry_info *entry;
}
return FAILURE;
}
- 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;
+ if (allow_dir) {
+ if ((entry = phar_get_entry_info_dir(phar, path, path_len, 2, for_create && !PHAR_G(readonly) ? NULL : error TSRMLS_CC)) == NULL) {
+ if (for_create && !PHAR_G(readonly)) {
+ return SUCCESS;
+ }
+ return FAILURE;
+ }
+ } else {
+ 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;
+ }
+ return FAILURE;
}
- return FAILURE;
}
if (entry->is_modified && !for_write) {
if (error) {
(*ret)->internal_file = entry;
(*ret)->is_zip = entry->is_zip;
(*ret)->is_tar = entry->is_tar;
+ if (entry->is_dir) {
+ entry->phar->refcount++;
+ entry->fp_refcount++;
+ return SUCCESS;
+ }
if (entry->fp) {
/* make a copy */
if (for_trunc) {
/**
* Create a new dummy file slot within a writeable phar for a newly created file
*/
-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) /* {{{ */
+phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error TSRMLS_DC) /* {{{ */
{
phar_archive_data *phar;
phar_entry_info *entry, etemp;
phar_entry_data *ret;
const char *pcr_error;
+ char is_dir = path[path_len - 1] == '/';
if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error TSRMLS_CC)) {
return NULL;
}
- if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, error TSRMLS_CC)) {
+ if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, allow_dir, error TSRMLS_CC)) {
return NULL;
} else if (ret) {
return ret;
}
return NULL;
}
- etemp.fp_refcount = 1;
+ if (is_dir) {
+ etemp.fp_refcount = 1;
+ etemp.is_dir = 1;
+ etemp.flags = PHAR_ENT_PERM_DEF_DIR;
+ etemp.old_flags = PHAR_ENT_PERM_DEF_DIR;
+ etemp.filename_len--; /* strip trailing / */
+ path_len--;
+ } else {
+ etemp.fp_refcount = 1;
+ etemp.flags = PHAR_ENT_PERM_DEF_FILE;
+ etemp.old_flags = PHAR_ENT_PERM_DEF_FILE;
+ }
etemp.is_modified = 1;
etemp.timestamp = time(0);
etemp.offset_within_phar = -1;
etemp.is_crc_checked = 1;
- etemp.flags = PHAR_ENT_PERM_DEF_FILE;
- etemp.old_flags = PHAR_ENT_PERM_DEF_FILE;
etemp.phar = phar;
#if HAVE_PHAR_ZIP
if (phar->is_zip) {
entry.is_dir = 0;
}
entry.filename = estrndup(buffer, entry.filename_len);
- buffer += entry.filename_len + entry.is_dir;
+ buffer += entry.filename_len + (entry.is_dir ? 1 : 0);
PHAR_GET_32(buffer, entry.uncompressed_filesize);
PHAR_GET_32(buffer, entry.timestamp);
if (offset == 0) {
phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len, char **error TSRMLS_DC);
phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, int path_len, char dir, 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_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, 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 allow_dir, char **error TSRMLS_DC);
+int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char allow_dir, char **error TSRMLS_DC);
int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **error TSRMLS_DC);
int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ext_str, int *ext_len);
int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_len, char **entry, int *entry_len TSRMLS_DC);
phar_entry_data *phar;
char *error;
if (f404_len) {
- if (FAILURE == phar_get_entry_data(&phar, fname, fname_len, f404, f404_len, "r", &error TSRMLS_CC)) {
+ if (FAILURE == phar_get_entry_data(&phar, fname, fname_len, f404, f404_len, "r", 0, &error TSRMLS_CC)) {
if (error) {
efree(error);
}
entry = estrndup("/index.php", sizeof("/index.php"));
entry_len = sizeof("/index.php")-1;
}
- if (FAILURE == phar_get_entry_data(&phar, fname, fname_len, entry, entry_len, "r", &error TSRMLS_CC)) {
+ if (FAILURE == phar_get_entry_data(&phar, fname, fname_len, entry, entry_len, "r", 0, &error TSRMLS_CC)) {
if (error) {
efree(error);
}
}
}
- if (FAILURE == phar_get_entry_data(&phar, fname, fname_len, entry, entry_len, "r", &error TSRMLS_CC)) {
+ if (FAILURE == phar_get_entry_data(&phar, fname, fname_len, entry, entry_len, "r", 0, &error TSRMLS_CC)) {
phar_do_404(fname, fname_len, f404, f404_len, entry, entry_len TSRMLS_CC);
#ifdef PHP_WIN32
efree(fname);
}
after_open_fp:
- if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, str_key, str_key_len, "w+b", &error TSRMLS_CC))) {
+ if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, str_key, str_key_len, "w+b", 0, &error TSRMLS_CC))) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s cannot be created: %s", str_key, error);
efree(error);
if (save) {
return;
}
- if (!phar_get_entry_info_dir(phar_obj->arc.archive, fname, fname_len, 1, &error TSRMLS_CC)) {
+ if (!phar_get_entry_info_dir(phar_obj->arc.archive, fname, fname_len, 2, &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);
return;
}
- if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, fname, fname_len, "w+b", &error TSRMLS_CC))) {
+ if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, fname, fname_len, "w+b", 2, &error TSRMLS_CC))) {
if (error) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist and cannot be created: %s", fname, error);
efree(error);
if (error) {
efree(error);
}
- if (cont_str) {
- contents_len = php_stream_write(data->fp, cont_str, cont_len);
- if (contents_len != cont_len) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", fname);
- }
- } else {
- if (!(php_stream_from_zval_no_verify(contents_file, &zresource))) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", fname);
+ if (!data->internal_file->is_dir) {
+ if (cont_str) {
+ contents_len = php_stream_write(data->fp, cont_str, cont_len);
+ if (contents_len != cont_len) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", fname);
+ }
+ } else {
+ if (!(php_stream_from_zval_no_verify(contents_file, &zresource))) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", fname);
+ }
+ contents_len = php_stream_copy_to_stream(contents_file, data->fp, PHP_STREAM_COPY_ALL);
}
- contents_len = php_stream_copy_to_stream(contents_file, data->fp, PHP_STREAM_COPY_ALL);
+ data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len;
}
- data->internal_file->compressed_filesize = data->internal_file->uncompressed_filesize = contents_len;
phar_entry_delref(data TSRMLS_CC);
phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
if (error) {
-/* Generated by re2c 0.10.5 on Thu Feb 8 23:49:41 2007 */
-#line 1 "ext/phar/phar_path_check.re"
+/* Generated by re2c 0.12.3 on Tue Jan 8 18:41:21 2008 */
+#line 1 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
/*
+----------------------------------------------------------------------+
| phar php single-file executable PHP extension |
loop:
{
-#line 48 "ext/phar/phar_path_check.c"
+#line 48 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
{
YYCTYPE yych;
}
yy2:
yych = *(YYMARKER = ++YYCURSOR);
- if(yych <= 0x00) goto yy16;
if(yych <= '-') goto yy3;
- if(yych <= '.') goto yy18;
- if(yych <= '/') goto yy20;
+ if(yych <= '.') goto yy16;
+ if(yych <= '/') goto yy18;
yy3:
-#line 97 "ext/phar/phar_path_check.re"
+#line 93 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
goto loop;
}
-#line 86 "ext/phar/phar_path_check.c"
+#line 85 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
yy4:
++YYCURSOR;
-#line 60 "ext/phar/phar_path_check.re"
+#line 60 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
*error = "back-slash";
return pcr_err_back_slash;
}
-#line 94 "ext/phar/phar_path_check.c"
+#line 93 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
yy6:
++YYCURSOR;
-#line 68 "ext/phar/phar_path_check.re"
+#line 64 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
*error = "star";
return pcr_err_star;
}
-#line 102 "ext/phar/phar_path_check.c"
+#line 101 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
yy8:
++YYCURSOR;
-#line 72 "ext/phar/phar_path_check.re"
+#line 68 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
if (**s == '/') {
(*s)++;
*error = NULL;
return pcr_use_query;
}
-#line 114 "ext/phar/phar_path_check.c"
+#line 113 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
yy10:
++YYCURSOR;
yy11:
-#line 80 "ext/phar/phar_path_check.re"
+#line 76 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
*error ="illegal character";
return pcr_err_illegal_char;
}
-#line 123 "ext/phar/phar_path_check.c"
+#line 122 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
yy12:
yych = *++YYCURSOR;
goto yy11;
yy13:
++YYCURSOR;
-#line 84 "ext/phar/phar_path_check.re"
+#line 80 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
if (**s == '/') {
(*s)++;
*error = NULL;
return pcr_is_ok;
}
-#line 143 "ext/phar/phar_path_check.c"
+#line 142 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
yy15:
yych = *++YYCURSOR;
goto yy3;
yy16:
- ++YYCURSOR;
-#line 64 "ext/phar/phar_path_check.re"
- {
- *error = "empty directory";
- return pcr_err_empty_entry;
- }
-#line 154 "ext/phar/phar_path_check.c"
-yy18:
yych = *++YYCURSOR;
- if(yych <= 0x00) goto yy23;
- if(yych <= '-') goto yy19;
- if(yych <= '.') goto yy22;
- if(yych <= '/') goto yy23;
-yy19:
+ if(yych <= 0x00) goto yy21;
+ if(yych <= '-') goto yy17;
+ if(yych <= '.') goto yy20;
+ if(yych <= '/') goto yy21;
+yy17:
YYCURSOR = YYMARKER;
goto yy3;
-yy20:
+yy18:
++YYCURSOR;
-#line 48 "ext/phar/phar_path_check.re"
+#line 48 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
*error = "double slash";
return pcr_err_double_slash;
}
-#line 171 "ext/phar/phar_path_check.c"
-yy22:
+#line 162 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
+yy20:
yych = *++YYCURSOR;
- if(yych <= 0x00) goto yy25;
- if(yych == '/') goto yy25;
- goto yy19;
-yy23:
+ if(yych <= 0x00) goto yy23;
+ if(yych == '/') goto yy23;
+ goto yy17;
+yy21:
++YYCURSOR;
-#line 56 "ext/phar/phar_path_check.re"
+#line 56 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
*error = "current directory reference";
return pcr_err_curr_dir;
}
-#line 184 "ext/phar/phar_path_check.c"
-yy25:
+#line 175 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
+yy23:
++YYCURSOR;
-#line 52 "ext/phar/phar_path_check.re"
+#line 52 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
{
*error = "upper directory reference";
return pcr_err_up_dir;
}
-#line 192 "ext/phar/phar_path_check.c"
+#line 183 "/home/cellog/workspace/php5/ext/phar/phar_path_check.c"
}
}
-#line 100 "ext/phar/phar_path_check.re"
+#line 96 "/home/cellog/workspace/php5/ext/phar/phar_path_check.re"
}
*error = "back-slash";
return pcr_err_back_slash;
}
-"/" END {
- *error = "empty directory";
- return pcr_err_empty_entry;
- }
"*" {
*error = "star";
return pcr_err_star;
/* strip leading "/" */
internal_file = estrdup(resource->path + 1);
if (mode[0] == 'w' || (mode[0] == 'r' && mode[1] == '+')) {
- if (NULL == (idata = phar_get_or_create_entry_data(resource->host, host_len, internal_file, strlen(internal_file), mode, &error TSRMLS_CC))) {
+ if (NULL == (idata = phar_get_or_create_entry_data(resource->host, host_len, internal_file, strlen(internal_file), mode, 0, &error TSRMLS_CC))) {
if (error) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
efree(error);
}
return fpf;
} else {
- if ((FAILURE == phar_get_entry_data(&idata, resource->host, host_len, internal_file, strlen(internal_file), "r", &error TSRMLS_CC)) || !idata) {
+ if ((FAILURE == phar_get_entry_data(&idata, resource->host, host_len, internal_file, strlen(internal_file), "r", 0, &error TSRMLS_CC)) || !idata) {
if (error) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
efree(error);
/* need to copy to strip leading "/", will get touched again */
internal_file = estrdup(resource->path + 1);
- if (FAILURE == phar_get_entry_data(&idata, resource->host, strlen(resource->host), internal_file, strlen(internal_file), "r", &error TSRMLS_CC)) {
+ if (FAILURE == phar_get_entry_data(&idata, resource->host, strlen(resource->host), internal_file, strlen(internal_file), "r", 0, &error TSRMLS_CC)) {
/* constraints of fp refcount were not met */
if (error) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
$files = array();
$files['a.php'] = '<?php echo "This is a\n"; include "'.$pname.'/b.php"; ?>';
+$files['dir/'] = '';
include 'phar_test.inc';
$a = new Phar($fname);
var_dump($a['a.php']->isExecutable());
var_dump($a['a.php']->isExecutable());
$a['a.php']->chmod(0666);
var_dump($a['a.php']->isExecutable());
+echo "test dir\n";
+var_dump($a['dir']->isDir());
+var_dump($a['dir']->isReadable());
+$a['dir']->chmod(000);
+var_dump($a['dir']->isReadable());
+$a['dir']->chmod(0666);
+var_dump($a['dir']->isReadable());
?>
===DONE===
--CLEAN--
bool(false)
bool(true)
bool(false)
+test dir
+bool(true)
+bool(true)
+bool(false)
+bool(true)
===DONE===
--- /dev/null
+--TEST--
+Phar: mkdir test
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.readonly=0
+phar.require_hash=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$phar = new Phar($fname);
+
+$phar['test/'] = '';
+var_dump($phar['test']->isDir());
+var_dump($phar['test/']->isDir());
+mkdir($pname . '/another/dir/');
+var_dump($phar['another/dir']->isDir());
+?>
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
$pname = 'phar://'.$fname;
$iname = '/file.txt';
-$ename = '/error/';
+$ename = '/error/..';
$p = new Phar($fname);
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '2.phar.php'); ?>
--EXPECTF--
-hihifile "/error/" contains invalid characters empty directory, cannot be copied from "a" in phar %s
+hihifile "/error/.." contains invalid characters upper directory reference, cannot be copied from "a" in phar %s
a: hib: hic: hia===DONE===
\ No newline at end of file
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
$pname = 'phar://'.$fname;
$iname = '/file.txt';
-$ename = '/error/';
+$ename = '/error/..';
$p = new Phar($fname);
$p[$iname] = "foobar\n";
--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 directory
+Entry /error/.. does not exist and cannot be created: phar error: invalid path "/error/.." contains upper directory reference
foobar
===DONE===
$pname = 'phar://'.$fname;
$iname = '/file.txt';
-$ename = '/error/';
+$ename = '/error/..';
$p = new Phar($fname);
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '2.phar.php'); ?>
--EXPECTF--
hihibool(true)
-file "/error/" contains invalid characters empty directory, cannot be copied from "a" in phar %s
+file "/error/.." contains invalid characters upper directory reference, cannot be copied from "a" in phar %s
bool(true)
a: hib: hic: hi===DONE===
\ No newline at end of file
$pname = 'phar://'.$fname;
$iname = '/file.txt';
-$ename = '/error/';
+$ename = '/error/..';
$p = new Phar($fname);
<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '2.phar.php'); ?>
--EXPECTF--
hihibool(true)
-file "/error/" contains invalid characters empty directory, cannot be copied from "a" in phar %s
+file "/error/.." contains invalid characters upper directory reference, cannot be copied from "a" in phar %s
bool(true)
a: hib: hic: hi===DONE===
\ No newline at end of file