mirror of
https://github.com/phpv8/v8js.git
synced 2024-11-08 12:38:41 +00:00
v8js_object_export: add size checks + precission down casts
This commit is contained in:
parent
7625d9b94f
commit
db7c81d4fa
@ -2,7 +2,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2016 The PHP Group |
|
||||
| Copyright (c) 1997-2017 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||
+----------------------------------------------------------------------+
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
#include "php_v8js_macros.h"
|
||||
#include "v8js_array_access.h"
|
||||
#include "v8js_exceptions.h"
|
||||
#include "v8js_generator_export.h"
|
||||
#include "v8js_object_export.h"
|
||||
#include "v8js_v8object_class.h"
|
||||
@ -42,7 +43,7 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
||||
zval fname, retval;
|
||||
unsigned int argc = info.Length(), min_num_args = 0, max_num_args = 0;
|
||||
char *error;
|
||||
int error_len;
|
||||
zend_ulong error_len;
|
||||
unsigned int i;
|
||||
|
||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||
@ -77,7 +78,14 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
||||
(argc < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
|
||||
argc);
|
||||
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, error_len);
|
||||
if (error_len > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Generated error message length exceeds maximum supported length", 0);
|
||||
}
|
||||
else {
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, static_cast<int>(error_len));
|
||||
}
|
||||
|
||||
if (object->ce == zend_ce_closure) {
|
||||
zend_string_release(method_ptr->internal_function.function_name);
|
||||
efree(method_ptr);
|
||||
@ -100,7 +108,15 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
||||
} else {
|
||||
if (v8js_to_zval(info[i], &fci.params[i], ctx->flags, isolate TSRMLS_CC) == FAILURE) {
|
||||
error_len = spprintf(&error, 0, "converting parameter #%d passed to %s() failed", i + 1, method_ptr->common.function_name);
|
||||
return_value = V8JS_THROW(isolate, Error, error, error_len);
|
||||
|
||||
if (error_len > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Generated error message length exceeds maximum supported length", 0);
|
||||
}
|
||||
else {
|
||||
return_value = V8JS_THROW(isolate, Error, error, static_cast<int>(error_len));
|
||||
}
|
||||
|
||||
efree(error);
|
||||
goto failure;
|
||||
}
|
||||
@ -311,7 +327,7 @@ static void v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8::Ar
|
||||
void *ptr;
|
||||
HashTable *proptable;
|
||||
zend_string *key;
|
||||
ulong index;
|
||||
zend_ulong index;
|
||||
|
||||
zend_object *object = reinterpret_cast<zend_object *>(self->GetAlignedPointerFromInternalField(1));
|
||||
ce = object->ce;
|
||||
@ -340,11 +356,23 @@ static void v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8::Ar
|
||||
IS_MAGIC_FUNC(ZEND_ISSET_FUNC_NAME)) {
|
||||
continue;
|
||||
}
|
||||
v8::Local<v8::String> method_name = V8JS_ZSTR(method_ptr->common.function_name);
|
||||
|
||||
v8::Local<v8::String> method_name;
|
||||
|
||||
// rename PHP special method names to JS equivalents.
|
||||
if (IS_MAGIC_FUNC(ZEND_TOSTRING_FUNC_NAME)) {
|
||||
method_name = V8JS_SYM("toString");
|
||||
}
|
||||
else {
|
||||
if (ZSTR_LEN(method_ptr->common.function_name) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Method name length exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
method_name = V8JS_STRL(ZSTR_VAL(method_ptr->common.function_name), static_cast<int>(ZSTR_LEN(method_ptr->common.function_name)));
|
||||
}
|
||||
|
||||
result->Set(result_len++, method_name);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
@ -362,13 +390,20 @@ static void v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8::Ar
|
||||
if(ZSTR_VAL(key)[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ZSTR_LEN(key) + 1 > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Object key length exceeds maximum supported length", 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// prefix enumerated property names with '$' so they can be
|
||||
// dereferenced unambiguously (ie, don't conflict with method
|
||||
// names)
|
||||
char *prefixed = static_cast<char *>(emalloc(ZSTR_LEN(key) + 2));
|
||||
prefixed[0] = '$';
|
||||
strncpy(prefixed + 1, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
|
||||
result->Set(result_len++, V8JS_STRL(prefixed, ZSTR_LEN(key) + 1));
|
||||
result->Set(result_len++, V8JS_STRL(prefixed, static_cast<int>(ZSTR_LEN(key) + 1)));
|
||||
efree(prefixed);
|
||||
} else {
|
||||
// even numeric indices are enumerated as strings in JavaScript
|
||||
@ -425,10 +460,10 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
{
|
||||
v8::Isolate *isolate = info.GetIsolate();
|
||||
v8::Local<v8::Object> self = info.Holder();
|
||||
v8::Handle<v8::Value> return_value;
|
||||
v8::Handle<v8::Value> return_value = V8JS_NULL;
|
||||
|
||||
char *error;
|
||||
int error_len;
|
||||
size_t error_len;
|
||||
|
||||
V8JS_TSRMLS_FETCH();
|
||||
zend_class_entry *ce;
|
||||
@ -440,16 +475,33 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
error_len = spprintf(&error, 0,
|
||||
"%s::__call expects 2 parameters, %d given",
|
||||
ce->name, (int) info.Length());
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, error_len);
|
||||
|
||||
if (error_len > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Generated error message length exceeds maximum supported length", 0);
|
||||
}
|
||||
else {
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, static_cast<int>(error_len));
|
||||
}
|
||||
|
||||
efree(error);
|
||||
info.GetReturnValue().Set(return_value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info[1]->IsArray()) {
|
||||
error_len = spprintf(&error, 0,
|
||||
"%s::__call expects 2nd parameter to be an array",
|
||||
ce->name);
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, error_len);
|
||||
|
||||
if (error_len > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Generated error message length exceeds maximum supported length", 0);
|
||||
}
|
||||
else {
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, static_cast<int>(error_len));
|
||||
}
|
||||
|
||||
efree(error);
|
||||
info.GetReturnValue().Set(return_value);
|
||||
return;
|
||||
@ -462,7 +514,15 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
error_len = spprintf(&error, 0,
|
||||
"%s::__call expects fewer than a million arguments",
|
||||
ce->name);
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, error_len);
|
||||
|
||||
if (error_len > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Generated error message length exceeds maximum supported length", 0);
|
||||
}
|
||||
else {
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, static_cast<int>(error_len));
|
||||
}
|
||||
|
||||
efree(error);
|
||||
info.GetReturnValue().Set(return_value);
|
||||
return;
|
||||
@ -484,7 +544,15 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
error_len = spprintf(&error, 0,
|
||||
"%s::__call to %s method %s", ce->name,
|
||||
(method_ptr == NULL) ? "undefined" : "non-public", method_name);
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, error_len);
|
||||
|
||||
if (error_len > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Generated error message length exceeds maximum supported length", 0);
|
||||
}
|
||||
else {
|
||||
return_value = V8JS_THROW(isolate, TypeError, error, static_cast<int>(error_len));
|
||||
}
|
||||
|
||||
efree(error);
|
||||
info.GetReturnValue().Set(return_value);
|
||||
return;
|
||||
@ -759,7 +827,13 @@ static v8::Handle<v8::Object> v8js_wrap_object(v8::Isolate *isolate, zend_class_
|
||||
/* No cached v8::FunctionTemplate available as of yet, create one. */
|
||||
new_tpl = v8::FunctionTemplate::New(isolate, 0);
|
||||
|
||||
new_tpl->SetClassName(V8JS_ZSTR(ce->name));
|
||||
if (ZSTR_LEN(ce->name) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Class name length exceeds maximum supported length", 0);
|
||||
return v8::Local<v8::Object>();
|
||||
}
|
||||
|
||||
new_tpl->SetClassName(V8JS_STRL(ZSTR_VAL(ce->name), static_cast<int>(ZSTR_LEN(ce->name))));
|
||||
new_tpl->InstanceTemplate()->SetInternalFieldCount(2);
|
||||
|
||||
if (ce == zend_ce_closure) {
|
||||
@ -855,7 +929,7 @@ static v8::Handle<v8::Object> v8js_wrap_array_to_object(v8::Isolate *isolate, zv
|
||||
{
|
||||
int i;
|
||||
zend_string *key;
|
||||
ulong index;
|
||||
zend_ulong index;
|
||||
|
||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||
v8::Local<v8::FunctionTemplate> new_tpl;
|
||||
@ -899,9 +973,23 @@ static v8::Handle<v8::Object> v8js_wrap_array_to_object(v8::Isolate *isolate, zv
|
||||
}
|
||||
continue;
|
||||
}
|
||||
newobj->Set(V8JS_ZSTR(key), zval_to_v8js(data, isolate TSRMLS_CC));
|
||||
|
||||
if (ZSTR_LEN(key) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Object key length exceeds maximum supported length", 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
newobj->Set(V8JS_STRL(ZSTR_VAL(key), static_cast<int>(ZSTR_LEN(key))),
|
||||
zval_to_v8js(data, isolate));
|
||||
} else {
|
||||
newobj->Set(index, zval_to_v8js(data, isolate TSRMLS_CC));
|
||||
if (index > std::numeric_limits<uint32_t>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Array index exceeds maximum supported bound", 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
newobj->Set(static_cast<uint32_t>(index), zval_to_v8js(data, isolate));
|
||||
}
|
||||
|
||||
if (tmp_ht) {
|
||||
|
Loading…
Reference in New Issue
Block a user