Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions php_v8js_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
+----------------------------------------------------------------------+
Expand Down Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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

Expand Down
5 changes: 3 additions & 2 deletions v8js.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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> |
+----------------------------------------------------------------------+
*/

Expand Down Expand Up @@ -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));
}
}
/* }}} */
Expand Down
17 changes: 13 additions & 4 deletions v8js_array_access.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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> |
+----------------------------------------------------------------------+
*/

Expand All @@ -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" {
Expand All @@ -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,
Expand Down Expand Up @@ -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);
}
/* }}} */

Expand Down
99 changes: 85 additions & 14 deletions v8js_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
+----------------------------------------------------------------------+
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -445,17 +451,37 @@ 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) {
v8js_register_accessors(&c->accessor_list, php_obj_t, vars_arr, isolate TSRMLS_CC);
}

/* 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 */
Expand All @@ -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();

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;

Expand All @@ -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? */
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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 */
Expand All @@ -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);
Expand Down
40 changes: 25 additions & 15 deletions v8js_convert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
+----------------------------------------------------------------------+
Expand All @@ -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"
Expand All @@ -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) {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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:
Expand Down
Loading