mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 18:41:52 +00:00
Merge pull request #76 from cscott/issue-75
Protect against direct invocation of `new V8Object` and `new V8Function`
This commit is contained in:
commit
5f0cd045e2
60
tests/direct_construct.phpt
Normal file
60
tests/direct_construct.phpt
Normal file
@ -0,0 +1,60 @@
|
||||
--TEST--
|
||||
Test V8::executeString() : direct construction is prohibited
|
||||
--SKIPIF--
|
||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
# these are not allowed
|
||||
echo "-- NOT ALLOWED --\n";
|
||||
try {
|
||||
$a = new V8Object;
|
||||
} catch (V8JsScriptException $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
try {
|
||||
$a = new V8Function;
|
||||
} catch (V8JsScriptException $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
# but these are allowed
|
||||
echo "-- ALLOWED --\n";
|
||||
$v8 = new V8Js();
|
||||
$o = $v8->executeString("({foo:1})");
|
||||
var_dump($o);
|
||||
$f = $v8->executeString("(function() { return 1; })");
|
||||
var_dump($f);
|
||||
|
||||
# but these are not allowed
|
||||
echo "-- NOT ALLOWED --\n";
|
||||
try {
|
||||
$oo = new $o();
|
||||
} catch (V8JsScriptException $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
try {
|
||||
$ff = new $f;
|
||||
} catch (V8JsScriptException $e) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
// free memory
|
||||
$o = null; $f = null; $v8 = null;
|
||||
?>
|
||||
===EOF===
|
||||
--EXPECTF--
|
||||
-- NOT ALLOWED --
|
||||
string(36) "Can't directly construct V8 objects!"
|
||||
string(36) "Can't directly construct V8 objects!"
|
||||
-- ALLOWED --
|
||||
object(V8Object)#%d (1) {
|
||||
["foo"]=>
|
||||
int(1)
|
||||
}
|
||||
object(V8Function)#%d (0) {
|
||||
}
|
||||
-- NOT ALLOWED --
|
||||
string(36) "Can't directly construct V8 objects!"
|
||||
string(36) "Can't directly construct V8 objects!"
|
||||
===EOF===
|
47
v8js.cc
47
v8js.cc
@ -310,6 +310,10 @@ static HashTable *php_v8js_v8_get_properties(zval *object TSRMLS_DC) /* {{{ */
|
||||
/* the garbage collector is running, don't create more zvals */
|
||||
return NULL;
|
||||
}
|
||||
if (obj->isolate == NULL) {
|
||||
/* Half-constructed object. Shouldn't happen, but be safe. */
|
||||
return NULL;
|
||||
}
|
||||
ALLOC_HASHTABLE(obj->properties);
|
||||
zend_hash_init(obj->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
} else {
|
||||
@ -490,6 +494,7 @@ static zend_object_value php_v8js_v8_new(zend_class_entry *ce TSRMLS_DC) /* {{{
|
||||
c = (php_v8js_object *) ecalloc(1, sizeof(*c));
|
||||
|
||||
zend_object_std_init(&c->std, ce TSRMLS_CC);
|
||||
new(&c->v8obj) v8::Persistent<v8::Value>();
|
||||
|
||||
retval.handle = zend_objects_store_put(c, NULL, (zend_objects_free_object_storage_t) php_v8js_v8_free_storage, NULL TSRMLS_CC);
|
||||
retval.handlers = &v8_object_handlers;
|
||||
@ -498,6 +503,31 @@ static zend_object_value php_v8js_v8_new(zend_class_entry *ce TSRMLS_DC) /* {{{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* NOTE: We could also override v8_object_handlers.get_constructor to throw
|
||||
* an exception when invoked, but doing so causes the half-constructed object
|
||||
* to leak -- this seems to be a PHP bug. So we'll define magic __construct
|
||||
* methods instead. */
|
||||
|
||||
/* {{{ proto V8Object::__construct()
|
||||
*/
|
||||
PHP_METHOD(V8Object,__construct)
|
||||
{
|
||||
zend_throw_exception(php_ce_v8js_script_exception,
|
||||
"Can't directly construct V8 objects!", 0 TSRMLS_CC);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto V8Function::__construct()
|
||||
*/
|
||||
PHP_METHOD(V8Function,__construct)
|
||||
{
|
||||
zend_throw_exception(php_ce_v8js_script_exception,
|
||||
"Can't directly construct V8 objects!", 0 TSRMLS_CC);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void php_v8js_create_v8(zval *res, v8::Handle<v8::Value> value, int flags, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
php_v8js_object *c;
|
||||
@ -1379,6 +1409,18 @@ ZEND_BEGIN_ARG_INFO(arginfo_v8jsscriptexception_no_args, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
static const zend_function_entry v8_object_methods[] = { /* {{{ */
|
||||
PHP_ME(V8Object, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
static const zend_function_entry v8_function_methods[] = { /* {{{ */
|
||||
PHP_ME(V8Function, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
static const zend_function_entry v8js_methods[] = { /* {{{ */
|
||||
PHP_ME(V8Js, __construct, arginfo_v8js_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
|
||||
PHP_ME(V8Js, executeString, arginfo_v8js_executestring, ZEND_ACC_PUBLIC)
|
||||
@ -1569,13 +1611,13 @@ static PHP_MINIT_FUNCTION(v8js)
|
||||
zend_class_entry ce;
|
||||
|
||||
/* V8Object Class */
|
||||
INIT_CLASS_ENTRY(ce, "V8Object", NULL);
|
||||
INIT_CLASS_ENTRY(ce, "V8Object", v8_object_methods);
|
||||
php_ce_v8_object = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
php_ce_v8_object->ce_flags |= ZEND_ACC_FINAL;
|
||||
php_ce_v8_object->create_object = php_v8js_v8_new;
|
||||
|
||||
/* V8Function Class */
|
||||
INIT_CLASS_ENTRY(ce, "V8Function", NULL);
|
||||
INIT_CLASS_ENTRY(ce, "V8Function", v8_function_methods);
|
||||
php_ce_v8_function = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
php_ce_v8_function->ce_flags |= ZEND_ACC_FINAL;
|
||||
php_ce_v8_function->create_object = php_v8js_v8_new;
|
||||
@ -1584,7 +1626,6 @@ static PHP_MINIT_FUNCTION(v8js)
|
||||
memcpy(&v8_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
v8_object_handlers.clone_obj = NULL;
|
||||
v8_object_handlers.cast_object = NULL;
|
||||
v8_object_handlers.get_constructor = NULL;
|
||||
v8_object_handlers.get_property_ptr_ptr = NULL;
|
||||
v8_object_handlers.has_property = php_v8js_v8_has_property;
|
||||
v8_object_handlers.read_property = php_v8js_v8_read_property;
|
||||
|
Loading…
Reference in New Issue
Block a user