mirror of
https://github.com/php/php-src.git
synced 2026-04-29 03:03:26 +02:00
fix several potential segfaults, add tests for chmod(), fix chmod()
This commit is contained in:
+21
-4
@@ -1900,13 +1900,14 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
|
||||
php_serialize_data_t metadata_hash;
|
||||
smart_str metadata_str = {0};
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
if (PHAR_G(readonly)) {
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
*error = NULL;
|
||||
}
|
||||
if (archive->fp && !archive->is_brandnew) {
|
||||
oldfile = archive->fp;
|
||||
closeoldfile = 0;
|
||||
@@ -1959,6 +1960,10 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
|
||||
} else {
|
||||
if ((pos = strstr(user_stub, "__HALT_COMPILER();")) == NULL)
|
||||
{
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
if (error) {
|
||||
spprintf(error, 0, "illegal stub for phar \"%s\"", archive->fname);
|
||||
}
|
||||
@@ -2277,10 +2282,20 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
|
||||
if (entry->cfp) {
|
||||
file = entry->cfp;
|
||||
php_stream_rewind(file);
|
||||
} else if (entry->is_modified || !oldfile) {
|
||||
} else if (entry->fp && (entry->is_modified || !oldfile)) {
|
||||
file = entry->fp;
|
||||
php_stream_rewind(file);
|
||||
} else {
|
||||
if (!oldfile) {
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to seek to start of file \"%s\" while creating new phar \"%s\"", entry->filename, archive->fname);
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
if (-1 == php_stream_seek(oldfile, entry->offset_within_phar + archive->internal_file_start, SEEK_SET)) {
|
||||
if (closeoldfile) {
|
||||
php_stream_close(oldfile);
|
||||
@@ -2399,6 +2414,7 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
|
||||
} else {
|
||||
archive->fp = php_stream_open_wrapper(archive->fname, "w+b", IGNORE_URL|STREAM_MUST_SEEK|REPORT_ERRORS, NULL);
|
||||
if (!archive->fp) {
|
||||
php_stream_close(newfile);
|
||||
archive->fp = newfile;
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to open new phar \"%s\" for writing", archive->fname);
|
||||
@@ -2414,6 +2430,7 @@ int phar_flush(phar_archive_data *archive, char *user_stub, long len, char **err
|
||||
if (error) {
|
||||
spprintf(error, 0, "unable to seek to __HALT_COMPILER(); in new phar \"%s\"", archive->fname);
|
||||
}
|
||||
php_stream_close(newfile);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "zend_qsort.h"
|
||||
#include "main/php_streams.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/basic_functions.h"
|
||||
#include "ext/standard/url.h"
|
||||
#include "ext/standard/crc32.h"
|
||||
#include "ext/standard/md5.h"
|
||||
|
||||
@@ -885,9 +885,13 @@ PHP_METHOD(PharFileInfo, getPharFlags)
|
||||
*/
|
||||
PHP_METHOD(PharFileInfo, chmod)
|
||||
{
|
||||
char *error;
|
||||
long perms;
|
||||
PHAR_ENTRY_OBJECT();
|
||||
|
||||
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);
|
||||
}
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &perms) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
@@ -895,6 +899,24 @@ PHP_METHOD(PharFileInfo, chmod)
|
||||
entry_obj->ent.entry->flags &= ~PHAR_ENT_PERM_MASK;
|
||||
perms &= 0777;
|
||||
entry_obj->ent.entry->flags |= perms;
|
||||
entry_obj->ent.entry->phar->is_modified = 1;
|
||||
entry_obj->ent.entry->is_modified = 1;
|
||||
/* hackish cache in php_stat needs to be cleared */
|
||||
/* if this code fails to work, check main/streams/streams.c, _php_stream_stat_path */
|
||||
if (BG(CurrentLStatFile)) {
|
||||
efree(BG(CurrentLStatFile));
|
||||
}
|
||||
if (BG(CurrentStatFile)) {
|
||||
efree(BG(CurrentStatFile));
|
||||
}
|
||||
BG(CurrentLStatFile) = NULL;
|
||||
BG(CurrentStatFile) = NULL;
|
||||
|
||||
phar_flush(entry_obj->ent.entry->phar, 0, 0, &error TSRMLS_CC);
|
||||
if (error) {
|
||||
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, error);
|
||||
efree(error);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Phar::chmod
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) print "skip"; ?>
|
||||
--INI--
|
||||
phar.readonly=0
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.1.phar.php';
|
||||
$pname = 'phar://hio';
|
||||
$file = '<?php include "' . $pname . '/a.php"; __HALT_COMPILER(); ?>';
|
||||
|
||||
$files = array();
|
||||
$files['a.php'] = '<?php echo "This is a\n"; include "'.$pname.'/b.php"; ?>';
|
||||
include 'phar_test.inc';
|
||||
$a = new Phar($fname);
|
||||
var_dump($a['a.php']->isExecutable());
|
||||
$a['a.php']->chmod(0777);
|
||||
var_dump($a['a.php']->isExecutable());
|
||||
$a['a.php']->chmod(0666);
|
||||
var_dump($a['a.php']->isExecutable());
|
||||
?>
|
||||
===DONE===
|
||||
--CLEAN--
|
||||
<?php
|
||||
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.1.phar.php');
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Phar::chmod
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("phar")) print "skip"; ?>
|
||||
--INI--
|
||||
phar.require_hash=0
|
||||
--FILE--
|
||||
<?php
|
||||
$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.1.phar.php';
|
||||
$pname = 'phar://hio';
|
||||
$file = '<?php include "' . $pname . '/a.php"; __HALT_COMPILER(); ?>';
|
||||
|
||||
$files = array();
|
||||
$files['a.php'] = '<?php echo "This is a\n"; include "'.$pname.'/b.php"; ?>';
|
||||
include 'phar_test.inc';
|
||||
try {
|
||||
$a = new Phar($fname);
|
||||
var_dump($a['a.php']->isExecutable());
|
||||
$a['a.php']->chmod(0777);
|
||||
var_dump($a['a.php']->isExecutable());
|
||||
$a['a.php']->chmod(0666);
|
||||
var_dump($a['a.php']->isExecutable());
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--CLEAN--
|
||||
<?php
|
||||
unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.1.phar.php');
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
Cannot modify permissions for file "a.php" write operations are prohibited
|
||||
===DONE===
|
||||
Reference in New Issue
Block a user