* 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, char **error TSRMLS_DC) /* {{{ */
+{
+ return phar_get_entry_info_dir(phar, path, path_len, 0, error TSRMLS_CC);
+}
+/* }}} */
+/**
+ * retrieve information on a file or directory contained within a phar, or null if none found
+ */
+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;
}
return entry;
}
+ if (dir) {
+ /* try to find a directory */
+ HashTable *manifest;
+ char *key;
+ uint keylen;
+ ulong unused;
+
+ manifest = &phar->manifest;
+ zend_hash_internal_pointer_reset(manifest);
+ while (FAILURE != zend_hash_has_more_elements(manifest)) {
+ if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(manifest, &key, &keylen, &unused, 0, NULL)) {
+ break;
+ }
+ if (0 != memcmp(key, path, path_len)) {
+ /* entry in directory not found */
+ if (SUCCESS != zend_hash_move_forward(manifest)) {
+ break;
+ }
+ continue;
+ } else {
+ if (key[path_len] != '/') {
+ if (SUCCESS != zend_hash_move_forward(manifest)) {
+ break;
+ }
+ continue;
+ }
+ /* found a file in this path */
+ entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info));
+ entry->is_dir = 1;
+ entry->filename = (char *) estrndup(path, path_len + 1);
+ entry->filename_len = path_len;
+ return entry;
+ }
+ }
+ }
return NULL;
}
/* }}} */
offset = phar->internal_file_start + entry->offset_within_phar;
if (-1 == php_stream_seek(fp, offset, SEEK_SET)) {
spprintf(error, 0, "phar error: internal corruption of phar \"%s\" (cannot seek to start of file \"%s\" at offset \"%d\")",
- phar->fname, entry, offset);
+ phar->fname, entry->filename, offset);
return NULL;
}
filter = NULL;
}
if (!filter) {
- spprintf(error, 0, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->fname, phar_decompress_filter(entry, 1), entry);
+ spprintf(error, 0, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->fname, phar_decompress_filter(entry, 1), entry->filename);
return NULL;
}
/* now we can safely use proper decompression */
{
phar_entry_data *idata;
char *internal_file;
- char *buffer;
char *error;
- char *filter_name;
char *plain_map;
- char tmpbuf[8];
HashTable *pharcontext;
php_url *resource = NULL;
php_stream *fp, *fpf;
- php_stream_filter *filter/*, *consumed */;
- php_uint32 offset, read, total, toread;
zval **pzoption, *metadata;
uint host_len;
long offset;
size_t wrote;
php_uint32 manifest_len, mytime, loc, new_manifest_count;
- php_uint32 newcrc32, save;
+ php_uint32 newcrc32;
php_stream *file, *oldfile, *newfile, *stubfile;
php_stream_filter *filter;
php_serialize_data_t metadata_hash;
int is_crc_checked:1;
int is_modified:1;
int is_deleted:1;
+ /* used when iterating */
+ int is_dir:1;
phar_archive_data *phar;
smart_str metadata_str;
} phar_entry_info;
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, 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_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);
return;
}
- if ((entry_info = phar_get_entry_info(phar_data, entry, entry_len, &error TSRMLS_CC)) == NULL) {
- efree(arch);
+ if ((entry_info = phar_get_entry_info_dir(phar_data, entry, entry_len, 1, &error TSRMLS_CC)) == NULL) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
"Cannot access phar file entry '%s' in archive '%s'%s%s", entry, arch, error?", ":"", error?error:"");
+ efree(arch);
efree(entry);
return;
}
return; \
}
+/* {{{ proto void PharFileInfo::__destruct()
+ * clean up directory-based entry objects
+ */
+PHP_METHOD(PharFileInfo, __destruct)
+{
+ PHAR_ENTRY_OBJECT();
+
+ if (entry_obj->ent.entry->is_dir) {
+ if (entry_obj->ent.entry->filename) {
+ efree(entry_obj->ent.entry->filename);
+ entry_obj->ent.entry->filename = NULL;
+ }
+ efree(entry_obj->ent.entry);
+ entry_obj->ent.entry = NULL;
+ }
+}
+/* }}} */
+
/* {{{ proto int PharFileInfo::getCompressedSize()
* Returns the compressed size
*/
PHP_METHOD(PharFileInfo, getCompressedSize)
{
PHAR_ENTRY_OBJECT();
-
+
RETURN_LONG(entry_obj->ent.entry->compressed_filesize);
}
/* }}} */
{
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_dir) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
+ "Phar entry is a directory, does not have a CRC"); \
+ }
if (entry_obj->ent.entry->is_crc_checked) {
RETURN_LONG(entry_obj->ent.entry->crc32);
} else {
long perms;
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_dir) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
+ "Phar entry is a directory, cannot chmod"); \
+ }
if (PHAR_G(readonly)) {
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Cannot modify permissions for file \"%s\" write operations are prohibited", entry_obj->ent.entry->filename, entry_obj->ent.entry->phar->fname);
}
zval *metadata;
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_dir) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
+ "Phar entry is a directory, cannot set metadata"); \
+ }
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &metadata) == FAILURE) {
return;
}
char *error;
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_dir) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
+ "Phar entry is a directory, cannot delete metadata"); \
+ }
if (entry_obj->ent.entry->metadata) {
zval_ptr_dtor(&entry_obj->ent.entry->metadata);
entry_obj->ent.entry->metadata = NULL;
char *error;
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_dir) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
+ "Phar entry is a directory, cannot set compression"); \
+ }
if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) {
RETURN_TRUE;
return;
char *error;
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_dir) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
+ "Phar entry is a directory, cannot set compression"); \
+ }
if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
RETURN_TRUE;
return;
int fname_len;
PHAR_ENTRY_OBJECT();
+ if (entry_obj->ent.entry->is_dir) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
+ "Phar entry is a directory, cannot set compression"); \
+ }
if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSION_MASK) == 0) {
RETURN_TRUE;
return;
zend_function_entry php_entry_methods[] = {
PHP_ME(PharFileInfo, __construct, arginfo_entry___construct, 0)
+ PHP_ME(PharFileInfo, __destruct, NULL, 0)
PHP_ME(PharFileInfo, getCompressedSize, NULL, 0)
PHP_ME(PharFileInfo, isCompressed, NULL, 0)
PHP_ME(PharFileInfo, isCompressedGZ, NULL, 0)