Skip to content

Commit 9e9170b

Browse files
committed
Strings and other pointers should be handled differently
1 parent e966167 commit 9e9170b

File tree

1 file changed

+63
-44
lines changed

1 file changed

+63
-44
lines changed

ext/opcache/zend_file_cache.c

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ static int zend_file_cache_flock(int fd, int type)
9494
(((char*)(ptr) >= (char*)script->mem && (char*)(ptr) < (char*)script->mem + script->size) || \
9595
IS_ACCEL_INTERNED(ptr))
9696
#define SERIALIZE_PTR(ptr) do { \
97+
if (ptr) { \
98+
ZEND_ASSERT(IS_UNSERIALIZED(ptr)); \
99+
(ptr) = (void*)((char*)(ptr) - (char*)script->mem); \
100+
} \
101+
} while (0)
102+
#define UNSERIALIZE_PTR(ptr) do { \
103+
if (ptr) { \
104+
ZEND_ASSERT(IS_SERIALIZED(ptr)); \
105+
(ptr) = (void*)((char*)buf + (size_t)(ptr)); \
106+
} \
107+
} while (0)
108+
#define SERIALIZE_STR(ptr) do { \
97109
if (ptr) { \
98110
if (IS_ACCEL_INTERNED(ptr)) { \
99111
(ptr) = zend_file_cache_serialize_interned((zend_string*)(ptr), info); \
@@ -103,10 +115,10 @@ static int zend_file_cache_flock(int fd, int type)
103115
} \
104116
} \
105117
} while (0)
106-
#define UNSERIALIZE_PTR(ptr) do { \
118+
#define UNSERIALIZE_STR(ptr) do { \
107119
if (ptr) { \
108120
if (IS_SERIALIZED_INTERNED(ptr)) { \
109-
(ptr) = (void*)zend_file_cache_unserialize_interned((zend_string*)(ptr)); \
121+
(ptr) = (void*)zend_file_cache_unserialize_interned((zend_string*)(ptr), script->corrupted); \
110122
} else { \
111123
ZEND_ASSERT(IS_SERIALIZED(ptr)); \
112124
(ptr) = (void*)((char*)buf + (size_t)(ptr)); \
@@ -190,15 +202,20 @@ static void *zend_file_cache_serialize_interned(zend_string *str,
190202
return ret;
191203
}
192204

193-
static void *zend_file_cache_unserialize_interned(zend_string *str)
205+
static void *zend_file_cache_unserialize_interned(zend_string *str, int in_shm)
194206
{
195207
zend_string *ret;
196208

197209
str = (zend_string*)((char*)ZCG(mem) + ((size_t)(str) & ~Z_UL(1)));
198210
ret = accel_new_interned_string(str);
199211
if (ret == str) {
200212
/* String wasn't interned but we will use it as interned anyway */
201-
GC_FLAGS(ret) |= IS_STR_INTERNED | IS_STR_PERMANENT;
213+
if (in_shm) {
214+
GC_FLAGS(ret) |= IS_STR_INTERNED | IS_STR_PERMANENT;
215+
} else {
216+
GC_FLAGS(ret) |= IS_STR_INTERNED;
217+
GC_FLAGS(ret) &= ~IS_STR_PERMANENT;
218+
}
202219
}
203220
return ret;
204221
}
@@ -224,7 +241,7 @@ static void zend_file_cache_serialize_hash(HashTable *ht,
224241
end = p + ht->nNumUsed;
225242
while (p < end) {
226243
if (Z_TYPE(p->val) != IS_UNDEF) {
227-
SERIALIZE_PTR(p->key);
244+
SERIALIZE_STR(p->key);
228245
func(&p->val, script, info, buf);
229246
}
230247
p++;
@@ -272,7 +289,7 @@ static void zend_file_cache_serialize_zval(zval *zv,
272289
case IS_STRING:
273290
case IS_CONSTANT:
274291
if (!IS_SERIALIZED(Z_STR_P(zv))) {
275-
SERIALIZE_PTR(Z_STR_P(zv));
292+
SERIALIZE_STR(Z_STR_P(zv));
276293
}
277294
break;
278295
case IS_ARRAY:
@@ -400,10 +417,10 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
400417
}
401418
while (p < end) {
402419
if (!IS_SERIALIZED(p->name)) {
403-
SERIALIZE_PTR(p->name);
420+
SERIALIZE_STR(p->name);
404421
}
405422
if (!IS_SERIALIZED(p->class_name)) {
406-
SERIALIZE_PTR(p->class_name);
423+
SERIALIZE_STR(p->class_name);
407424
}
408425
p++;
409426
}
@@ -418,17 +435,17 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
418435
end = p + op_array->last_var;
419436
while (p < end) {
420437
if (!IS_SERIALIZED(*p)) {
421-
SERIALIZE_PTR(*p);
438+
SERIALIZE_STR(*p);
422439
}
423440
p++;
424441
}
425442
}
426443

427-
SERIALIZE_PTR(op_array->function_name);
428-
SERIALIZE_PTR(op_array->filename);
444+
SERIALIZE_STR(op_array->function_name);
445+
SERIALIZE_STR(op_array->filename);
429446
SERIALIZE_PTR(op_array->brk_cont_array);
430447
SERIALIZE_PTR(op_array->scope);
431-
SERIALIZE_PTR(op_array->doc_comment);
448+
SERIALIZE_STR(op_array->doc_comment);
432449
SERIALIZE_PTR(op_array->try_catch_array);
433450
SERIALIZE_PTR(op_array->prototype);
434451
}
@@ -463,10 +480,10 @@ static void zend_file_cache_serialize_prop_info(zval *zv,
463480
SERIALIZE_PTR(prop->ce);
464481
}
465482
if (prop->name && !IS_SERIALIZED(prop->name)) {
466-
SERIALIZE_PTR(prop->name);
483+
SERIALIZE_STR(prop->name);
467484
}
468485
if (prop->doc_comment && !IS_SERIALIZED(prop->doc_comment)) {
469-
SERIALIZE_PTR(prop->doc_comment);
486+
SERIALIZE_STR(prop->doc_comment);
470487
}
471488
}
472489
}
@@ -482,7 +499,7 @@ static void zend_file_cache_serialize_class(zval *zv,
482499
ce = Z_PTR_P(zv);
483500
UNSERIALIZE_PTR(ce);
484501

485-
SERIALIZE_PTR(ce->name);
502+
SERIALIZE_STR(ce->name);
486503
zend_file_cache_serialize_hash(&ce->function_table, script, info, buf, zend_file_cache_serialize_func);
487504
if (ce->default_properties_table) {
488505
zval *p, *end;
@@ -509,8 +526,8 @@ static void zend_file_cache_serialize_class(zval *zv,
509526
}
510527
}
511528
zend_file_cache_serialize_hash(&ce->constants_table, script, info, buf, zend_file_cache_serialize_zval);
512-
SERIALIZE_PTR(ZEND_CE_FILENAME(ce));
513-
SERIALIZE_PTR(ZEND_CE_DOC_COMMENT(ce));
529+
SERIALIZE_STR(ZEND_CE_FILENAME(ce));
530+
SERIALIZE_STR(ZEND_CE_DOC_COMMENT(ce));
514531
zend_file_cache_serialize_hash(&ce->properties_info, script, info, buf, zend_file_cache_serialize_prop_info);
515532

516533
if (ce->trait_aliases) {
@@ -533,15 +550,15 @@ static void zend_file_cache_serialize_class(zval *zv,
533550
UNSERIALIZE_PTR(m);
534551

535552
if (m->method_name) {
536-
SERIALIZE_PTR(m->method_name);
553+
SERIALIZE_STR(m->method_name);
537554
}
538555
if (m->class_name) {
539-
SERIALIZE_PTR(m->class_name);
556+
SERIALIZE_STR(m->class_name);
540557
}
541558
}
542559

543560
if (q->alias) {
544-
SERIALIZE_PTR(q->alias);
561+
SERIALIZE_STR(q->alias);
545562
}
546563
p++;
547564
}
@@ -567,10 +584,10 @@ static void zend_file_cache_serialize_class(zval *zv,
567584
UNSERIALIZE_PTR(m);
568585

569586
if (m->method_name) {
570-
SERIALIZE_PTR(m->method_name);
587+
SERIALIZE_STR(m->method_name);
571588
}
572589
if (m->class_name) {
573-
SERIALIZE_PTR(m->class_name);
590+
SERIALIZE_STR(m->class_name);
574591
}
575592
}
576593

@@ -582,7 +599,7 @@ static void zend_file_cache_serialize_class(zval *zv,
582599
UNSERIALIZE_PTR(s);
583600

584601
while (*s) {
585-
SERIALIZE_PTR(*s);
602+
SERIALIZE_STR(*s);
586603
s++;
587604
}
588605
}
@@ -622,7 +639,7 @@ static void zend_file_cache_serialize(zend_persistent_script *script,
622639
memcpy(buf, script->mem, script->size);
623640

624641
new_script = (zend_persistent_script*)((char*)buf + info->script_offset);
625-
SERIALIZE_PTR(new_script->full_path);
642+
SERIALIZE_STR(new_script->full_path);
626643

627644
zend_file_cache_serialize_hash(&new_script->class_table, script, info, buf, zend_file_cache_serialize_class);
628645
zend_file_cache_serialize_hash(&new_script->function_table, script, info, buf, zend_file_cache_serialize_func);
@@ -754,7 +771,7 @@ static void zend_file_cache_unserialize_hash(HashTable *ht,
754771
end = p + ht->nNumUsed;
755772
while (p < end) {
756773
if (Z_TYPE(p->val) != IS_UNDEF) {
757-
UNSERIALIZE_PTR(p->key);
774+
UNSERIALIZE_STR(p->key);
758775
func(&p->val, script, buf);
759776
}
760777
p++;
@@ -797,7 +814,7 @@ static void zend_file_cache_unserialize_zval(zval *zv,
797814
case IS_STRING:
798815
case IS_CONSTANT:
799816
if (!IS_UNSERIALIZED(Z_STR_P(zv))) {
800-
UNSERIALIZE_PTR(Z_STR_P(zv));
817+
UNSERIALIZE_STR(Z_STR_P(zv));
801818
}
802819
break;
803820
case IS_ARRAY:
@@ -914,10 +931,10 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
914931
}
915932
while (p < end) {
916933
if (!IS_UNSERIALIZED(p->name)) {
917-
UNSERIALIZE_PTR(p->name);
934+
UNSERIALIZE_STR(p->name);
918935
}
919936
if (!IS_UNSERIALIZED(p->class_name)) {
920-
UNSERIALIZE_PTR(p->class_name);
937+
UNSERIALIZE_STR(p->class_name);
921938
}
922939
p++;
923940
}
@@ -931,17 +948,17 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
931948
end = p + op_array->last_var;
932949
while (p < end) {
933950
if (!IS_UNSERIALIZED(*p)) {
934-
UNSERIALIZE_PTR(*p);
951+
UNSERIALIZE_STR(*p);
935952
}
936953
p++;
937954
}
938955
}
939956

940-
UNSERIALIZE_PTR(op_array->function_name);
941-
UNSERIALIZE_PTR(op_array->filename);
957+
UNSERIALIZE_STR(op_array->function_name);
958+
UNSERIALIZE_STR(op_array->filename);
942959
UNSERIALIZE_PTR(op_array->brk_cont_array);
943960
UNSERIALIZE_PTR(op_array->scope);
944-
UNSERIALIZE_PTR(op_array->doc_comment);
961+
UNSERIALIZE_STR(op_array->doc_comment);
945962
UNSERIALIZE_PTR(op_array->try_catch_array);
946963
UNSERIALIZE_PTR(op_array->prototype);
947964
}
@@ -972,10 +989,10 @@ static void zend_file_cache_unserialize_prop_info(zval *zv,
972989
UNSERIALIZE_PTR(prop->ce);
973990
}
974991
if (prop->name && !IS_UNSERIALIZED(prop->name)) {
975-
UNSERIALIZE_PTR(prop->name);
992+
UNSERIALIZE_STR(prop->name);
976993
}
977994
if (prop->doc_comment && !IS_UNSERIALIZED(prop->doc_comment)) {
978-
UNSERIALIZE_PTR(prop->doc_comment);
995+
UNSERIALIZE_STR(prop->doc_comment);
979996
}
980997
}
981998
}
@@ -989,7 +1006,7 @@ static void zend_file_cache_unserialize_class(zval *zv,
9891006
UNSERIALIZE_PTR(Z_PTR_P(zv));
9901007
ce = Z_PTR_P(zv);
9911008

992-
UNSERIALIZE_PTR(ce->name);
1009+
UNSERIALIZE_STR(ce->name);
9931010
zend_file_cache_unserialize_hash(&ce->function_table, script, buf, zend_file_cache_unserialize_func);
9941011
if (ce->default_properties_table) {
9951012
zval *p, *end;
@@ -1014,8 +1031,8 @@ static void zend_file_cache_unserialize_class(zval *zv,
10141031
}
10151032
}
10161033
zend_file_cache_unserialize_hash(&ce->constants_table, script, buf, zend_file_cache_unserialize_zval);
1017-
UNSERIALIZE_PTR(ZEND_CE_FILENAME(ce));
1018-
UNSERIALIZE_PTR(ZEND_CE_DOC_COMMENT(ce));
1034+
UNSERIALIZE_STR(ZEND_CE_FILENAME(ce));
1035+
UNSERIALIZE_STR(ZEND_CE_DOC_COMMENT(ce));
10191036
zend_file_cache_unserialize_hash(&ce->properties_info, script, buf, zend_file_cache_unserialize_prop_info);
10201037

10211038
if (ce->trait_aliases) {
@@ -1035,15 +1052,15 @@ static void zend_file_cache_unserialize_class(zval *zv,
10351052
m = q->trait_method;
10361053

10371054
if (m->method_name) {
1038-
UNSERIALIZE_PTR(m->method_name);
1055+
UNSERIALIZE_STR(m->method_name);
10391056
}
10401057
if (m->class_name) {
1041-
UNSERIALIZE_PTR(m->class_name);
1058+
UNSERIALIZE_STR(m->class_name);
10421059
}
10431060
}
10441061

10451062
if (q->alias) {
1046-
UNSERIALIZE_PTR(q->alias);
1063+
UNSERIALIZE_STR(q->alias);
10471064
}
10481065
p++;
10491066
}
@@ -1066,10 +1083,10 @@ static void zend_file_cache_unserialize_class(zval *zv,
10661083
m = q->trait_method;
10671084

10681085
if (m->method_name) {
1069-
UNSERIALIZE_PTR(m->method_name);
1086+
UNSERIALIZE_STR(m->method_name);
10701087
}
10711088
if (m->class_name) {
1072-
UNSERIALIZE_PTR(m->class_name);
1089+
UNSERIALIZE_STR(m->class_name);
10731090
}
10741091
}
10751092

@@ -1080,7 +1097,7 @@ static void zend_file_cache_unserialize_class(zval *zv,
10801097
s = (zend_string**)q->exclude_from_classes;
10811098

10821099
while (*s) {
1083-
UNSERIALIZE_PTR(*s);
1100+
UNSERIALIZE_STR(*s);
10841101
s++;
10851102
}
10861103
}
@@ -1109,7 +1126,7 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
11091126
{
11101127
script->mem = buf;
11111128

1112-
UNSERIALIZE_PTR(script->full_path);
1129+
UNSERIALIZE_STR(script->full_path);
11131130

11141131
zend_file_cache_unserialize_hash(&script->class_table, script, buf, zend_file_cache_unserialize_class);
11151132
zend_file_cache_unserialize_hash(&script->function_table, script, buf, zend_file_cache_unserialize_func);
@@ -1266,7 +1283,9 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
12661283

12671284
ZCG(mem) = ((char*)mem + info.mem_size);
12681285
script = (zend_persistent_script*)((char*)buf + info.script_offset);
1286+
script->corrupted = cache_it; /* used to check if script restored to SHM or process memory */
12691287
zend_file_cache_unserialize(script, buf);
1288+
script->corrupted = 0;
12701289

12711290
if (cache_it) {
12721291
script->dynamic_members.checksum = zend_accel_script_checksum(script);

0 commit comments

Comments
 (0)