1616
1717#include " php_v8_startup_data.h"
1818#include " php_v8_exceptions.h"
19+ #include " php_v8_script_compiler.h"
1920#include " php_v8_a.h"
2021#include " php_v8.h"
22+ #include " zend_smart_str.h"
2123
2224
2325zend_class_entry *php_v8_startup_data_class_entry;
2426#define this_ce php_v8_startup_data_class_entry
2527
2628static zend_object_handlers php_v8_startup_data_object_handlers;
2729
30+ extern script_compiler_tag php_v8_startup_data_get_current_tag () {
31+ script_compiler_tag tag = {PHP_V8_SCRIPT_COMPILER_TAG_MAGIC, v8::ScriptCompiler::CachedDataVersionTag ()};
32+ return tag;
33+ }
2834
2935void php_v8_startup_data_create (zval *return_value, v8::StartupData *blob) {
3036 object_init_ex (return_value, this_ce);
3137
3238 PHP_V8_STARTUP_DATA_FETCH_INTO (return_value, php_v8_startup_data);
3339
34- php_v8_startup_data->blob = new phpv8::StartupData (blob);
40+ script_compiler_tag version = php_v8_startup_data_get_current_tag ();
41+
42+ const char *blob_data = blob->data ;
43+
44+ blob->data = (const char *) estrndup (blob->data , blob->raw_size );
45+
46+ delete [] blob_data;
47+
48+ php_v8_startup_data->blob = new phpv8::StartupData (blob, version);
3549}
3650
3751static void php_v8_startup_data_free (zend_object *object) {
@@ -68,22 +82,27 @@ static PHP_METHOD(StartupData, __construct) {
6882 return ;
6983 }
7084
71- if (ZSTR_LEN (blob_string) > INT_MAX) {
72- PHP_V8_THROW_EXCEPTION (" Failed to create startup blob due to blob size integer overflow " );
85+ if (ZSTR_LEN (blob_string) > INT_MAX + sizeof (script_compiler_tag) ) {
86+ PHP_V8_THROW_EXCEPTION (" Invalid startup blob (too large) " );
7387 return ;
7488 }
7589
76- if (!ZSTR_LEN (blob_string)) {
90+ if (ZSTR_LEN (blob_string) < sizeof (script_compiler_tag)) {
91+ PHP_V8_THROW_EXCEPTION (" Invalid startup blob (too small)" );
7792 return ;
7893 }
7994
95+ script_compiler_tag version = {};
96+ memcpy (&version, &ZSTR_VAL (blob_string)[0 ], sizeof (script_compiler_tag));
97+
8098 PHP_V8_STARTUP_DATA_FETCH_INTO (getThis (), php_v8_startup_data);
8199
82100 v8::StartupData *blob = new v8::StartupData ();
83- blob->data = (const char *) estrndup (ZSTR_VAL (blob_string), ZSTR_LEN (blob_string));
84- blob->raw_size = static_cast <int >(ZSTR_LEN (blob_string));
85101
86- php_v8_startup_data->blob = new phpv8::StartupData (blob);
102+ blob->data = (const char *) estrndup (&ZSTR_VAL (blob_string)[sizeof (script_compiler_tag)], ZSTR_LEN (blob_string) - sizeof (script_compiler_tag));
103+ blob->raw_size = static_cast <int >(ZSTR_LEN (blob_string) - sizeof (script_compiler_tag));
104+
105+ php_v8_startup_data->blob = new phpv8::StartupData (blob, version);
87106}
88107
89108static PHP_METHOD (StartupData, getData) {
@@ -94,26 +113,34 @@ static PHP_METHOD(StartupData, getData) {
94113 PHP_V8_STARTUP_DATA_FETCH_INTO (getThis (), php_v8_startup_data);
95114
96115 if (php_v8_startup_data->blob && php_v8_startup_data->blob ->hasData ()) {
97- zend_string *out = zend_string_init (php_v8_startup_data->blob ->data ()->data , static_cast <size_t >(php_v8_startup_data->blob ->data ()->raw_size ), 0 );
116+ script_compiler_tag loaded = php_v8_startup_data->blob ->version ();
117+ smart_str my_str = {0 };
118+
119+ smart_str_appendl (&my_str, (char *)&loaded, sizeof (script_compiler_tag));
120+ smart_str_appendl (&my_str, php_v8_startup_data->blob ->data ()->data , static_cast <size_t >(php_v8_startup_data->blob ->data ()->raw_size ));
121+ smart_str_0 (&my_str);
122+
123+ zend_string *out = zend_string_copy (my_str.s );
124+ smart_str_free (&my_str);
125+
98126 RETURN_STR (out);
99127 }
100128
101129 RETURN_EMPTY_STRING ();
102130}
103131
104- static PHP_METHOD (StartupData, getRawSize ) {
132+ static PHP_METHOD (StartupData, isRejected ) {
105133 if (zend_parse_parameters_none () == FAILURE) {
106134 return ;
107135 }
108136
109137 PHP_V8_STARTUP_DATA_FETCH_INTO (getThis (), php_v8_startup_data);
110138
111- if (php_v8_startup_data->blob && php_v8_startup_data->blob ->hasData ()) {
112- RETVAL_LONG (static_cast <zend_long>(php_v8_startup_data->blob ->data ()->raw_size ));
113- return ;
139+ if (php_v8_startup_data->blob ) {
140+ RETURN_BOOL (php_v8_startup_data->blob ->rejected ());
114141 }
115142
116- RETURN_LONG ( 0 );
143+ RETURN_BOOL ( false );
117144}
118145
119146static PHP_METHOD (StartupData, createFromSource) {
@@ -128,7 +155,7 @@ static PHP_METHOD(StartupData, createFromSource) {
128155 const char *source = ZSTR_VAL (blob);
129156 php_v8_init ();
130157
131- v8::StartupData *startup_blob = new v8::StartupData;
158+ v8::StartupData *startup_blob = new v8::StartupData () ;
132159
133160 *startup_blob = v8::V8::CreateSnapshotDataBlob (source);
134161
@@ -175,7 +202,7 @@ ZEND_END_ARG_INFO()
175202PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_getData, ZEND_RETURN_VALUE, 0 , IS_STRING, 0 )
176203ZEND_END_ARG_INFO()
177204
178- PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_getRawSize , ZEND_RETURN_VALUE, 0 , IS_LONG , 0 )
205+ PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_isRejected , ZEND_RETURN_VALUE, 0 , _IS_BOOL , 0 )
179206ZEND_END_ARG_INFO()
180207
181208PHP_V8_ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_createFromSource, ZEND_RETURN_VALUE, 1 , V8\\StartupData, 0 )
@@ -191,7 +218,7 @@ ZEND_END_ARG_INFO()
191218static const zend_function_entry php_v8_startup_data_methods[] = {
192219 PHP_V8_ME (StartupData, __construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
193220 PHP_V8_ME (StartupData, getData, ZEND_ACC_PUBLIC)
194- PHP_V8_ME (StartupData, getRawSize , ZEND_ACC_PUBLIC)
221+ PHP_V8_ME (StartupData, isRejected , ZEND_ACC_PUBLIC)
195222 PHP_V8_ME (StartupData, createFromSource, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
196223 PHP_V8_ME (StartupData, warmUpSnapshotDataBlob, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
197224
0 commit comments