mirror of
https://github.com/phpv8/v8js.git
synced 2025-01-05 11:41:52 +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 |
|
| 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 |
|
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "php_v8js_macros.h"
|
#include "php_v8js_macros.h"
|
||||||
#include "v8js_array_access.h"
|
#include "v8js_array_access.h"
|
||||||
|
#include "v8js_exceptions.h"
|
||||||
#include "v8js_generator_export.h"
|
#include "v8js_generator_export.h"
|
||||||
#include "v8js_object_export.h"
|
#include "v8js_object_export.h"
|
||||||
#include "v8js_v8object_class.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;
|
zval fname, retval;
|
||||||
unsigned int argc = info.Length(), min_num_args = 0, max_num_args = 0;
|
unsigned int argc = info.Length(), min_num_args = 0, max_num_args = 0;
|
||||||
char *error;
|
char *error;
|
||||||
int error_len;
|
zend_ulong error_len;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
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 < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
|
||||||
argc);
|
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) {
|
if (object->ce == zend_ce_closure) {
|
||||||
zend_string_release(method_ptr->internal_function.function_name);
|
zend_string_release(method_ptr->internal_function.function_name);
|
||||||
efree(method_ptr);
|
efree(method_ptr);
|
||||||
@ -100,7 +108,15 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
|||||||
} else {
|
} else {
|
||||||
if (v8js_to_zval(info[i], &fci.params[i], ctx->flags, isolate TSRMLS_CC) == FAILURE) {
|
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);
|
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);
|
efree(error);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
@ -311,7 +327,7 @@ static void v8js_named_property_enumerator(const v8::PropertyCallbackInfo<v8::Ar
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
HashTable *proptable;
|
HashTable *proptable;
|
||||||
zend_string *key;
|
zend_string *key;
|
||||||
ulong index;
|
zend_ulong index;
|
||||||
|
|
||||||
zend_object *object = reinterpret_cast<zend_object *>(self->GetAlignedPointerFromInternalField(1));
|
zend_object *object = reinterpret_cast<zend_object *>(self->GetAlignedPointerFromInternalField(1));
|
||||||
ce = object->ce;
|
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)) {
|
IS_MAGIC_FUNC(ZEND_ISSET_FUNC_NAME)) {
|
||||||
continue;
|
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.
|
// rename PHP special method names to JS equivalents.
|
||||||
if (IS_MAGIC_FUNC(ZEND_TOSTRING_FUNC_NAME)) {
|
if (IS_MAGIC_FUNC(ZEND_TOSTRING_FUNC_NAME)) {
|
||||||
method_name = V8JS_SYM("toString");
|
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);
|
result->Set(result_len++, method_name);
|
||||||
} ZEND_HASH_FOREACH_END();
|
} 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') {
|
if(ZSTR_VAL(key)[0] == '\0') {
|
||||||
continue;
|
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
|
// prefix enumerated property names with '$' so they can be
|
||||||
// dereferenced unambiguously (ie, don't conflict with method
|
// dereferenced unambiguously (ie, don't conflict with method
|
||||||
// names)
|
// names)
|
||||||
char *prefixed = static_cast<char *>(emalloc(ZSTR_LEN(key) + 2));
|
char *prefixed = static_cast<char *>(emalloc(ZSTR_LEN(key) + 2));
|
||||||
prefixed[0] = '$';
|
prefixed[0] = '$';
|
||||||
strncpy(prefixed + 1, ZSTR_VAL(key), ZSTR_LEN(key) + 1);
|
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);
|
efree(prefixed);
|
||||||
} else {
|
} else {
|
||||||
// even numeric indices are enumerated as strings in JavaScript
|
// 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::Isolate *isolate = info.GetIsolate();
|
||||||
v8::Local<v8::Object> self = info.Holder();
|
v8::Local<v8::Object> self = info.Holder();
|
||||||
v8::Handle<v8::Value> return_value;
|
v8::Handle<v8::Value> return_value = V8JS_NULL;
|
||||||
|
|
||||||
char *error;
|
char *error;
|
||||||
int error_len;
|
size_t error_len;
|
||||||
|
|
||||||
V8JS_TSRMLS_FETCH();
|
V8JS_TSRMLS_FETCH();
|
||||||
zend_class_entry *ce;
|
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,
|
error_len = spprintf(&error, 0,
|
||||||
"%s::__call expects 2 parameters, %d given",
|
"%s::__call expects 2 parameters, %d given",
|
||||||
ce->name, (int) info.Length());
|
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);
|
efree(error);
|
||||||
info.GetReturnValue().Set(return_value);
|
info.GetReturnValue().Set(return_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info[1]->IsArray()) {
|
if (!info[1]->IsArray()) {
|
||||||
error_len = spprintf(&error, 0,
|
error_len = spprintf(&error, 0,
|
||||||
"%s::__call expects 2nd parameter to be an array",
|
"%s::__call expects 2nd parameter to be an array",
|
||||||
ce->name);
|
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);
|
efree(error);
|
||||||
info.GetReturnValue().Set(return_value);
|
info.GetReturnValue().Set(return_value);
|
||||||
return;
|
return;
|
||||||
@ -462,7 +514,15 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
|||||||
error_len = spprintf(&error, 0,
|
error_len = spprintf(&error, 0,
|
||||||
"%s::__call expects fewer than a million arguments",
|
"%s::__call expects fewer than a million arguments",
|
||||||
ce->name);
|
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);
|
efree(error);
|
||||||
info.GetReturnValue().Set(return_value);
|
info.GetReturnValue().Set(return_value);
|
||||||
return;
|
return;
|
||||||
@ -484,7 +544,15 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
|||||||
error_len = spprintf(&error, 0,
|
error_len = spprintf(&error, 0,
|
||||||
"%s::__call to %s method %s", ce->name,
|
"%s::__call to %s method %s", ce->name,
|
||||||
(method_ptr == NULL) ? "undefined" : "non-public", method_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);
|
efree(error);
|
||||||
info.GetReturnValue().Set(return_value);
|
info.GetReturnValue().Set(return_value);
|
||||||
return;
|
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. */
|
/* No cached v8::FunctionTemplate available as of yet, create one. */
|
||||||
new_tpl = v8::FunctionTemplate::New(isolate, 0);
|
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);
|
new_tpl->InstanceTemplate()->SetInternalFieldCount(2);
|
||||||
|
|
||||||
if (ce == zend_ce_closure) {
|
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;
|
int i;
|
||||||
zend_string *key;
|
zend_string *key;
|
||||||
ulong index;
|
zend_ulong index;
|
||||||
|
|
||||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
v8::Local<v8::FunctionTemplate> new_tpl;
|
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;
|
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 {
|
} 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) {
|
if (tmp_ht) {
|
||||||
|
Loading…
Reference in New Issue
Block a user