mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 15:11:53 +00:00
Merge pull request #296 from stesie/win64-precission-loss-fixes
Win64 precission loss fixes
This commit is contained in:
commit
6d5a3a2ea6
@ -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 |
|
||||
+----------------------------------------------------------------------+
|
||||
@ -79,7 +79,10 @@ extern "C" {
|
||||
|
||||
|
||||
/* Convert zval into V8 value */
|
||||
v8::Handle<v8::Value> zval_to_v8js(zval *, v8::Isolate * TSRMLS_DC);
|
||||
v8::Handle<v8::Value> zval_to_v8js(zval *, v8::Isolate *);
|
||||
|
||||
/* Convert zend_long into V8 value */
|
||||
v8::Handle<v8::Value> zend_long_to_v8js(zend_long, v8::Isolate *);
|
||||
|
||||
/* Convert V8 value into zval */
|
||||
int v8js_to_zval(v8::Handle<v8::Value>, zval *, int, v8::Isolate * TSRMLS_DC);
|
||||
@ -102,7 +105,7 @@ struct v8js_timer_ctx;
|
||||
/* Module globals */
|
||||
ZEND_BEGIN_MODULE_GLOBALS(v8js)
|
||||
// Thread-local cache whether V8 has been initialized so far
|
||||
int v8_initialized;
|
||||
bool v8_initialized;
|
||||
|
||||
/* Ini globals */
|
||||
bool use_date; /* Generate JS Date objects instead of PHP DateTime */
|
||||
@ -141,7 +144,7 @@ ZEND_EXTERN_MODULE_GLOBALS(v8js)
|
||||
*/
|
||||
struct _v8js_process_globals {
|
||||
#ifdef ZTS
|
||||
int v8_initialized;
|
||||
bool v8_initialized;
|
||||
std::mutex lock;
|
||||
#endif
|
||||
|
||||
|
5
v8js.cc
5
v8js.cc
@ -2,12 +2,13 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
| Copyright (c) 1997-2017 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
||||
| Author: Patrick Reilly <preilly@php.net> |
|
||||
| Author: Stefan Siegl <stesie@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@ -77,7 +78,7 @@ static bool v8js_ini_to_bool(const zend_string *new_value) /* {{{ */
|
||||
} else if (ZSTR_LEN(new_value) == 4 && strcasecmp("true", ZSTR_VAL(new_value)) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return (bool) atoi(ZSTR_VAL(new_value));
|
||||
return 0 != atoi(ZSTR_VAL(new_value));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -2,11 +2,11 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| 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 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Stefan Siegl <stesie@brokenpipe.de> |
|
||||
| Author: Stefan Siegl <stesie@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#include "php_v8js_macros.h"
|
||||
#include "v8js_array_access.h"
|
||||
#include "v8js_exceptions.h"
|
||||
#include "v8js_object_export.h"
|
||||
|
||||
extern "C" {
|
||||
@ -24,6 +25,7 @@ extern "C" {
|
||||
#include "ext/standard/php_string.h"
|
||||
#include "zend_interfaces.h"
|
||||
#include "zend_closures.h"
|
||||
#include "zend_exceptions.h"
|
||||
}
|
||||
|
||||
static zval v8js_array_access_dispatch(zend_object *object, const char *method_name, int param_count,
|
||||
@ -123,8 +125,15 @@ static int v8js_array_access_get_count_result(zend_object *object TSRMLS_DC) /*
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = Z_LVAL(php_value);
|
||||
return result;
|
||||
zend_long result = Z_LVAL(php_value);
|
||||
|
||||
if (result > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Array size/offset exceeds maximum supported length", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<int>(result);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -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 |
|
||||
+----------------------------------------------------------------------+
|
||||
@ -362,8 +362,14 @@ static PHP_METHOD(V8Js, __construct)
|
||||
if (Z_TYPE_P(snapshot_blob) == IS_STRING) {
|
||||
ZVAL_COPY(&c->zval_snapshot_blob, snapshot_blob);
|
||||
|
||||
if (Z_STRLEN_P(snapshot_blob) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Snapshot size exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
c->snapshot_blob.data = Z_STRVAL_P(snapshot_blob);
|
||||
c->snapshot_blob.raw_size = Z_STRLEN_P(snapshot_blob);
|
||||
c->snapshot_blob.raw_size = static_cast<int>(Z_STRLEN_P(snapshot_blob));
|
||||
c->create_params.snapshot_blob = &c->snapshot_blob;
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument snapshot_blob expected to be of string type");
|
||||
@ -445,7 +451,14 @@ static PHP_METHOD(V8Js, __construct)
|
||||
|
||||
/* Set class name for PHP object */
|
||||
zend_class_entry *ce = Z_OBJCE_P(getThis());
|
||||
php_obj_t->SetClassName(V8JS_SYML(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name)));
|
||||
|
||||
if (ZSTR_LEN(ce->name) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"PHP object class name exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
php_obj_t->SetClassName(V8JS_SYML(ZSTR_VAL(ce->name), static_cast<int>(ZSTR_LEN(ce->name))));
|
||||
|
||||
/* Register Get accessor for passed variables */
|
||||
if (vars_arr && zend_hash_num_elements(Z_ARRVAL_P(vars_arr)) > 0) {
|
||||
@ -453,9 +466,22 @@ static PHP_METHOD(V8Js, __construct)
|
||||
}
|
||||
|
||||
/* Set name for the PHP JS object */
|
||||
v8::Local<v8::String> object_name_js = (object_name && ZSTR_LEN(object_name))
|
||||
? V8JS_ZSYM(object_name)
|
||||
: V8JS_SYM("PHP");
|
||||
v8::Local<v8::String> object_name_js;
|
||||
|
||||
if (object_name && ZSTR_LEN(object_name)) {
|
||||
if (ZSTR_LEN(object_name) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"PHP JS object class name exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
object_name_js = v8::String::NewFromUtf8(isolate, ZSTR_VAL(object_name),
|
||||
v8::String::kInternalizedString, static_cast<int>(ZSTR_LEN(object_name)));
|
||||
}
|
||||
else {
|
||||
object_name_js = V8JS_SYM("PHP");
|
||||
}
|
||||
|
||||
c->object_name.Reset(isolate, object_name_js);
|
||||
|
||||
/* Add the PHP object into global object */
|
||||
@ -473,9 +499,18 @@ static PHP_METHOD(V8Js, __construct)
|
||||
if(property_info &&
|
||||
property_info != ZEND_WRONG_PROPERTY_INFO &&
|
||||
(property_info->flags & ZEND_ACC_PUBLIC)) {
|
||||
if (ZSTR_LEN(member) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Property name exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> key = v8::String::NewFromUtf8(isolate, ZSTR_VAL(member),
|
||||
v8::String::kInternalizedString, static_cast<int>(ZSTR_LEN(member)));
|
||||
|
||||
/* Write value to PHP JS object */
|
||||
value = OBJ_PROP(Z_OBJ_P(getThis()), property_info->offset);
|
||||
php_obj->ForceSet(V8JS_ZSYM(member), zval_to_v8js(value, isolate TSRMLS_CC), v8::ReadOnly);
|
||||
php_obj->ForceSet(key, zval_to_v8js(value, isolate TSRMLS_CC), v8::ReadOnly);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
@ -527,7 +562,15 @@ static PHP_METHOD(V8Js, __construct)
|
||||
continue;
|
||||
}
|
||||
|
||||
v8::Local<v8::String> method_name = V8JS_ZSTR(method_ptr->common.function_name);
|
||||
if (ZSTR_LEN(method_ptr->common.function_name) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Method name exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::String> method_name = v8::String::NewFromUtf8(isolate,
|
||||
ZSTR_VAL(method_ptr->common.function_name), v8::String::kInternalizedString,
|
||||
static_cast<int>(ZSTR_LEN(method_ptr->common.function_name)));
|
||||
v8::Local<v8::FunctionTemplate> ft;
|
||||
|
||||
/*try {
|
||||
@ -567,7 +610,7 @@ PHP_METHOD(V8Js, __wakeup)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void v8js_compile_script(zval *this_ptr, zend_string *str, zend_string *identifier, v8js_script **ret TSRMLS_DC)
|
||||
static void v8js_compile_script(zval *this_ptr, const zend_string *str, const zend_string *identifier, v8js_script **ret TSRMLS_DC)
|
||||
{
|
||||
v8js_script *res = NULL;
|
||||
|
||||
@ -577,10 +620,24 @@ static void v8js_compile_script(zval *this_ptr, zend_string *str, zend_string *i
|
||||
v8::TryCatch try_catch;
|
||||
|
||||
/* Set script identifier */
|
||||
v8::Local<v8::String> sname = identifier ? V8JS_ZSTR(identifier) : V8JS_SYM("V8Js::compileString()");
|
||||
if (identifier && ZSTR_LEN(identifier) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Script identifier exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::String> sname = identifier
|
||||
? v8::String::NewFromUtf8(isolate, ZSTR_VAL(identifier), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(identifier)))
|
||||
: V8JS_SYM("V8Js::compileString()");
|
||||
|
||||
/* Compiles a string context independently. TODO: Add a php function which calls this and returns the result as resource which can be executed later. */
|
||||
v8::Local<v8::String> source = V8JS_ZSTR(str);
|
||||
if (ZSTR_LEN(str) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Script source exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, ZSTR_VAL(str), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(str)));
|
||||
v8::Local<v8::Script> script = v8::Script::Compile(source, sname);
|
||||
|
||||
/* Compile errors? */
|
||||
@ -1020,7 +1077,7 @@ static PHP_METHOD(V8Js, registerExtension)
|
||||
static PHP_METHOD(V8Js, getExtensions)
|
||||
{
|
||||
v8js_jsext *jsext;
|
||||
ulong index;
|
||||
zend_ulong index;
|
||||
zend_string *key;
|
||||
zval *val, ext;
|
||||
|
||||
@ -1209,8 +1266,15 @@ static void v8js_write_property(zval *object, zval *member, zval *value, void **
|
||||
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
|
||||
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(object_name_js)->ToObject();
|
||||
|
||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Property name exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write value to PHP JS object */
|
||||
jsobj->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, isolate TSRMLS_CC), v8::ReadOnly);
|
||||
v8::Local<v8::Value> key = V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
||||
jsobj->ForceSet(key, zval_to_v8js(value, isolate TSRMLS_CC), v8::ReadOnly);
|
||||
}
|
||||
|
||||
/* Write value to PHP object */
|
||||
@ -1226,8 +1290,15 @@ static void v8js_unset_property(zval *object, zval *member, void **cache_slot TS
|
||||
v8::Local<v8::String> object_name_js = v8::Local<v8::String>::New(isolate, c->object_name);
|
||||
v8::Local<v8::Object> jsobj = V8JS_GLOBAL(isolate)->Get(object_name_js)->ToObject();
|
||||
|
||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Property name exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Delete value from PHP JS object */
|
||||
jsobj->Delete(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)));
|
||||
v8::Local<v8::Value> key = V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
||||
jsobj->Delete(key);
|
||||
|
||||
/* Unset from PHP object */
|
||||
std_object_handlers.unset_property(object, member, NULL);
|
||||
|
@ -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 |
|
||||
+----------------------------------------------------------------------+
|
||||
@ -20,6 +20,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include "php_v8js_macros.h"
|
||||
#include "v8js_exceptions.h"
|
||||
#include "v8js_object_export.h"
|
||||
#include "v8js_v8object_class.h"
|
||||
#include "v8js_v8.h"
|
||||
@ -30,12 +31,13 @@ extern "C" {
|
||||
#include "ext/standard/php_string.h"
|
||||
#include "zend_interfaces.h"
|
||||
#include "zend_closures.h"
|
||||
#include "zend_exceptions.h"
|
||||
}
|
||||
|
||||
static int v8js_is_assoc_array(HashTable *myht TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_string *key;
|
||||
ulong index, idx = 0;
|
||||
zend_ulong index, idx = 0;
|
||||
|
||||
ZEND_HASH_FOREACH_KEY(myht, index, key) {
|
||||
if(key) {
|
||||
@ -98,10 +100,20 @@ static v8::Handle<v8::Value> v8js_hash_to_jsarr(zval *value, v8::Isolate *isolat
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
v8::Handle<v8::Value> zval_to_v8js(zval *value, v8::Isolate *isolate TSRMLS_DC) /* {{{ */
|
||||
v8::Handle<v8::Value> zend_long_to_v8js(zend_long v, v8::Isolate *isolate) /* {{{ */
|
||||
{
|
||||
if (v < - std::numeric_limits<int32_t>::min() || v > std::numeric_limits<int32_t>::max()) {
|
||||
return V8JS_FLOAT(static_cast<double>(v));
|
||||
} else {
|
||||
return V8JS_INT(static_cast<int32_t>(v));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
v8::Handle<v8::Value> zval_to_v8js(zval *value, v8::Isolate *isolate) /* {{{ */
|
||||
{
|
||||
v8::Handle<v8::Value> jsValue;
|
||||
zend_long v;
|
||||
zend_string *value_str;
|
||||
zend_class_entry *ce;
|
||||
|
||||
switch (Z_TYPE_P(value))
|
||||
@ -133,20 +145,18 @@ v8::Handle<v8::Value> zval_to_v8js(zval *value, v8::Isolate *isolate TSRMLS_DC)
|
||||
break;
|
||||
|
||||
case IS_STRING:
|
||||
jsValue = V8JS_ZSTR(Z_STR_P(value));
|
||||
value_str = Z_STR_P(value);
|
||||
if (ZSTR_LEN(value_str) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"String exceeds maximum string length", 0);
|
||||
break;
|
||||
}
|
||||
|
||||
jsValue = v8::String::NewFromUtf8(isolate, ZSTR_VAL(value_str), v8::String::kNormalString, static_cast<int>(ZSTR_LEN(value_str)));
|
||||
break;
|
||||
|
||||
case IS_LONG:
|
||||
v = Z_LVAL_P(value);
|
||||
/* On Windows there are max and min macros, which would clobber the
|
||||
* method names of std::numeric_limits< > otherwise. */
|
||||
#undef max
|
||||
#undef min
|
||||
if (v < - std::numeric_limits<int32_t>::min() || v > std::numeric_limits<int32_t>::max()) {
|
||||
jsValue = V8JS_FLOAT(static_cast<double>(v));
|
||||
} else {
|
||||
jsValue = V8JS_INT(static_cast<int32_t>(v));
|
||||
}
|
||||
jsValue = zend_long_to_v8js(Z_LVAL_P(value), isolate);
|
||||
break;
|
||||
|
||||
case IS_DOUBLE:
|
||||
|
@ -2,13 +2,13 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
| Copyright (c) 1997-2017 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
||||
| Author: Patrick Reilly <preilly@php.net> |
|
||||
| Author: Stefan Siegl <stesie@brokenpipe.de> |
|
||||
| Author: Stefan Siegl <stesie@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
#include "php_v8js_macros.h"
|
||||
#include "v8js_commonjs.h"
|
||||
#include "v8js_exceptions.h"
|
||||
|
||||
extern "C" {
|
||||
#include "zend_exceptions.h"
|
||||
@ -42,15 +43,15 @@ V8JS_METHOD(sleep) /* {{{ */
|
||||
V8JS_METHOD(print) /* {{{ */
|
||||
{
|
||||
v8::Isolate *isolate = info.GetIsolate();
|
||||
int ret = 0;
|
||||
V8JS_TSRMLS_FETCH();
|
||||
zend_long ret = 0;
|
||||
|
||||
for (int i = 0; i < info.Length(); i++) {
|
||||
v8::String::Utf8Value str(info[i]);
|
||||
const char *cstr = ToCString(str);
|
||||
ret = PHPWRITE(cstr, strlen(cstr));
|
||||
}
|
||||
info.GetReturnValue().Set(V8JS_INT(ret));
|
||||
|
||||
info.GetReturnValue().Set(zend_long_to_v8js(ret, isolate));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -433,7 +434,13 @@ V8JS_METHOD(require)
|
||||
// Set script identifier
|
||||
v8::Local<v8::String> sname = V8JS_STR(normalised_module_id);
|
||||
|
||||
v8::Local<v8::String> source = V8JS_ZSTR(Z_STR(module_code));
|
||||
if (Z_STRLEN(module_code) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Module code size exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::String> source = V8JS_STRL(Z_STRVAL(module_code), static_cast<int>(Z_STRLEN(module_code)));
|
||||
zval_ptr_dtor(&module_code);
|
||||
|
||||
// Create and compile script
|
||||
|
@ -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) {
|
||||
|
11
v8js_v8.cc
11
v8js_v8.cc
@ -65,8 +65,15 @@ void v8js_v8_init(TSRMLS_D) /* {{{ */
|
||||
|
||||
/* Set V8 command line flags (must be done before V8::Initialize()!) */
|
||||
if (v8js_process_globals.v8_flags) {
|
||||
v8::V8::SetFlagsFromString(v8js_process_globals.v8_flags,
|
||||
strlen(v8js_process_globals.v8_flags));
|
||||
size_t flags_len = strlen(v8js_process_globals.v8_flags);
|
||||
|
||||
if (flags_len > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Length of V8 flags exceeds maximum supported length", 0);
|
||||
}
|
||||
else {
|
||||
v8::V8::SetFlagsFromString(v8js_process_globals.v8_flags, static_cast<int>(flags_len));
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize V8 */
|
||||
|
@ -36,6 +36,12 @@
|
||||
#define V8JS_GLOBAL(isolate) ((isolate)->GetCurrentContext()->Global())
|
||||
|
||||
|
||||
/* On Windows there are max and min macros, which would clobber the
|
||||
* method names of std::numeric_limits< > otherwise. */
|
||||
#undef max
|
||||
#undef min
|
||||
|
||||
|
||||
/* Extracts a C string from a V8 Utf8Value. */
|
||||
static inline const char * ToCString(const v8::String::Utf8Value &value) /* {{{ */
|
||||
{
|
||||
|
@ -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 |
|
||||
+----------------------------------------------------------------------+
|
||||
@ -67,9 +67,14 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
|
||||
|
||||
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject())
|
||||
{
|
||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Member name length exceeds maximum supported length", 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> jsObj = v8obj->ToObject();
|
||||
v8::Local<v8::String> jsKey = V8JS_ZSTR(Z_STR_P(member));
|
||||
v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
||||
v8::Local<v8::Value> jsVal;
|
||||
|
||||
/* Skip any prototype properties */
|
||||
@ -126,9 +131,14 @@ static zval *v8js_v8object_read_property(zval *object, zval *member, int type, v
|
||||
|
||||
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject())
|
||||
{
|
||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Member name length exceeds maximum supported length", 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> jsObj = v8obj->ToObject();
|
||||
v8::Local<v8::String> jsKey = V8JS_ZSTR(Z_STR_P(member));
|
||||
v8::Local<v8::String> jsKey = V8JS_STRL(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member)));
|
||||
v8::Local<v8::Value> jsVal;
|
||||
|
||||
/* Skip any prototype properties */
|
||||
@ -158,8 +168,14 @@ static void v8js_v8object_write_property(zval *object, zval *member, zval *value
|
||||
V8JS_CTX_PROLOGUE(obj->ctx);
|
||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||
|
||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Member name length exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v8obj->IsObject()) {
|
||||
v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)), zval_to_v8js(value, isolate TSRMLS_CC));
|
||||
v8obj->ToObject()->ForceSet(V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member))), zval_to_v8js(value, isolate));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -177,8 +193,14 @@ static void v8js_v8object_unset_property(zval *object, zval *member, void **cach
|
||||
V8JS_CTX_PROLOGUE(obj->ctx);
|
||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||
|
||||
if (Z_STRLEN_P(member) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Member name length exceeds maximum supported length", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v8obj->IsObject()) {
|
||||
v8obj->ToObject()->Delete(V8JS_SYML(Z_STRVAL_P(member), Z_STRLEN_P(member)));
|
||||
v8obj->ToObject()->Delete(V8JS_SYML(Z_STRVAL_P(member), static_cast<int>(Z_STRLEN_P(member))));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -241,8 +263,14 @@ static zend_function *v8js_v8object_get_method(zend_object **object_ptr, zend_st
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ZSTR_LEN(method) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Method name length exceeds maximum supported length", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
V8JS_CTX_PROLOGUE_EX(obj->ctx, NULL);
|
||||
v8::Local<v8::String> jsKey = V8JS_ZSTR(method);
|
||||
v8::Local<v8::String> jsKey = V8JS_STRL(ZSTR_VAL(method), static_cast<int>(ZSTR_LEN(method)));
|
||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||
|
||||
if (!obj->v8obj.IsEmpty() && v8obj->IsObject() && !v8obj->IsFunction()) {
|
||||
@ -277,6 +305,12 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (ZSTR_LEN(method) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Method name length exceeds maximum supported length", 0);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
argv = (zval*)safe_emalloc(sizeof(zval), argc, 0);
|
||||
zend_get_parameters_array_ex(argc, argv);
|
||||
@ -288,7 +322,7 @@ static int v8js_v8object_call_method(zend_string *method, zend_object *object, I
|
||||
std::function< v8::Local<v8::Value>(v8::Isolate *) > v8_call = [obj, method, argc, argv, object, &return_value TSRMLS_CC](v8::Isolate *isolate) {
|
||||
int i = 0;
|
||||
|
||||
v8::Local<v8::String> method_name = V8JS_ZSYM(method);
|
||||
v8::Local<v8::String> method_name = V8JS_SYML(ZSTR_VAL(method), static_cast<int>(ZSTR_LEN(method)));
|
||||
v8::Local<v8::Object> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj)->ToObject();
|
||||
v8::Local<v8::Object> thisObj;
|
||||
v8::Local<v8::Function> cb;
|
||||
|
@ -2,17 +2,16 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2013 The PHP Group |
|
||||
| Copyright (c) 1997-2017 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
||||
| Author: Patrick Reilly <preilly@php.net> |
|
||||
| Author: Stefan Siegl <stesie@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id:$ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
@ -20,6 +19,11 @@
|
||||
#include <string>
|
||||
|
||||
#include "php_v8js_macros.h"
|
||||
#include "v8js_exceptions.h"
|
||||
|
||||
extern "C" {
|
||||
#include "zend_exceptions.h"
|
||||
}
|
||||
|
||||
static void v8js_fetch_php_variable(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) /* {{{ */
|
||||
{
|
||||
@ -66,13 +70,19 @@ void v8js_register_accessors(std::vector<v8js_accessor_ctx*> *accessor_list, v8:
|
||||
continue; /* Ignore invalid values */
|
||||
}
|
||||
|
||||
if (ZSTR_LEN(property_name) > std::numeric_limits<int>::max()) {
|
||||
zend_throw_exception(php_ce_v8js_exception,
|
||||
"Property name length exceeds maximum supported length", 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create context to store accessor data
|
||||
v8js_accessor_ctx *ctx = (v8js_accessor_ctx *)emalloc(sizeof(v8js_accessor_ctx));
|
||||
ctx->variable_name = zend_string_copy(Z_STR_P(item));
|
||||
ctx->isolate = isolate;
|
||||
|
||||
/* Set the variable fetch callback for given symbol on named property */
|
||||
php_obj->SetAccessor(V8JS_ZSTR(property_name), v8js_fetch_php_variable, NULL, v8::External::New(isolate, ctx), v8::PROHIBITS_OVERWRITING, v8::ReadOnly, v8::AccessorSignature::New(isolate, php_obj_t));
|
||||
php_obj->SetAccessor(V8JS_STRL(ZSTR_VAL(property_name), static_cast<int>(ZSTR_LEN(property_name))), v8js_fetch_php_variable, NULL, v8::External::New(isolate, ctx), v8::PROHIBITS_OVERWRITING, v8::ReadOnly, v8::AccessorSignature::New(isolate, php_obj_t));
|
||||
|
||||
/* record the context so we can free it later */
|
||||
accessor_list->push_back(ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user