/* prevent any ".phar" without a stub getting through */
if (!phar->halt_offset && !phar->is_brandnew) {
if (PHAR_G(readonly) && FAILURE == zend_hash_find(&(phar->manifest), ".phar/stub.php", sizeof(".phar/stub.php")-1, (void **)&stub)) {
- spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", fname);
+ if (error) {
+ spprintf(error, 0, "'%s' is not a phar archive. Use PharData::__construct() for a standard zip or tar archive", fname);
+ }
return FAILURE;
}
}
phar_unixify_path_separators(mydata->fname, fname_len);
#endif
mydata->fname_len = fname_len;
+ endbuffer = strrchr(mydata->fname, '/');
+ if (endbuffer) {
+ mydata->ext = memchr(endbuffer, '.', (mydata->fname + fname_len) - endbuffer);
+ if (mydata->ext == endbuffer) {
+ mydata->ext = memchr(endbuffer + 1, '.', (mydata->fname + fname_len) - endbuffer - 1);
+ }
+ if (mydata->ext) {
+ mydata->ext_len = (mydata->fname + mydata->fname_len) - mydata->ext;
+ }
+ }
mydata->alias = alias ? estrndup(alias, alias_len) : estrndup(mydata->fname, fname_len);
mydata->alias_len = alias ? alias_len : fname_len;
mydata->sig_flags = sig_flags;
phar_archive_data *mydata;
int register_alias;
php_stream *fp;
- char *actual = NULL;
+ char *actual = NULL, *p;
if (!pphar) {
pphar = &mydata;
#ifdef PHP_WIN32
phar_unixify_path_separators(mydata->fname, fname_len);
#endif
-
+ p = strrchr(mydata->fname, '/');
+ if (p) {
+ mydata->ext = memchr(p, '.', (mydata->fname + fname_len) - p);
+ if (mydata->ext == p) {
+ mydata->ext = memchr(p + 1, '.', (mydata->fname + fname_len) - p - 1);
+ }
+ if (mydata->ext) {
+ mydata->ext_len = (mydata->fname + fname_len) - mydata->ext;
+ }
+ }
+
if (pphar) {
*pphar = mydata;
}
}
}
+ if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) {
+ phar_archive_data **pphar;
+
+ if (is_complete) {
+ if (SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), filename, filename_len, (void **)&pphar)) {
+ *ext_str = filename + (filename_len - (*pphar)->ext_len);
+woohoo:
+ *ext_len = (*pphar)->ext_len;
+ if (executable == 2) {
+ return SUCCESS;
+ }
+ if (executable == 1 && !(*pphar)->is_data) {
+ return SUCCESS;
+ }
+ if (!executable && (*pphar)->is_data) {
+ return SUCCESS;
+ }
+ return FAILURE;
+ }
+ } else {
+ char *key;
+ uint keylen;
+ ulong unused;
+
+ zend_hash_internal_pointer_reset(&(PHAR_GLOBALS->phar_fname_map));
+ while (FAILURE != zend_hash_has_more_elements(&(PHAR_GLOBALS->phar_fname_map))) {
+ if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(&(PHAR_GLOBALS->phar_fname_map), &key, &keylen, &unused, 0, NULL)) {
+ break;
+ }
+
+ if (keylen > filename_len) {
+ zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map));
+ continue;
+ }
+ if (!memcmp(filename, key, keylen) && (filename_len == keylen
+ || filename[keylen] == '/' || filename[keylen] == '\0')) {
+ if (FAILURE == zend_hash_get_current_data(&(PHAR_GLOBALS->phar_fname_map), (void **) &pphar)) {
+ break;
+ }
+ *ext_str = filename + (keylen - (*pphar)->ext_len);
+ goto woohoo;
+ }
+ zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map));
+ }
+ }
+ }
+
pos = strchr(filename + 1, '.');
next_extension:
if (!pos) {
struct _phar_archive_data {
char *fname;
int fname_len;
+ /* for phar_detect_fname_ext, this stores the location of the file extension within fname */
+ char *ext;
+ int ext_len;
char *alias;
int alias_len;
char version[12];
}
if (!phar->is_data) {
- if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &ext, &ext_len, 1, 1, 1 TSRMLS_CC)) {
+ if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &(phar->ext_len), 1, 1, 1 TSRMLS_CC)) {
efree(oldpath);
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "phar \"%s\" has invalid extension %s", phar->fname, ext);
return NULL;
}
}
} else {
- if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &ext, &ext_len, 0, 1, 1 TSRMLS_CC)) {
+ if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &(phar->ext_len), 0, 1, 1 TSRMLS_CC)) {
efree(oldpath);
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "data phar \"%s\" has invalid extension %s", phar->fname, ext);
return NULL;
int phar_open_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, php_uint32 compression, char **error TSRMLS_DC) /* {{{ */
{
- char buf[512], *actual_alias = NULL;
+ char buf[512], *actual_alias = NULL, *p;
phar_entry_info entry = {0};
size_t pos = 0, read, totalsize;
tar_header *hdr;
phar_unixify_path_separators(myphar->fname, fname_len);
#endif
myphar->fname_len = fname_len;
+ p = strrchr(myphar->fname, '/');
+ if (p) {
+ myphar->ext = memchr(p, '.', (myphar->fname + fname_len) - p);
+ if (myphar->ext == p) {
+ myphar->ext = memchr(p + 1, '.', (myphar->fname + fname_len) - p - 1);
+ }
+ if (myphar->ext) {
+ myphar->ext_len = (myphar->fname + fname_len) - p;
+ }
+ }
myphar->fp = fp;
phar_request_initialize(TSRMLS_C);
if (SUCCESS != zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), myphar->fname, fname_len, (void*)&myphar, sizeof(phar_archive_data*), (void **)&actual)) {
A Phar alias cannot be set in a plain tar archive
A Phar stub cannot be set in a plain tar archive
Cannot set signature algorithm, not possible with tar-based phar archives
-data phar "%sphar_convert_again2.phar.tgz.oops" has invalid extension .phar.tgz.oops
-phar "%sphar_convert_again2.tgz.oops" has invalid extension .tgz.oops
-data phar "%sphar_convert_again2.phar/.tgz.oops" has invalid extension .phar/.tgz.oops
+data phar "%sphar_convert_again2.phar.tgz.oops" has invalid extension phar.tgz.oops
+phar "%sphar_convert_again2.tgz.oops" has invalid extension tgz.oops
+data phar "%sphar_convert_again2.phar/.tgz.oops" has invalid extension phar/.tgz.oops
===DONE===
php_uint16 i;
phar_archive_data *mydata = NULL;
phar_entry_info entry = {0};
- char *p = buf;
+ char *p = buf, *ext;
size = php_stream_tell(fp);
if (size > sizeof(locator) + 65536) {
#endif
mydata->is_zip = 1;
mydata->fname_len = fname_len;
+ ext = strrchr(mydata->fname, '/');
+ if (ext) {
+ mydata->ext = memchr(ext, '.', (mydata->fname + fname_len) - ext);
+ if (mydata->ext == ext) {
+ mydata->ext = memchr(ext + 1, '.', (mydata->fname + fname_len) - ext - 1);
+ }
+ if (mydata->ext) {
+ mydata->ext_len = (mydata->fname + fname_len) - mydata->ext;
+ }
+ }
/* clean up on big-endian systems */
/* seek to central directory */
php_stream_seek(fp, PHAR_GET_32(locator.cdir_offset), SEEK_SET);