From: Marcus Boerger Date: Sun, 7 Jan 2007 16:01:35 +0000 (+0000) Subject: - Fix a memleak X-Git-Tag: RELEASE_1_0_0RC1~367 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0d8ec844d6138713a0be0df4f429038318dccff2;p=php - Fix a memleak - Fix uninitialized mem access - Fix/improve error handling - Add INI entry phar.readonly - Add tests --- diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 9026426def..f3124d0822 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -81,10 +81,15 @@ ZEND_BEGIN_MODULE_GLOBALS(phar) HashTable phar_fname_map; HashTable phar_alias_map; + int readonly; ZEND_END_MODULE_GLOBALS(phar) ZEND_DECLARE_MODULE_GLOBALS(phar) +PHP_INI_BEGIN() + STD_PHP_INI_BOOLEAN("phar.readonly", "1", PHP_INI_SYSTEM, OnUpdateBool, readonly, zend_phar_globals, phar_globals) +PHP_INI_END() + #ifndef php_uint16 # if SIZEOF_SHORT == 2 # define php_uint16 unsigned short @@ -157,7 +162,7 @@ union _phar_entry_object { }; /* {{{ forward declarations */ -static int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar TSRMLS_DC); +static int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC); static php_stream *php_stream_phar_url_wrapper(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); static int phar_close(php_stream *stream, int close_handle TSRMLS_DC); @@ -372,6 +377,7 @@ static phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len if ((phar = phar_get_archive(fname, fname_len, NULL, 0 TSRMLS_CC)) == NULL) { return NULL; } + if (NULL != (ret = phar_get_entry_data(fname, fname_len, path, path_len TSRMLS_CC))) { /* reset file size */ ret->internal_file->uncompressed_filesize = 0; @@ -379,6 +385,13 @@ static phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len ret->internal_file->crc32 = 0; return ret; } + + if (PHAR_G(readonly)) { + /*no need to issue an error here */ + /*php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar error: write operations disabled by INI setting");*/ + return NULL; + } + /* create a new phar data holder */ ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data)); if ((entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC)) == NULL) { @@ -437,6 +450,14 @@ PHP_METHOD(Phar, canCompress) } /* }}} */ +/* {{{ proto bool canWrite() + * Returns whether phar extension supports writing and creating phars */ +PHP_METHOD(Phar, canWrite) +{ + RETURN_BOOL(PHAR_G(readonly)); +} +/* }}} */ + #define MAPPHAR_ALLOC_FAIL(msg) \ php_stream_close(fp);\ php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, msg, fname);\ @@ -698,7 +719,7 @@ static int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alia /** * Create or open a phar for writing */ -static int phar_create_or_open_filename(char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar TSRMLS_DC) /* {{{ */ +static int phar_create_or_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC) /* {{{ */ { phar_archive_data *mydata; int register_alias; @@ -711,7 +732,9 @@ static int phar_create_or_open_filename(char *fname, int fname_len, char *alias, if ((phar = phar_get_archive(fname, fname_len, alias, alias_len TSRMLS_CC)) != NULL) { if (fname_len != phar->fname_len || strncmp(fname, phar->fname, fname_len)) { - php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, phar->fname, fname); + if (options & REPORT_ERRORS) { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, phar->fname, fname); + } return FAILURE; } else { if (pphar) { @@ -731,12 +754,19 @@ static int phar_create_or_open_filename(char *fname, int fname_len, char *alias, return FAILURE; } - fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); + fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, NULL); if (fp) { /* open an existing phar */ php_stream_close(fp); - return phar_open_filename(fname, fname_len, alias, alias_len, pphar TSRMLS_CC); + return phar_open_filename(fname, fname_len, alias, alias_len, options, pphar TSRMLS_CC); + } + + if (PHAR_G(readonly)) { + if (options & REPORT_ERRORS) { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "creating archive \"%s\" disabled by INI setting", fname); + } + return FAILURE; } /* set up our manifest */ mydata = emalloc(sizeof(phar_archive_data)); @@ -749,6 +779,7 @@ static int phar_create_or_open_filename(char *fname, int fname_len, char *alias, mydata->alias = alias ? estrndup(alias, alias_len) : mydata->fname; mydata->alias_len = alias ? alias_len : fname_len; snprintf(mydata->version, sizeof(mydata->version), "%s", PHAR_VERSION_STR); + mydata->explicit_alias = alias ? TRUE : FALSE; mydata->internal_file_start = -1; mydata->halt_offset = 0; mydata->has_compressed_files = 0; @@ -774,7 +805,7 @@ static int phar_create_or_open_filename(char *fname, int fname_len, char *alias, * that the manifest is proper, then pass it to phar_open_file(). SUCCESS * or FAILURE is returned and pphar is set to a pointer to the phar's manifest */ -static int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar TSRMLS_DC) /* {{{ */ +static int phar_open_filename(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar TSRMLS_DC) /* {{{ */ { const char token[] = "__HALT_COMPILER();"; char *pos, buffer[1024 + sizeof(token)]; @@ -786,7 +817,9 @@ static int phar_open_filename(char *fname, int fname_len, char *alias, int alias if ((phar = phar_get_archive(fname, fname_len, alias, alias_len TSRMLS_CC)) != NULL) { if (fname_len != phar->fname_len || strncmp(fname, phar->fname, fname_len)) { - php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, phar->fname, fname); + if (options & REPORT_ERRORS) { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, phar->fname, fname); + } return FAILURE; } else { if (pphar) { @@ -809,7 +842,9 @@ static int phar_open_filename(char *fname, int fname_len, char *alias, int alias fp = php_stream_open_wrapper(fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (!fp) { - php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open phar for reading \"%s\"", fname); + if (options & REPORT_ERRORS) { + php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open phar for reading \"%s\"", fname); + } return FAILURE; } @@ -929,13 +964,13 @@ static php_url* phar_open_url(php_stream_wrapper *wrapper, char *filename, char } #endif if (strcmp(mode, "wb") == 0 || strcmp(mode, "w") == 0) { - if (phar_create_or_open_filename(resource->host, arch_len, NULL, 0, NULL TSRMLS_CC) == FAILURE) + if (phar_create_or_open_filename(resource->host, arch_len, NULL, 0, options, NULL TSRMLS_CC) == FAILURE) { php_url_free(resource); return NULL; } } else { - if (phar_open_filename(resource->host, arch_len, NULL, 0, NULL TSRMLS_CC) == FAILURE) + if (phar_open_filename(resource->host, arch_len, NULL, 0, options, NULL TSRMLS_CC) == FAILURE) { php_url_free(resource); return NULL; @@ -1009,7 +1044,7 @@ PHP_METHOD(Phar, loadPhar) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &fname, &fname_len, &alias, &alias_len) == FAILURE) { return; } - RETURN_BOOL(phar_open_filename(fname, fname_len, alias, alias_len, NULL TSRMLS_CC) == SUCCESS); + RETURN_BOOL(phar_open_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, NULL TSRMLS_CC) == SUCCESS); } /* }}} */ static php_stream_ops phar_ops = { @@ -1475,7 +1510,7 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ { phar_entry_data *data = (phar_entry_data *)stream->abstract; phar_entry_info *entry; - int alias_len, fname_len, halt_offset; + int alias_len, fname_len, halt_offset, restore_alias_len; char *buffer, *fname, *alias; char *manifest; off_t manifest_ftell, bufsize; @@ -1485,6 +1520,9 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ php_stream *file, *newfile, *compressedfile; php_stream_filter *filter; + if (PHAR_G(readonly)) { + return EOF; + } if (strcmp(stream->mode, "wb") != 0 && strcmp(stream->mode, "w") != 0) { return EOF; } @@ -1500,16 +1538,20 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ if (data->phar->halt_offset != php_stream_copy_to_stream(data->fp, newfile, data->phar->halt_offset)) { php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to copy prologue of old phar to new phar \"%s\"", data->phar->fname); + return EOF; } } else { /* this is a brand new phar */ data->phar->halt_offset = sizeof(""); if (sizeof("") != php_stream_write(newfile, "" ,sizeof(""))) { php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to create prologue in new phar \"%s\"", data->phar->fname); + return EOF; } } manifest_ftell = php_stream_tell(newfile); @@ -1561,9 +1603,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_stream_close(compressedfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, data->phar->fname); + return EOF; } file = data->fp; copy = entry->uncompressed_filesize; @@ -1578,6 +1622,7 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_stream_close(compressedfile); if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { @@ -1585,6 +1630,7 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ } else { php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to bzip2 compress file \"%s\" to new phar \"%s\"", entry->filename, data->phar->fname); } + return EOF; } php_stream_filter_append(&file->readfilters, filter); if (bufsize < entry->uncompressed_filesize) { @@ -1611,7 +1657,9 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(entry->temp_file); + entry->temp_file = NULL; php_stream_close(newfile); php_stream_close(compressedfile); if (entry->flags & PHAR_ENT_COMPRESSED_GZ) { @@ -1619,6 +1667,7 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ } else { php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to bzip2 compress file \"%s\" to new phar \"%s\"", entry->filename, data->phar->fname); } + return EOF; } file = entry->temp_file; entry->compressed_filesize = copy; @@ -1631,6 +1680,7 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ /* 4: manifest length, 4: manifest entry count, 2: phar version, 4: alias length, the rest is the alias itself */ + restore_alias_len = data->phar->alias_len; if (data->phar->explicit_alias) { manifest = (char *) emalloc(14 + data->phar->alias_len); phar_set_32(manifest, offset + data->phar->alias_len + 10); /* manifest length */ @@ -1644,8 +1694,6 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ phar_set_32(manifest+4, new_manifest_count); phar_set_32(manifest+10, 0); data->phar->alias_len = 0; - efree(data->phar->alias); - data->phar->alias = 0; } *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION) >> 8) & 0xFF); *(manifest + 9) = (unsigned char) ((PHAR_API_VERSION) & 0xFF); @@ -1655,9 +1703,13 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write manifest meta-data of new phar \"%s\"", data->phar->fname); + data->phar->alias_len = restore_alias_len; + return EOF; } + data->phar->alias_len = restore_alias_len; /* re-calculate the manifest location to simplify later code */ manifest_ftell = php_stream_tell(newfile); @@ -1679,16 +1731,20 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write filename of file \"%s\" to manifest of new phar \"%s\"", entry->filename, data->phar->fname); + return EOF; } if ((entry->flags & PHAR_ENT_MODIFIED) && !entry->temp_file) { /* nothing to do here - error out*/ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "internal error - unable to write temporary manifest of modified file \"%s\" to manifest of new phar \"%s\" temporary file was not open (please report to Phar developers)", entry->filename, data->phar->fname); + return EOF; } /* set the manifest meta-data: 4: uncompressed filesize @@ -1707,8 +1763,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write temporary manifest of file \"%s\" to manifest of new phar \"%s\"", entry->filename, data->phar->fname); + return EOF; } } @@ -1736,9 +1794,11 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_stream_close(compressedfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, data->phar->fname); + return EOF; } file = data->fp; } @@ -1750,8 +1810,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to write contents of file \"%s\" to new phar \"%s\"", entry->filename, data->phar->fname); + return EOF; } /* close the temporary file, no longer needed */ if (entry->flags & PHAR_ENT_MODIFIED) { @@ -1772,8 +1834,10 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ efree(buffer); efree(manifest); php_stream_close(data->fp); + data->fp = NULL; php_stream_close(newfile); php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open new phar \"%s\" for writing", data->phar->fname); + return EOF; } php_stream_copy_to_stream(newfile, file, PHP_STREAM_COPY_ALL); php_stream_close(newfile); @@ -1786,13 +1850,16 @@ static int phar_flush(php_stream *stream TSRMLS_DC) /* {{{ */ if (!file) { php_stream_close(data->fp); + data->fp = NULL; php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to open new phar \"%s\" for reading", data->phar->fname); return EOF; } if (-1 == php_stream_seek(file, data->phar->halt_offset, SEEK_SET)) { php_stream_close(data->fp); + data->fp = NULL; php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", data->phar->fname); + return EOF; } if (data->fp) { @@ -2146,6 +2213,11 @@ static int phar_unlink(php_stream_wrapper *wrapper, char *url, int options, php_ return FAILURE; } + if (PHAR_G(readonly)) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: write operations disabled by INI setting"); + return FAILURE; + } + /* strip leading "/" */ internal_file = estrdup(resource->path + 1); if (NULL == (idata = phar_get_entry_data(resource->host, strlen(resource->host), internal_file, strlen(internal_file) TSRMLS_CC))) { @@ -2271,7 +2343,7 @@ PHP_METHOD(Phar, __construct) return; } - if (phar_open_filename(fname, fname_len, alias, alias_len, &phar_data TSRMLS_CC) == FAILURE) { + if (phar_open_filename(fname, fname_len, alias, alias_len, REPORT_ERRORS, &phar_data TSRMLS_CC) == FAILURE) { zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Cannot open phar file '%s' with alias '%s'", fname, alias); return; @@ -2400,6 +2472,11 @@ PHP_METHOD(Phar, offsetSet) php_stream *fp; PHAR_ARCHIVE_OBJECT(); + if (PHAR_G(readonly)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by INI setting"); + return; + } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &fname, &fname_len, &contents, &contents_len) == FAILURE) { return; } @@ -2410,7 +2487,6 @@ PHP_METHOD(Phar, offsetSet) fname_len = spprintf(&fname, 0, "phar://%s/%s", phar_obj->arc.archive->fname, fname); fp = php_stream_open_wrapper(fname, "wb", STREAM_MUST_SEEK|REPORT_ERRORS, NULL); if (contents_len != php_stream_write(fp, contents, contents_len)) { - php_stream_close(fp); zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", fname); } php_stream_close(fp); @@ -2428,6 +2504,11 @@ PHP_METHOD(Phar, offsetUnset) phar_entry_info *entry; PHAR_ARCHIVE_OBJECT(); + if (PHAR_G(readonly)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Write operations disabled by INI setting"); + return; + } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &fname, &fname_len) == FAILURE) { return; } @@ -2478,7 +2559,7 @@ PHP_METHOD(PharFileInfo, __construct) return; } - if (phar_open_filename(arch, arch_len, NULL, 0, &phar_data TSRMLS_CC) == FAILURE) { + if (phar_open_filename(arch, arch_len, NULL, 0, REPORT_ERRORS, &phar_data TSRMLS_CC) == FAILURE) { efree(arch); efree(entry); zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, @@ -2616,6 +2697,7 @@ zend_function_entry php_archive_methods[] = { /* static member functions */ PHP_ME(Phar, apiVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, canCompress, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) + PHP_ME(Phar, canWrite, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, mapPhar, arginfo_phar_mapPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) PHP_ME(Phar, loadPhar, arginfo_phar_loadPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL) {NULL, NULL, NULL} @@ -2642,6 +2724,7 @@ zend_function_entry php_entry_methods[] = { static void php_phar_init_globals_module(zend_phar_globals *phar_globals) { memset(phar_globals, 0, sizeof(zend_phar_globals)); + phar_globals->readonly = 1; } /* }}} */ @@ -2650,6 +2733,7 @@ PHP_MINIT_FUNCTION(phar) /* {{{ */ zend_class_entry ce; ZEND_INIT_MODULE_GLOBALS(phar, php_phar_init_globals_module, NULL); + REGISTER_INI_ENTRIES(); INIT_CLASS_ENTRY(ce, "Phar", php_archive_methods); phar_ce_archive = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator, NULL TSRMLS_CC); @@ -2705,6 +2789,7 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */ #endif php_info_print_table_row(1, "Phar based on pear/PHP_Archive, original concept by Davey Shafik and fully realized by Gregory Beaver"); php_info_print_table_end(); + DISPLAY_INI_ENTRIES(); } /* }}} */ diff --git a/ext/phar/tests/create_new_phar.phpt b/ext/phar/tests/create_new_phar.phpt index 8b58aa892e..fe00960a74 100644 --- a/ext/phar/tests/create_new_phar.phpt +++ b/ext/phar/tests/create_new_phar.phpt @@ -2,6 +2,8 @@ Phar: create a completely new phar --SKIPIF-- +--INI-- +phar.readonly=0 --FILE-- +--INI-- +phar.readonly=1 +--FILE-- + + +===DONE=== +--CLEAN-- + +--EXPECTF-- + +Warning: file_put_contents(phar://%screate_new_phar_b.phar.php/a.php): failed to open stream: No such file or directory in %screate_new_phar_b.php on line %d + +Warning: include(%screate_new_phar_b.phar.php): failed to open stream: No such file or directory in %screate_new_phar_b.php on line %d + +Warning: include(phar://%screate_new_phar_b.phar.php/a.php): failed to open stream: No such file or directory in %screate_new_phar_b.php on line %d + +Warning: include(): Failed opening 'phar://%screate_new_phar_b.phar.php/a.php' for inclusion (include_path='.') in %screate_new_phar_b.php on line %d + +===DONE=== diff --git a/ext/phar/tests/delete_in_phar.phpt b/ext/phar/tests/delete_in_phar.phpt index 99bf0d66d0..6fa4bf1448 100644 --- a/ext/phar/tests/delete_in_phar.phpt +++ b/ext/phar/tests/delete_in_phar.phpt @@ -2,6 +2,8 @@ Phar: delete a file within a .phar --SKIPIF-- +--INI-- +phar.readonly=0 --FILE-- "; @@ -47,5 +49,10 @@ This is b/c ===AFTER=== This is a This is b -Warning: include(%selete_in_phar.phpt.phar.php/b/c.php): failed to open stream: phar error: "b/c.php" is not a file in phar "%selete_in_phar.phpt.phar.php" in %selete_in_phar.phpt on line %d + +Warning: include(%sdelete_in_phar.phar.php/b/c.php): failed to open stream: phar error: "b/c.php" is not a file in phar "%sdelete_in_phar.phar.php" in %sdelete_in_phar.php on line %d + +Warning: include(): Failed opening 'phar://%sdelete_in_phar.phar.php/b/c.php' for inclusion (include_path='.') in %sdelete_in_phar.php on line %d + ===DONE=== + \ No newline at end of file diff --git a/ext/phar/tests/delete_in_phar_b.phpt b/ext/phar/tests/delete_in_phar_b.phpt new file mode 100755 index 0000000000..c90dd10120 --- /dev/null +++ b/ext/phar/tests/delete_in_phar_b.phpt @@ -0,0 +1,56 @@ +--TEST-- +Phar: delete a file within a .phar +--SKIPIF-- + +--INI-- +phar.readonly=1 +--FILE-- +"; + +$files = array(); +$files['a.php'] = ''; +$files['b.php'] = ''; +$files['b/c.php'] = ''; +$manifest = ''; +foreach($files as $name => $cont) { + $len = strlen($cont); + $manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), $len, crc32($cont), 0x00); +} +$alias = ''; +$manifest = pack('VnV', count($files), 0x0800, strlen($alias)) . $alias . $manifest; +$file .= pack('V', strlen($manifest)) . $manifest; +foreach($files as $cont) +{ + $file .= $cont; +} + +file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file); + +include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/a.php'; +include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b.php'; +include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b/c.php'; +unlink('phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b/c.php'); +?> +===AFTER=== + + +===DONE=== +--CLEAN-- + +--EXPECTF-- +This is a +This is b +This is b/c + +Warning: unlink(): phar error: write operations disabled by INI setting in %sdelete_in_phar_b.php on line %d +===AFTER=== +This is a +This is b +This is b/c + +===DONE=== diff --git a/ext/phar/tests/open_for_write_existing.phpt b/ext/phar/tests/open_for_write_existing.phpt index 81a7217bff..b789e941a1 100644 --- a/ext/phar/tests/open_for_write_existing.phpt +++ b/ext/phar/tests/open_for_write_existing.phpt @@ -2,6 +2,8 @@ Phar: fopen a .phar for writing (existing file) --SKIPIF-- +--INI-- +phar.readonly=0 --FILE-- "; diff --git a/ext/phar/tests/open_for_write_existing_b.phpt b/ext/phar/tests/open_for_write_existing_b.phpt new file mode 100755 index 0000000000..1c3e21199f --- /dev/null +++ b/ext/phar/tests/open_for_write_existing_b.phpt @@ -0,0 +1,43 @@ +--TEST-- +Phar: fopen a .phar for writing (existing file) +--SKIPIF-- + +--INI-- +phar.readonly=1 +--FILE-- +"; + +$files = array(); +$files['a.php'] = ''; +$files['b.php'] = ''; +$files['b/c.php'] = ''; +$manifest = ''; +foreach($files as $name => $cont) { + $len = strlen($cont); + $manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), $len, crc32($cont), 0x00); +} +$alias = ''; +$manifest = pack('VnV', count($files), 0x0800, strlen($alias)) . $alias . $manifest; +$file .= pack('V', strlen($manifest)) . $manifest; +foreach($files as $cont) +{ + $file .= $cont; +} + +file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file); + +$fp = fopen('phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b/c.php', 'wb'); +fwrite($fp, 'extra'); +fclose($fp); +include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b/c.php'; +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- + +Warning: include(phar://%sopen_for_write_existing_b.phar.php/b/c.php): failed to open stream: phar error: internal corruption of phar "%sopen_for_write_existing_b.phar.php" (crc32 mismatch on file "b/c.php") in %sopen_for_write_existing_b.php on line %d + +Warning: include(): Failed opening 'phar://%sopen_for_write_existing_b.phar.php/b/c.php' for inclusion (include_path='.') in %sopen_for_write_existing_b.php on line %d +===DONE=== diff --git a/ext/phar/tests/open_for_write_newfile.phpt b/ext/phar/tests/open_for_write_newfile.phpt index ed017d733c..585ac80240 100644 --- a/ext/phar/tests/open_for_write_newfile.phpt +++ b/ext/phar/tests/open_for_write_newfile.phpt @@ -2,6 +2,8 @@ Phar: fopen a .phar for writing (new file) --SKIPIF-- +--INI-- +phar.readonly=0 --FILE-- "; diff --git a/ext/phar/tests/open_for_write_newfile_b.phpt b/ext/phar/tests/open_for_write_newfile_b.phpt new file mode 100755 index 0000000000..0c4bd13f7d --- /dev/null +++ b/ext/phar/tests/open_for_write_newfile_b.phpt @@ -0,0 +1,53 @@ +--TEST-- +Phar: fopen a .phar for writing (new file) +--SKIPIF-- + +--INI-- +phar.readonly=1 +--FILE-- +"; + +$files = array(); +$files['a.php'] = ''; +$files['b.php'] = ''; +$files['b/c.php'] = ''; +$manifest = ''; +foreach($files as $name => $cont) { + $len = strlen($cont); + $manifest .= pack('V', strlen($name)) . $name . pack('VVVVC', $len, time(), $len, crc32($cont), 0x00); +} +$alias = ''; +$manifest = pack('VnV', count($files), 0x0800, strlen($alias)) . $alias . $manifest; +$file .= pack('V', strlen($manifest)) . $manifest; +foreach($files as $cont) +{ + $file .= $cont; +} + +file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file); + +$fp = fopen('phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b/new.php', 'wb'); +fwrite($fp, 'extra'); +fclose($fp); +include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b/c.php'; +include 'phar://' . dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php/b/new.php'; +?> + +===DONE=== +--CLEAN-- + +--EXPECTF-- + +Warning: fopen(phar://%sopen_for_write_newfile_b.phar.php/b/new.php): failed to open stream: phar error: file "b/new.php" could not be created in phar "%sopen_for_write_newfile_b.phar.php" in %sopen_for_write_newfile_b.php on line %d + +Warning: fwrite(): supplied argument is not a valid stream resource in %sopen_for_write_newfile_b.php on line %d + +Warning: fclose(): supplied argument is not a valid stream resource in %sopen_for_write_newfile_b.php on line %d +This is b/c + +Warning: include(phar://%sopen_for_write_newfile_b.phar.php/b/new.php): failed to open stream: phar error: "b/new.php" is not a file in phar "%sopen_for_write_newfile_b.phar.php" in %sopen_for_write_newfile_b.php on line %d + +Warning: include(): Failed opening 'phar://%sopen_for_write_newfile_b.phar.php/b/new.php' for inclusion (include_path='.') in %sopen_for_write_newfile_b.php on line %d + +===DONE=== diff --git a/ext/phar/tests/phar_oo_011.phpt b/ext/phar/tests/phar_oo_011.phpt index bdd348558a..fbaccb03ad 100644 --- a/ext/phar/tests/phar_oo_011.phpt +++ b/ext/phar/tests/phar_oo_011.phpt @@ -2,6 +2,8 @@ Phar object: add file --SKIPIF-- +--INI-- +phar.readonly=0 --FILE-- +--INI-- +phar.readonly=1 +--FILE-- +getMessage() . "\n"; +} + +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Exception: Write operations disabled by INI setting +===DONE=== diff --git a/ext/phar/tests/phar_oo_012.phpt b/ext/phar/tests/phar_oo_012.phpt index 8958259beb..3b6f2cfe3b 100644 --- a/ext/phar/tests/phar_oo_012.phpt +++ b/ext/phar/tests/phar_oo_012.phpt @@ -2,6 +2,8 @@ Phar object: unset file --SKIPIF-- +--INI-- +phar.readonly=0 --FILE-- +--INI-- +phar.readonly=1 +--FILE-- +getMessage() . "\n"; +} + +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Exception: Write operations disabled by INI setting +===DONE===