summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Beaver <cellog@php.net>2007-12-22 07:46:53 +0000
committerGreg Beaver <cellog@php.net>2007-12-22 07:46:53 +0000
commit8e4cc4b3dd81b184da2229782cd65547a674956f (patch)
tree68b75095b7693ce472a73c27ee1c0a7ff274251c
parent2bbd4be65ef988f1c548dc95df5c1b077834bdb3 (diff)
downloadphp-git-8e4cc4b3dd81b184da2229782cd65547a674956f.tar.gz
first attempt at major new feature: default front controller for web
Currently, an entire phar entry is leaked for no obvious reason, otherwise it works. Sample code: The phar has to be created using Phar->useFrontController(); and the stub performs actual resolution of which file to load: <?php Phar::mapPhar(); include 'phar://' . __FILE__ . '/' . substr($_SERVER['REQUEST_URI'], strlen(basename(__FILE__))); __HALT_COMPILER(); ?> Phar automatically determines mime type from the file extension and either parses or displays the file. Modification of REQUEST_URI and other variables should happen in the stub [DOC]
-rw-r--r--ext/phar/phar.c236
-rwxr-xr-xext/phar/phar_internal.h27
-rwxr-xr-xext/phar/phar_object.c26
-rw-r--r--ext/phar/tests/001.phpt2
-rwxr-xr-xext/phar/tests/create_path_error.phpt10
-rwxr-xr-xext/phar/tests/phar_test.inc2
6 files changed, 280 insertions, 23 deletions
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index 44baaef34c..1f8dd4d162 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -185,6 +185,11 @@ PHP_INI_END()
*/
static void phar_destroy_phar_data(phar_archive_data *data TSRMLS_DC) /* {{{ */
{
+ if (!PHAR_G(request_ends)) {
+ if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_web_map))) {
+ zend_hash_del(&(PHAR_GLOBALS->phar_web_map), data->fname, data->fname_len);
+ }
+ }
if (data->alias && data->alias != data->fname) {
efree(data->alias);
data->alias = NULL;
@@ -390,6 +395,12 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
*error = NULL;
}
+ if (!path_len && !dir) {
+ if (error) {
+ spprintf(error, 0, "phar error: invalid path \"%s\" must not be empty", path);
+ }
+ return 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);
@@ -414,6 +425,9 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
uint keylen;
ulong unused;
+ if (!path_len) {
+ path = "/";
+ }
manifest = &phar->manifest;
zend_hash_internal_pointer_reset(manifest);
while (FAILURE != zend_hash_has_more_elements(manifest)) {
@@ -515,6 +529,12 @@ 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 (!path_len) {
+ if (error) {
+ spprintf(error, 0, "phar error: file \"\" cannot be empty");
+ }
+ 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;
@@ -1314,6 +1334,13 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
mydata->sig_len = sig_len;
mydata->signature = signature;
phar_request_initialize(TSRMLS_C);
+ if ((manifest_flags & PHAR_HDR_WEB) != 0) {
+ mydata->is_web = 1;
+ if (!zend_hash_num_elements(&(PHAR_GLOBALS->phar_mimes))) {
+ phar_init_mime_list(TSRMLS_C);
+ }
+ zend_hash_add(&(PHAR_GLOBALS->phar_web_map), mydata->fname, fname_len, (void*)&mydata, sizeof(void*), NULL);
+ }
zend_hash_add(&(PHAR_GLOBALS->phar_fname_map), mydata->fname, fname_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);
if (register_alias) {
mydata->is_explicit_alias = 1;
@@ -1564,9 +1591,12 @@ int phar_detect_phar_fname_ext(const char *filename, int check_length, char **ex
static int php_check_dots(const char *element, int n)
{
- while (n-- > 0) if (element[n] != '.') break;
-
- return (n != -1);
+ for(n--; n >= 0; --n) {
+ if (element[n] != '.') {
+ return 1;
+ }
+ }
+ return 0;
}
#define IS_DIRECTORY_UP(element, len) \
@@ -1631,7 +1661,7 @@ static char *phar_fix_filepath(char *path, int *new_len) /* {{{ */
efree(free_path);
- if (path[path_length-1] == '/') {
+ if (path[path_length-1] == '/' && new_phar_len > 1) {
new_phar = (char*)erealloc(new_phar, new_phar_len + 2);
new_phar[new_phar_len++] = '/';
new_phar[new_phar_len] = 0;
@@ -1694,7 +1724,7 @@ int phar_split_fname(char *filename, int filename_len, char **arch, int *arch_le
#ifdef PHP_WIN32
phar_unixify_path_separators(*entry, *entry_len);
#endif
- *entry = phar_fix_filepath(*entry, entry_len);
+ *entry = phar_fix_filepath(*entry, entry_len);
} else {
*entry_len = 1;
*entry = estrndup("/", 1);
@@ -2264,7 +2294,7 @@ static size_t phar_stream_read(php_stream *stream, char *buf, size_t count TSRML
/* use our proxy position */
php_stream_seek(data->fp, data->position + data->zero, SEEK_SET);
-
+
if (!data->zero) {
got = php_stream_read(data->fp, buf, count);
if (data->fp->eof) {
@@ -2750,8 +2780,13 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
manifest_len = offset + archive->alias_len + sizeof(manifest) + main_metadata_str.len;
phar_set_32(manifest, manifest_len);
phar_set_32(manifest+4, new_manifest_count);
- *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION) >> 8) & 0xFF);
- *(manifest + 9) = (unsigned char) (((PHAR_API_VERSION) & 0xF0));
+ if (archive->is_web) {
+ *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION_NOWEB) >> 8) & 0xFF);
+ *(manifest + 9) = (unsigned char) (((PHAR_API_VERSION_NOWEB) & 0xF0));
+ } else {
+ *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION) >> 8) & 0xFF);
+ *(manifest + 9) = (unsigned char) (((PHAR_API_VERSION) & 0xF0));
+ }
phar_set_32(manifest+10, global_flags);
phar_set_32(manifest+14, archive->alias_len);
@@ -3831,12 +3866,166 @@ static void php_phar_init_globals_module(zend_phar_globals *phar_globals)
phar_globals->readonly = 1;
}
/* }}} */
+
+static void phar_init_mime_list(TSRMLS_D)
+{
+ phar_mime_type mime;
+#define PHAR_SET_MIME(mimetype, ret, ...) \
+ mime.mime = mimetype; \
+ mime.len = sizeof((mimetype))+1; \
+ mime.type = ret; \
+ { \
+ char mimes[][5] = {__VA_ARGS__, "\0"}; \
+ int i = 0; \
+ for (; mimes[i][0]; i++) { \
+ zend_hash_add(&(PHAR_GLOBALS->phar_mimes), mimes[i], strlen(mimes[i]), (void *)&mime, sizeof(phar_mime_type), NULL); \
+ } \
+ }
+
+ PHAR_SET_MIME("text/html", PHAR_MIME_PHPS, "phps")
+ PHAR_SET_MIME("text/plain", PHAR_MIME_OTHER, "c", "cc", "cpp", "c++", "dtd", "h", "log", "rng", "txt", "xsd")
+ PHAR_SET_MIME("", PHAR_MIME_PHP, "php", "inc")
+ PHAR_SET_MIME("video/avi", PHAR_MIME_OTHER, "avi")
+ PHAR_SET_MIME("image/bmp", PHAR_MIME_OTHER, "bmp")
+ PHAR_SET_MIME("text/css", PHAR_MIME_OTHER, "css")
+ PHAR_SET_MIME("image/gif", PHAR_MIME_OTHER, "gif")
+ PHAR_SET_MIME("text/html", PHAR_MIME_OTHER, "htm", "html", "htmls")
+ PHAR_SET_MIME("image/x-ico", PHAR_MIME_OTHER, "ico")
+ PHAR_SET_MIME("image/jpeg", PHAR_MIME_OTHER, "jpe", "jpg", "jpeg")
+ PHAR_SET_MIME("application/x-javascript", PHAR_MIME_OTHER, "js")
+ PHAR_SET_MIME("audio/midi", PHAR_MIME_OTHER, "mid", "midi")
+ PHAR_SET_MIME("audio/mod", PHAR_MIME_OTHER, "mod")
+ PHAR_SET_MIME("movie/quicktime", PHAR_MIME_OTHER, "mov")
+ PHAR_SET_MIME("audio/mp3", PHAR_MIME_OTHER, "mp3")
+ PHAR_SET_MIME("video/mpeg", PHAR_MIME_OTHER, "mpg", "mpeg")
+ PHAR_SET_MIME("application/pdf", PHAR_MIME_OTHER, "pdf")
+ PHAR_SET_MIME("image/png", PHAR_MIME_OTHER, "png")
+ PHAR_SET_MIME("application/shockwave-flash", PHAR_MIME_OTHER, "swf")
+ PHAR_SET_MIME("image/tiff", PHAR_MIME_OTHER, "tif", "tiff")
+ PHAR_SET_MIME("audio/wav", PHAR_MIME_OTHER, "wav")
+ PHAR_SET_MIME("image/xbm", PHAR_MIME_OTHER, "xbm")
+ PHAR_SET_MIME("text/xml", PHAR_MIME_OTHER, "xml")
+}
+
+static int phar_file_type(char *file, char **mime_type TSRMLS_DC)
+{
+ char *ext;
+ phar_mime_type *mime;
+ if (!mime_type) {
+ /* assume PHP */
+ return 0;
+ }
+ ext = strrchr(file, '.');
+ if (!ext) {
+ *mime_type = "text/plain";
+ /* no file extension = assume text/plain */
+ return PHAR_MIME_OTHER;
+ }
+ ext++;
+ if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_mimes), ext, strlen(ext), (void **) &mime)) {
+ *mime_type = "application/octet-stream";
+ return PHAR_MIME_OTHER;
+ }
+ *mime_type = mime->mime;
+ return mime->type;
+}
+/* }}} */
+
+static zend_op_array *phar_file_action(char *entry, int entry_len, char *arch, int arch_len, char **ourname TSRMLS_DC)
+{
+ char *mime_type, *name = NULL, buf[8192], *error;
+ zend_syntax_highlighter_ini syntax_highlighter_ini;
+ sapi_header_line ctr = {0};
+ zend_op_array *nada;
+ zend_op *opline;
+ phar_entry_data *phar;
+ size_t got;
+
+ *ourname = name;
+
+#define PHAR_NOP() \
+ nada = (zend_op_array *) emalloc(sizeof(zend_op_array)); \
+ init_op_array(nada, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); \
+ opline = get_next_op(nada TSRMLS_CC); \
+ opline->opcode = ZEND_RETURN; \
+ opline->op1.op_type = IS_CONST; \
+ INIT_ZVAL(opline->op1.u.constant); \
+ SET_UNUSED(opline->op2); \
+ ZEND_VM_SET_OPCODE_HANDLER(opline); \
+ nada->done_pass_two = 1; \
+ return nada;
+
+ switch (phar_file_type(entry, &mime_type TSRMLS_CC)) {
+ case PHAR_MIME_PHPS:
+ /* highlight source */
+ spprintf(&name, 4096, "phar://%s/%s", arch, entry);
+ efree(arch);
+ php_get_highlight_struct(&syntax_highlighter_ini);
+
+ if (highlight_file(name, &syntax_highlighter_ini TSRMLS_CC) == FAILURE) {
+ }
+
+ PHAR_NOP();
+ case PHAR_MIME_OTHER:
+ /* send headers, output file contents */
+ if (FAILURE == phar_get_entry_data(&phar, arch, arch_len, entry, entry_len, "r", &error TSRMLS_CC)) {
+ ctr.response_code = 404;
+ ctr.line_len = sizeof("HTTP/1.0 404")+1;
+ ctr.line = "HTTP/1.0 404";
+ sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+
+ PHAR_NOP();
+ }
+ ctr.line_len = spprintf(&(ctr.line), 0, "Content-type: %s", mime_type);
+ sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+ efree(ctr.line);
+ ctr.line_len = spprintf(&(ctr.line), 0, "Content-length: %d", phar->internal_file->uncompressed_filesize);
+ sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+ efree(ctr.line);
+ if (FAILURE == sapi_send_headers(TSRMLS_C)) {
+ phar_entry_delref(phar TSRMLS_CC);
+ zend_bailout();
+ }
+
+ /* prepare to output */
+ if (!phar->fp) {
+ phar->internal_file->fp_refcount++;
+ phar->fp = phar->phar->fp;
+ phar->zero = phar->phar->internal_file_start + phar->internal_file->offset_within_phar;
+ }
+ php_stream_seek(phar->fp, phar->position + phar->zero, SEEK_SET);
+ do {
+ if (!phar->zero) {
+ got = php_stream_read(phar->fp, buf, 8192);
+ PHPWRITE(buf, got);
+ if (phar->fp->eof) {
+ break;
+ }
+ } else {
+ got = php_stream_read(phar->fp, buf, MIN(8192, phar->internal_file->uncompressed_filesize - phar->position));
+ PHPWRITE(buf, got);
+ phar->position = php_stream_tell(phar->fp) - phar->zero;
+ if (phar->position == (off_t) phar->internal_file->uncompressed_filesize) {
+ break;
+ }
+ }
+ } while (1);
+
+ phar_entry_delref(phar TSRMLS_CC);
+ PHAR_NOP();
+ case PHAR_MIME_PHP:
+ /* fall through */
+ break;
+ }
+ return NULL;
+}
+
static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */
{
zend_op_array *res;
char *s, *name = NULL;
char *fname = NULL;
- int fname_len;
+ int fname_len, failed;
zend_op_array *(*save)(zend_file_handle *file_handle, int type TSRMLS_DC);
save = zend_compile_file; /* restore current handler or we cause trouble */
@@ -3845,12 +4034,25 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
char *arch, *entry;
int arch_len, entry_len;
fname = zend_get_executed_filename(TSRMLS_C);
+ fname_len = strlen(fname);
+ /* check for web front controller phars */
+ if (zend_hash_exists(&(PHAR_GLOBALS->phar_web_map), fname, fname_len)) {
+ zend_op_array *retval;
+ if (strncasecmp(file_handle->filename, "phar://", 7)) {
+ goto skip_phar;
+ }
+ fname_len = strlen(file_handle->filename);
+ if (SUCCESS == phar_split_fname(file_handle->filename, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
+ if ((retval = phar_file_action(entry, entry_len, arch, arch_len, &name TSRMLS_CC))) {
+ return retval;
+ }
+ }
+ }
if (strncasecmp(fname, "phar://", 7)) {
goto skip_phar;
}
fname_len = strlen(fname);
if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
-
efree(entry);
entry = file_handle->filename;
/* include within phar, if :// is not in the url, then prepend phar://<archive>/ */
@@ -3870,11 +4072,19 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
}
}
skip_phar:
- res = zend_compile_file(file_handle, type TSRMLS_CC);
+ zend_try {
+ failed = 0;
+ res = zend_compile_file(file_handle, type TSRMLS_CC);
+ } zend_catch {
+ failed = 1;
+ } zend_end_try();
if (name) {
efree(name);
}
zend_compile_file = save;
+ if (failed) {
+ zend_bailout();
+ }
return res;
}
/* }}} */
@@ -3969,6 +4179,8 @@ void phar_request_initialize(TSRMLS_D) /* {{{ */
PHAR_GLOBALS->request_done = 0;
zend_hash_init(&(PHAR_GLOBALS->phar_fname_map), sizeof(phar_archive_data*), zend_get_hash_value, destroy_phar_data, 0);
zend_hash_init(&(PHAR_GLOBALS->phar_alias_map), sizeof(phar_archive_data*), zend_get_hash_value, NULL, 0);
+ zend_hash_init(&(PHAR_GLOBALS->phar_web_map), sizeof(void *), zend_get_hash_value, NULL, 0);
+ zend_hash_init(&(PHAR_GLOBALS->phar_mimes), sizeof(phar_mime_type *), zend_get_hash_value, NULL, 0);
zend_hash_init(&(PHAR_GLOBALS->phar_plain_map), sizeof(const char *), zend_get_hash_value, NULL, 0);
phar_split_extract_list(TSRMLS_C);
if (SUCCESS == zend_hash_find(CG(function_table), "fopen", 6, (void **)&orig)) {
@@ -3990,6 +4202,8 @@ PHP_RSHUTDOWN_FUNCTION(phar) /* {{{ */
}
zend_hash_destroy(&(PHAR_GLOBALS->phar_alias_map));
zend_hash_destroy(&(PHAR_GLOBALS->phar_fname_map));
+ zend_hash_destroy(&(PHAR_GLOBALS->phar_web_map));
+ zend_hash_destroy(&(PHAR_GLOBALS->phar_mimes));
zend_hash_destroy(&(PHAR_GLOBALS->phar_plain_map));
PHAR_GLOBALS->request_init = 0;
}
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h
index 0682cc2d82..fe6bfcc74f 100755
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@ -33,6 +33,7 @@
#include "zend_interfaces.h"
#include "zend_operators.h"
#include "zend_qsort.h"
+#include "zend_vm.h"
#include "main/php_streams.h"
#include "main/streams/php_stream_plain_wrapper.h"
#include "ext/standard/info.h"
@@ -69,9 +70,11 @@
#endif
#define PHAR_EXT_VERSION_STR "1.3.0"
-#define PHAR_API_VERSION_STR "1.1.0"
+#define PHAR_API_VERSION_STR "1.2.0"
/* x.y.z maps to 0xyz0 */
-#define PHAR_API_VERSION 0x1100
+#define PHAR_API_VERSION 0x1200
+/* API version to use for is_web=0 in phar creation */
+#define PHAR_API_VERSION_NOWEB 0x1100
#define PHAR_API_MIN_READ 0x1000
#define PHAR_API_MAJORVERSION 0x1000
#define PHAR_API_MAJORVER_MASK 0xF000
@@ -82,6 +85,7 @@
#define PHAR_HDR_COMPRESSED_GZ 0x00001000
#define PHAR_HDR_COMPRESSED_BZ2 0x00002000
#define PHAR_HDR_SIGNATURE 0x00010000
+#define PHAR_HDR_WEB 0x00020000
#define PHAR_SIG_MD5 0x0001
#define PHAR_SIG_SHA1 0x0002
@@ -109,6 +113,10 @@ ZEND_BEGIN_MODULE_GLOBALS(phar)
HashTable phar_fname_map;
HashTable phar_alias_map;
HashTable phar_plain_map;
+ /* phar archives that have is_web = 1, used for fast lookup in phar_compile_file */
+ HashTable phar_web_map;
+ /* mapping of file extension to MIME type */
+ HashTable phar_mimes;
char* extract_list;
int readonly;
zend_bool readonly_orig;
@@ -202,8 +210,20 @@ struct _phar_archive_data {
int is_brandnew:1;
/* defer phar creation */
int donotflush:1;
+ /* this phar is intended to use a web front controller with non-CLI SAPI */
+ int is_web:1;
};
+#define PHAR_MIME_PHP '\0'
+#define PHAR_MIME_PHPS '\1'
+#define PHAR_MIME_OTHER '\2'
+
+typedef struct _phar_mime_type {
+ char *mime;
+ int len;
+ /* one of PHAR_MIME_* */
+ char type;
+} phar_mime_type;
/* stream access data for one file entry in a phar file */
typedef struct _phar_entry_data {
@@ -251,10 +271,9 @@ int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, i
int phar_open_or_create_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
int phar_open_compiled_file(char *alias, int alias_len, char **error TSRMLS_DC);
-static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS);
-static void phar_getcwd(INTERNAL_FUNCTION_PARAMETERS);
#ifdef PHAR_MAIN
+static void phar_init_mime_list(TSRMLS_D);
static void phar_fopen(INTERNAL_FUNCTION_PARAMETERS);
static int phar_open_fp(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index e7dfcb0fbf..96b9e68f8c 100755
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -342,6 +342,31 @@ PHP_METHOD(Phar, getSupportedCompression)
return; \
}
+/* {{{ proto void Phar::useWebFrontController()
+ * This method is used in Phar creation to specify that this phar
+ * is intended to be executed as a self-contained website, and the
+ * built-in fast front controller should be used.
+ */
+PHP_METHOD(Phar, useWebFrontController)
+{
+ char *error;
+ PHAR_ARCHIVE_OBJECT();
+
+ if (PHAR_G(readonly)) {
+ zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC,
+ "Cannot specify use of default front controller, phar is read-only");
+ return;
+ }
+
+ phar_obj->arc.archive->is_web = 1;
+ phar_flush(phar_obj->arc.archive, 0, 0, &error TSRMLS_CC);
+ if (error) {
+ zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
+ efree(error);
+ }
+}
+/* }}} */
+
static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC)
{
zval **value;
@@ -1982,6 +2007,7 @@ zend_function_entry php_archive_methods[] = {
PHP_ME(Phar, offsetUnset, arginfo_phar_offsetExists, ZEND_ACC_PUBLIC)
PHP_ME(Phar, uncompressAllFiles, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phar, buildFromIterator, arginfo_phar_build, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, useWebFrontController, NULL, ZEND_ACC_PUBLIC)
#endif
/* static member functions */
PHP_ME(Phar, apiVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
diff --git a/ext/phar/tests/001.phpt b/ext/phar/tests/001.phpt
index 397501e8e4..26c225deb0 100644
--- a/ext/phar/tests/001.phpt
+++ b/ext/phar/tests/001.phpt
@@ -8,5 +8,5 @@ var_dump(Phar::apiVersion());
?>
===DONE===
--EXPECT--
-string(5) "1.1.0"
+string(5) "1.2.0"
===DONE===
diff --git a/ext/phar/tests/create_path_error.phpt b/ext/phar/tests/create_path_error.phpt
index eb2dbe43ca..cdb5b5f6da 100755
--- a/ext/phar/tests/create_path_error.phpt
+++ b/ext/phar/tests/create_path_error.phpt
@@ -54,11 +54,9 @@ foreach($checks as $check)
--EXPECTF--
string(5) "query"
string(5) "query"
-Error: file_put_contents(phar://%s//): failed to open stream: phar error: invalid path "/" contains empty directory
-Error: file_put_contents(phar://%s/.): failed to open stream: phar error: invalid path "." contains current directory reference
-Error: file_put_contents(phar://%s/../): failed to open stream: phar error: invalid path "../" contains empty directory
-Error: file_put_contents(phar://%s/a/..): failed to open stream: phar error: invalid path "a/.." contains upper directory reference
-Error: file_put_contents(phar://%s/a/): failed to open stream: phar error: invalid path "a/" contains empty directory
-Error: file_put_contents(phar://%s/b//a.php): failed to open stream: phar error: invalid path "b//a.php" contains double slash
+Error: file_put_contents(phar://%s//): failed to open stream: phar error: file "" cannot be empty
+Error: file_put_contents(phar://%s/.): failed to open stream: phar error: file "" cannot be empty
+Error: file_put_contents(phar://%s/../): failed to open stream: phar error: file "" cannot be empty
+Error: file_put_contents(phar://%s/a/..): failed to open stream: phar error: file "" cannot be empty
Exception: Entry a does not exist and cannot be created: phar error: invalid path "a" contains illegal character
===DONE===
diff --git a/ext/phar/tests/phar_test.inc b/ext/phar/tests/phar_test.inc
index 213e95558c..af5d227f66 100755
--- a/ext/phar/tests/phar_test.inc
+++ b/ext/phar/tests/phar_test.inc
@@ -51,7 +51,7 @@ foreach($files as $name => $cont)
$alias = 'hio';
if (isset($pmeta)) $pmeta = serialize($pmeta); else $pmeta = '';
-$manifest = pack('VnVV', count($files), 0x1000, $glags, strlen($alias)) . $alias . pack('V', strlen($pmeta)) . $pmeta . $manifest;
+$manifest = pack('VnVV', count($files), 0x1000, $gflags, strlen($alias)) . $alias . pack('V', strlen($pmeta)) . $pmeta . $manifest;
$file .= pack('V', strlen($manifest)) . $manifest;
foreach($files as $cont)