Skip to content
This repository was archived by the owner on Mar 29, 2024. It is now read-only.

Commit b344971

Browse files
committed
Fix V8\Tempalte::Set() to do not accept non-primitive values
1 parent 545925c commit b344971

File tree

6 files changed

+83
-19
lines changed

6 files changed

+83
-19
lines changed

php_v8.h

+4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ ZEND_END_MODULE_GLOBALS(v8)
7171
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, NULL, allow_null)
7272
#endif
7373

74+
#if PHP_VERSION_ID < 70100
75+
#define zend_get_executed_scope() EG(scope)
76+
#endif
77+
7478

7579
/* Always refer to the globals in your function as PHP_V8_G(variable).
7680
You are encouraged to rename these macros something shorter, see

src/php_v8_function.cc

+1-13
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,7 @@ bool php_v8_function_unpack_args(zval *arguments_zv, int arg_position, v8::Isola
4747

4848
char *exception_message;
4949

50-
#if PHP_VERSION_ID >= 70100
5150
zend_string *ce_name = zend_get_executed_scope()->name;
52-
#else
53-
zend_string *ce_name = EG(scope)->name;
54-
#endif
5551

5652
ZEND_HASH_FOREACH_VAL(myht, pzval) {
5753
if (Z_TYPE_P(pzval) != IS_OBJECT) {
@@ -136,11 +132,7 @@ bool php_v8_function_unpack_string_args(zval* arguments_zv, int arg_position, v8
136132

137133
char *exception_message;
138134

139-
#if PHP_VERSION_ID >= 70100
140-
zend_string *ce_name = zend_get_executed_scope()->name;
141-
#else
142-
zend_string *ce_name = EG(scope)->name;
143-
#endif
135+
zend_string *ce_name = zend_get_executed_scope()->name;
144136

145137
ZEND_HASH_FOREACH_VAL(myht, pzval) {
146138
if (Z_TYPE_P(pzval) != IS_OBJECT) {
@@ -225,11 +217,7 @@ bool php_v8_function_unpack_object_args(zval* arguments_zv, int arg_position, v8
225217

226218
char *exception_message;
227219

228-
#if PHP_VERSION_ID >= 70100
229220
zend_string *ce_name = zend_get_executed_scope()->name;
230-
#else
231-
zend_string *ce_name = EG(scope)->name;
232-
#endif
233221

234222
ZEND_HASH_FOREACH_VAL(myht, pzval) {
235223
if (Z_TYPE_P(pzval) != IS_OBJECT) {

src/php_v8_template.cc

+13-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,19 @@ void php_v8_template_Set(v8::Isolate *isolate, v8::Local<T> local_template, N* p
140140

141141
PHP_V8_DATA_ISOLATES_CHECK(php_v8_template, php_v8_value_to_set);
142142

143-
local_template->Set(local_name, php_v8_value_get_local(php_v8_value_to_set), static_cast<v8::PropertyAttribute>(attributes));
143+
v8::Local<v8::Value> local_value = php_v8_value_get_local(php_v8_value_to_set);
144+
145+
if (local_value->IsObject()) {
146+
int arg_position = 3;
147+
zend_string *ce_name = zend_get_executed_scope()->name;
148+
149+
zend_throw_error(zend_ce_type_error,
150+
"Argument %d passed to %s::%s() should be instance of \\V8\\PrimitiveValue or \\V8\\Template, instance of %s given",
151+
arg_position, ZSTR_VAL(ce_name), get_active_function_name(), ZSTR_VAL(Z_OBJCE_P(php_v8_value_zv)->name));
152+
return;
153+
}
154+
155+
local_template->Set(local_name, local_value, static_cast<v8::PropertyAttribute>(attributes));
144156
} else if (instanceof_function(Z_OBJCE_P(php_v8_value_zv), php_v8_object_template_class_entry)) {
145157
// set object template
146158
PHP_V8_FETCH_OBJECT_TEMPLATE_WITH_CHECK(php_v8_value_zv, php_v8_object_template_to_set);

stubs/src/Exception.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public static function TypeError(Context $context, StringValue $message): Value
6666
* @param Context $context
6767
* @param \V8\StringValue $message
6868
*
69-
* @return Value
69+
* @return Value | ObjectValue
7070
*/
7171
public static function Error(Context $context, StringValue $message): Value
7272
{

stubs/src/Template.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,13 @@ public function GetIsolate(): Isolate
4242
/**
4343
* Adds a property to each instance created by this template.
4444
*
45-
* @param NameValue $name
46-
* @param \V8\Data $value
47-
* @param int $attributes One of \v8\PropertyAttribute constants
45+
* @param NameValue $name
46+
* @param PrimitiveValue|Template $value
47+
* @param int $attributes One of \v8\PropertyAttribute constants
48+
*
49+
* @return void
4850
*/
49-
public function Set(NameValue $name, Data $value, int $attributes = PropertyAttribute::None)
51+
public function Set(NameValue $name, /*Data*/ $value, int $attributes = PropertyAttribute::None)
5052
{
5153
}
5254

tests/V8FunctionTemplate_Set.phpt

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
V8\FunctionTemplate::Set()
3+
--SKIPIF--
4+
<?php if (!extension_loaded("v8")) {
5+
print "skip";
6+
} ?>
7+
--FILE--
8+
<?php
9+
/** @var \Phpv8Testsuite $helper */
10+
$helper = require '.testsuite.php';
11+
12+
require '.v8-helpers.php';
13+
$v8_helper = new PhpV8Helpers($helper);
14+
15+
16+
$isolate = new \V8\Isolate();
17+
$context = new V8\Context($isolate);
18+
$v8_helper->injectConsoleLog($context);
19+
20+
// Tests:
21+
22+
$ft = new \V8\FunctionTemplate($isolate);
23+
$ft->SetClassName(new \V8\StringValue($isolate, 'Test'));
24+
25+
$proto = $ft->PrototypeTemplate();
26+
27+
$f = new \V8\FunctionObject($context, function (\V8\FunctionCallbackInfo $args) {
28+
});
29+
30+
try {
31+
$proto->Set(new \V8\StringValue($isolate, 'foo'), $f);
32+
} catch (TypeError $e) {
33+
$helper->exception_export($e);
34+
}
35+
36+
$ftpl2 = new \V8\FunctionTemplate($isolate, function (\V8\FunctionCallbackInfo $args) {
37+
var_dump($args->This(), $args->Holder(), $args->NewTarget());
38+
});
39+
40+
$proto->Set(new \V8\StringValue($isolate, 'foo'), $ftpl2);
41+
42+
$context->GlobalObject()->Set($context, new \V8\StringValue($isolate, 't'), $ft->GetFunction($context));
43+
44+
45+
$v8_helper->CompileRun($context, '
46+
console.log(t);
47+
let nt = new t();
48+
console.log(nt);
49+
console.log(nt.foo);
50+
');
51+
52+
53+
?>
54+
--EXPECT--
55+
TypeError: Argument 3 passed to V8\ObjectTemplate::Set() should be instance of \V8\PrimitiveValue or \V8\Template, instance of V8\FunctionObject given
56+
function Test() { [native code] }
57+
[object Test]
58+
function foo() { [native code] }

0 commit comments

Comments
 (0)