This commit is contained in:
Xinchen Hui 2015-03-31 11:54:08 +08:00
commit b72fd9c258
24 changed files with 167 additions and 84 deletions

View File

@ -1,22 +0,0 @@
--TEST--
Testing declaration of alias to 'static'
--FILE--
<?php
class bar {
}
class foo {
public function test() {
class_alias('bar', 'static');
return new static;
}
}
$a = new foo;
var_dump($a->test());
?>
--EXPECTF--
object(foo)#%d (0) {
}

View File

@ -11,4 +11,4 @@ foo(10);
?>
--EXPECTF--
Fatal error: "bar\int" cannot be used as a type declaration in %s on line %d
Fatal error: Cannot use 'bar\int' as class name as it is reserved in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (2)
class int {}
--EXPECTF--
Fatal error: "int" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'int' as class name as it is reserved in %s on line %d

View File

@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (2) - c
class foobar {}
class_alias("foobar", "int");
--EXPECTF--
Fatal error: "int" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'int' as class name as it is reserved in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (2) - u
use foobar as int;
--EXPECTF--
Fatal error: "int" cannot be used as a class name in %s on line %d
Fatal error: Cannot use foobar as int because 'int' is a special class name in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (3)
class float {}
--EXPECTF--
Fatal error: "float" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'float' as class name as it is reserved in %s on line %d

View File

@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (3) - c
class foobar {}
class_alias("foobar", "float");
--EXPECTF--
Fatal error: "float" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'float' as class name as it is reserved in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (3) - u
use foobar as float;
--EXPECTF--
Fatal error: "float" cannot be used as a class name in %s on line %d
Fatal error: Cannot use foobar as float because 'float' is a special class name in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (4)
class string {}
--EXPECTF--
Fatal error: "string" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'string' as class name as it is reserved in %s on line %d

View File

@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (4) - c
class foobar {}
class_alias("foobar", "string");
--EXPECTF--
Fatal error: "string" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'string' as class name as it is reserved in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (4) - u
use foobar as string;
--EXPECTF--
Fatal error: "string" cannot be used as a class name in %s on line %d
Fatal error: Cannot use foobar as string because 'string' is a special class name in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (6)
class bool {}
--EXPECTF--
Fatal error: "bool" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'bool' as class name as it is reserved in %s on line %d

View File

@ -6,4 +6,4 @@ Scalar type hint names cannot be used as class, trait or interface names (6) - c
class foobar {}
class_alias("foobar", "bool");
--EXPECTF--
Fatal error: "bool" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'bool' as class name as it is reserved in %s on line %d

View File

@ -5,4 +5,4 @@ Scalar type hint names cannot be used as class, trait or interface names (6) - u
use foobar as bool;
--EXPECTF--
Fatal error: "bool" cannot be used as a class name in %s on line %d
Fatal error: Cannot use foobar as bool because 'bool' is a special class name in %s on line %d

View File

@ -6,4 +6,4 @@ namespace foo;
class int {}
--EXPECTF--
Fatal error: "int" cannot be used as a class name in %s on line %d
Fatal error: Cannot use 'int' as class name as it is reserved in %s on line %d

View File

@ -1698,6 +1698,10 @@ ZEND_FUNCTION(set_error_handler)
Restores the previously defined error handler function */
ZEND_FUNCTION(restore_error_handler)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
zval zeh;
@ -1760,6 +1764,10 @@ ZEND_FUNCTION(set_exception_handler)
Restores the previously defined exception handler function */
ZEND_FUNCTION(restore_exception_handler)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
zval_ptr_dtor(&EG(user_exception_handler));
}

View File

@ -129,6 +129,53 @@ static zend_bool zend_get_unqualified_name(const zend_string *name, const char *
}
/* }}} */
struct reserved_class_name {
const char *name;
size_t len;
};
static const struct reserved_class_name reserved_class_names[] = {
{ZEND_STRL("bool")},
{ZEND_STRL("false")},
{ZEND_STRL("float")},
{ZEND_STRL("int")},
{ZEND_STRL("null")},
{ZEND_STRL("parent")},
{ZEND_STRL("self")},
{ZEND_STRL("static")},
{ZEND_STRL("string")},
{ZEND_STRL("true")},
{NULL, 0}
};
static zend_bool zend_is_reserved_class_name(const zend_string *name) /* {{{ */
{
const struct reserved_class_name *reserved = reserved_class_names;
const char *uqname = name->val;
size_t uqname_len = name->len;
zend_get_unqualified_name(name, &uqname, &uqname_len);
for (; reserved->name; ++reserved) {
if (uqname_len == reserved->len
&& zend_binary_strcasecmp(uqname, uqname_len, reserved->name, reserved->len) == 0
) {
return 1;
}
}
return 0;
}
/* }}} */
ZEND_API void zend_assert_valid_class_name(const zend_string *name) /* {{{ */
{
if (zend_is_reserved_class_name(name)) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot use '%s' as class name as it is reserved", name->val);
}
}
/* }}} */
typedef struct _scalar_typehint_info {
const char* name;
const size_t name_len;
@ -143,39 +190,19 @@ static const scalar_typehint_info scalar_typehints[] = {
{NULL, 0, IS_UNDEF}
};
static zend_always_inline const scalar_typehint_info* zend_find_scalar_typehint(const zend_string *const_name) /* {{{ */
static zend_always_inline const scalar_typehint_info* zend_find_scalar_typehint(const zend_string *name) /* {{{ */
{
const scalar_typehint_info *info = &scalar_typehints[0];
const char *uqname;
size_t uqname_len;
if (!zend_get_unqualified_name(const_name, &uqname, &uqname_len)) {
uqname = const_name->val;
uqname_len = const_name->len;
}
while (info->name) {
if (uqname_len == info->name_len && zend_binary_strcasecmp(uqname, uqname_len, info->name, info->name_len) == 0) {
break;
for (; info->name; ++info) {
if (name->len == info->name_len
&& zend_binary_strcasecmp(name->val, name->len, info->name, info->name_len) == 0
) {
return info;
}
info++;
}
if (info->name) {
return info;
} else {
return NULL;
}
}
/* }}} */
ZEND_API void zend_assert_valid_class_name(const zend_string *const_name) /* {{{ */
{
const scalar_typehint_info *info = zend_find_scalar_typehint(const_name);
if (info) {
zend_error_noreturn(E_COMPILE_ERROR, "\"%s\" cannot be used as a class name", info->name);
}
return NULL;
}
/* }}} */
@ -184,9 +211,6 @@ static zend_always_inline zend_uchar zend_lookup_scalar_typehint_by_name(const z
const scalar_typehint_info *info = zend_find_scalar_typehint(const_name);
if (info) {
if (const_name->len != info->name_len) {
zend_error_noreturn(E_COMPILE_ERROR, "\"%s\" cannot be used as a type declaration", const_name->val);
}
return info->type;
} else {
return 0;
@ -4099,6 +4123,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_
} else {
if (zend_is_const_default_class_ref(return_type_ast)) {
class_name = zend_resolve_class_name_ast(return_type_ast);
zend_assert_valid_class_name(class_name);
} else {
zend_string_addref(class_name);
if (!is_method) {
@ -4225,9 +4250,9 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, zend_bool is_
if (type != 0) {
arg_info->type_hint = type;
} else {
if (zend_is_const_default_class_ref(type_ast)) {
class_name = zend_resolve_class_name_ast(type_ast);
zend_assert_valid_class_name(class_name);
} else {
zend_string_addref(class_name);
}
@ -4846,10 +4871,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
return;
}
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved",
name->val);
}
zend_assert_valid_class_name(name);
lcname = zend_string_tolower(name);
@ -4857,8 +4879,6 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
import_name = zend_hash_find_ptr(CG(current_import), lcname);
}
zend_assert_valid_class_name(name);
if (CG(current_namespace)) {
name = zend_prefix_with_ns(name);
@ -5094,19 +5114,13 @@ void zend_compile_use(zend_ast *ast) /* {{{ */
}
}
if (type == T_CLASS) {
zend_assert_valid_class_name(new_name);
}
if (case_sensitive) {
lookup_name = zend_string_copy(new_name);
} else {
lookup_name = zend_string_tolower(new_name);
}
if (type == T_CLASS && (zend_string_equals_literal(lookup_name, "self")
|| zend_string_equals_literal(lookup_name, "parent"))
) {
if (type == T_CLASS && zend_is_reserved_class_name(new_name)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' "
"is a special class name", old_name->val, new_name->val, new_name->val);
}

View File

@ -397,7 +397,7 @@ class PharCommand extends CLICommand
*/
static function cli_arg_typ_privkey($arg, $cfg, $key)
{
$arg = self::cli_arg_typ_string($arg, $cfg, $key);
$arg = self::cli_arg_typ_filecont($arg, $cfg, $key);
$hash_avail = Phar::getSupportedSignatures();
if ($arg && !in_array('OpenSSL', $hash_avail))

View File

@ -3579,7 +3579,7 @@ static void phar_add_file(phar_archive_data **pphar, char *filename, int filenam
phar_entry_data *data;
php_stream *contents_file;
if (filename_len >= sizeof(".phar")-1 && !memcmp(filename, ".phar", sizeof(".phar")-1)) {
if (filename_len >= sizeof(".phar")-1 && !memcmp(filename, ".phar", sizeof(".phar")-1) && (filename[5] == '/' || filename[5] == '\\' || filename[5] == '\0')) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create any files in magic \".phar\" directory", (*pphar)->fname);
return;
}

View File

@ -102,7 +102,7 @@ int phar_is_tar(char *buf, char *fname) /* {{{ */
tar_header *header = (tar_header *) buf;
php_uint32 checksum = phar_tar_number(header->checksum, sizeof(header->checksum));
php_uint32 ret;
char save[sizeof(header->checksum)];
char save[sizeof(header->checksum)], *bname;
/* assume that the first filename in a tar won't begin with <?php */
if (!strncmp(buf, "<?php", sizeof("<?php")-1)) {
@ -113,7 +113,10 @@ int phar_is_tar(char *buf, char *fname) /* {{{ */
memset(header->checksum, ' ', sizeof(header->checksum));
ret = (checksum == phar_tar_checksum(buf, 512));
memcpy(header->checksum, save, sizeof(header->checksum));
if (!ret && strstr(fname, ".tar")) {
if ((bname = strrchr(fname, PHP_DIR_SEPARATOR))) {
fname = bname;
}
if (!ret && (bname = strstr(fname, ".tar")) && (bname[4] == '\0' || bname[4] == '.')) {
/* probably a corrupted tar - so we will pretend it is one */
return 1;
}

View File

@ -0,0 +1,58 @@
--TEST--
Bug #64931 (phar_add_file is too restrictive on filename)
--SKIPIF--
<?php extension_loaded("phar") or die("skip need ext/phar support"); ?>
--INI--
phar.readonly=0
--FILE--
<?php
echo "Test\n";
@unlink(__DIR__."/bug64931.phar");
$phar = new Phar(__DIR__."/bug64931.phar");
$phar->addFile(__DIR__."/src/.pharignore", ".pharignore");
try {
$phar->addFile(__DIR__."/src/.pharignore", ".phar/gotcha");
} catch (Exception $e) {
echo "CAUGHT: ". $e->getMessage() ."\n";
}
try {
$phar->addFromString(".phar", "gotcha");
} catch (Exception $e) {
echo "CAUGHT: ". $e->getMessage() ."\n";
}
try {
$phar->addFromString(".phar//", "gotcha");
} catch (Exception $e) {
echo "CAUGHT: ". $e->getMessage() ."\n";
}
try {
$phar->addFromString(".phar\\", "gotcha");
} catch (Exception $e) {
echo "CAUGHT: ". $e->getMessage() ."\n";
}
try {
$phar->addFromString(".phar\0", "gotcha");
} catch (Exception $e) {
echo "CAUGHT: ". $e->getMessage() ."\n";
}
?>
===DONE===
--CLEAN--
<?php
@unlink(__DIR__."/bug64931.phar");
?>
--EXPECT--
Test
CAUGHT: Cannot create any files in magic ".phar" directory
CAUGHT: Cannot create any files in magic ".phar" directory
CAUGHT: Cannot create any files in magic ".phar" directory
CAUGHT: Cannot create any files in magic ".phar" directory
CAUGHT: Cannot create any files in magic ".phar" directory
===DONE===

View File

@ -0,0 +1,3 @@
# ignore file
*.tmp
*~

View File

@ -0,0 +1,19 @@
--TEST--
Bug #67761 (Phar::mapPhar fails for Phars inside a path containing ".tar")
--SKIPIF--
<?php extension_loaded("phar") or die("SKIP need ext/phar suppport"); ?>
--FILE--
<?php
echo "Test\n";
include __DIR__."/files/bug67761.tar/bug67761.phar";
?>
===DONE===
--EXPECT--
Test
#!/usr/bin/env php
Test
===DONE===

Binary file not shown.