summaryrefslogtreecommitdiffstats
path: root/uopz-php8.patch
blob: 200fd2d902eb54b70a6a79f4430af09ef31d8857 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
From ce0b480bd6446c81b909451cebd54fb8c53c8590 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Fri, 21 Aug 2020 10:13:33 +0200
Subject: [PATCH 3/7] Skip unsupported tests on PHP 7.4+ with OPcache

As of PHP 7.4.0, uopz can no longer support manipulation of immutable
classes and functions when OPcache is enabled.  Therefore, we skip the
respective test cases under these conditions.

We also have to make sure that the `die()`s are actually executed.
---
 tests/016.phpt       | 12 +++++++++++-
 tests/bugs/gh76.phpt |  8 ++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/tests/016.phpt b/tests/016.phpt
index 3d65ea4..79e9b3a 100644
--- a/tests/016.phpt
+++ b/tests/016.phpt
@@ -1,7 +1,17 @@
 --TEST--
 uopz_flags
 --SKIPIF--
-<?php include("skipif.inc") ?>
+<?php
+include("skipif.inc");
+uopz_allow_exit(true);
+if (version_compare(PHP_VERSION, '7.4', '>=')
+	&& function_exists('opcache_get_status')
+	&& ($status = opcache_get_status())
+	&& $status['opcache_enabled'])
+{
+	die('skip not for PHP 7.4+ with OPcache');
+}
+?>
 --INI--
 uopz.disable=0
 --FILE--
diff --git a/tests/bugs/gh76.phpt b/tests/bugs/gh76.phpt
index 62680c3..ef09976 100644
--- a/tests/bugs/gh76.phpt
+++ b/tests/bugs/gh76.phpt
@@ -3,6 +3,14 @@ uopz_extend affects only explicit calls via parent:: but not inherited methods
 --SKIPIF--
 <?php
 include(__DIR__ . '/../skipif.inc');
+uopz_allow_exit(true);
+if (version_compare(PHP_VERSION, '7.4', '>=')
+	&& function_exists('opcache_get_status')
+	&& ($status = opcache_get_status())
+	&& $status['opcache_enabled'])
+{
+	die('skip not for PHP 7.4+ with OPcache');
+}
 ?>
 --INI--
 uopz.disable=0
-- 
2.29.2

From 0f975b64248ecc0af579370e1266b0cfc5775c69 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Thu, 20 Aug 2020 16:23:34 +0200
Subject: [PATCH 4/7] Don't remove methods of immutable classes

These are not fully reloaded by OPcache, so the methods would be
missing after the first request shutdown.

Cf. <https://github.com/php/php-src/blob/php-7.4.9/UPGRADING.INTERNALS#L139-L141>.
---
 src/util.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/util.c b/src/util.c
index 707b236..fce1fd3 100644
--- a/src/util.c
+++ b/src/util.c
@@ -169,7 +169,12 @@ int uopz_clean_function(zval *zv) { /* {{{ */
 
 int uopz_clean_class(zval *zv) { /* {{{ */
 	zend_class_entry *ce = Z_PTR_P(zv);
-	
+
+#if PHP_VERSION_ID >= 70400
+	if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
+		return ZEND_HASH_APPLY_KEEP;
+	}
+#endif
 	zend_hash_apply(
 		&ce->function_table, uopz_clean_function);
 	
-- 
2.29.2

From cfaa8987096117eb0c921ef0c927320b4831b725 Mon Sep 17 00:00:00 2001
From: Joe Watkins <krakjoe@php.net>
Date: Thu, 1 Oct 2020 10:12:07 +0200
Subject: [PATCH 5/7] php 8 support

---
 src/class.c           | 14 ++++++++++++++
 src/copy.c            |  9 ++++++++-
 src/function.c        |  8 ++++++--
 src/handlers.c        | 20 +++++++++++++++++---
 src/hook.c            |  4 ++++
 src/return.c          |  4 ++++
 src/util.c            | 12 +++++++++++-
 tests/012.phpt        |  2 +-
 tests/018.phpt        |  4 ++--
 tests/035.phpt        |  2 +-
 tests/040.phpt        |  2 +-
 tests/bugs/gh102.phpt |  2 +-
 uopz.c                | 16 ++++++++++++++--
 13 files changed, 84 insertions(+), 15 deletions(-)

diff --git a/src/class.c b/src/class.c
index 95fa0f2..555577e 100644
--- a/src/class.c
+++ b/src/class.c
@@ -220,6 +220,10 @@ zend_bool uopz_implement(zend_class_entry *clazz, zend_class_entry *interface) {
 
 	zend_do_implement_interface(clazz, interface);
 
+#if PHP_VERSION_ID >= 80000
+	clazz->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES;
+#endif
+
 	return instanceof_function(clazz, interface);
 } /* }}} */
 
@@ -246,8 +250,13 @@ void uopz_set_property(zval *object, zval *member, zval *value) { /* {{{ */
 		uopz_set_scope(Z_OBJCE_P(object));
 	}
 
+#if PHP_VERSION_ID >= 80000
+	Z_OBJ_HT_P(object)
+		->write_property(Z_OBJ_P(object), Z_STR_P(member), value, NULL);
+#else
 	Z_OBJ_HT_P(object)
 		->write_property(object, member, value, NULL);
+#endif
 
 	uopz_set_scope(scope);
 } /* }}} */
@@ -276,8 +285,13 @@ void uopz_get_property(zval *object, zval *member, zval *value) { /* {{{ */
 		uopz_set_scope(Z_OBJCE_P(object));
 	}
 
+#if PHP_VERSION_ID >= 80000
+	prop = Z_OBJ_HT_P(object)->read_property(
+		Z_OBJ_P(object), Z_STR_P(member), BP_VAR_R, NULL, &rv);
+#else
 	prop = Z_OBJ_HT_P(object)->read_property(
 		object, member, BP_VAR_R, NULL, &rv);
+#endif
 
 	uopz_set_scope(scope);
 
diff --git a/src/copy.c b/src/copy.c
index 11b1414..c8ddb0e 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -176,7 +176,14 @@ static inline zend_arg_info* uopz_copy_arginfo(zend_op_array *op_array, zend_arg
 	while (it < end) {
 		if (info[it].name)
 			info[it].name = zend_string_copy(old[it].name);
-#if PHP_VERSION_ID >= 70200
+#if PHP_VERSION_ID >= 80000
+		if (ZEND_TYPE_IS_SET(old[it].type) && ZEND_TYPE_HAS_CLASS(old[it].type)) {
+			info[it].type = (zend_type) ZEND_TYPE_INIT_CLASS(
+				zend_string_copy(
+					ZEND_TYPE_NAME(info[it].type)), 
+				ZEND_TYPE_ALLOW_NULL(info[it].type), 0);
+		}		
+#elif PHP_VERSION_ID >= 70200
 		if (ZEND_TYPE_IS_SET(old[it].type) && ZEND_TYPE_IS_CLASS(old[it].type)) {
 			info[it].type = ZEND_TYPE_ENCODE_CLASS(
 				zend_string_copy(
diff --git a/src/function.c b/src/function.c
index 8ce6c72..4245bd2 100644
--- a/src/function.c
+++ b/src/function.c
@@ -60,11 +60,15 @@ zend_bool uopz_add_function(zend_class_entry *clazz, zend_string *name, zval *cl
 
 	zend_hash_update(functions, key, closure);
 	zval_copy_ctor(closure);
-
+#if PHP_VERSION_ID >= 80000
+	function = uopz_copy_closure(clazz, 
+			(zend_function*) zend_get_closure_method_def(Z_OBJ_P(closure)),
+			flags);
+#else
 	function = uopz_copy_closure(clazz, 
 			(zend_function*) zend_get_closure_method_def(closure),
 			flags);
-
+#endif
 	zend_hash_update_ptr(table, key, (void*) function);
 
 	if (clazz) {
diff --git a/src/handlers.c b/src/handlers.c
index aadf504..a71cc53 100644
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -143,8 +143,14 @@ UOPZ_HANDLERS_DECL_BEGIN()
 	UOPZ_HANDLER_DECL(ZEND_INIT_STATIC_METHOD_CALL, init_static_method_call)
 UOPZ_HANDLERS_DECL_END()
 
+#if PHP_VERSION_ID >= 80000
+static zend_always_inline zval* uopz_get_zval(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data) {
+#else
 static zend_always_inline zval* uopz_get_zval(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type) {
-#if PHP_VERSION_ID >= 70300
+#endif
+#if PHP_VERSION_ID >= 80000
+	return zend_get_zval_ptr(opline, op_type, node, execute_data);
+#elif PHP_VERSION_ID >= 70300
 	return zend_get_zval_ptr(opline, op_type, node, execute_data, should_free, type);
 #else
 	return zend_get_zval_ptr(op_type, node, execute_data, should_free, type);
@@ -234,7 +240,9 @@ static zend_always_inline int _uopz_vm_dispatch(UOPZ_OPCODE_HANDLER_ARGS) {
 int uopz_vm_exit(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
 	UOPZ_USE_OPLINE;
 	zval *estatus;
+#if PHP_VERSION_ID < 80000
 	zend_free_op free_op1;
+#endif
 
 	if (UOPZ(exit)) {
 		UOPZ_VM_DISPATCH();
@@ -245,8 +253,12 @@ int uopz_vm_exit(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
 				opline,
 				opline->op1_type,
 				&opline->op1,
-				execute_data,
-				&free_op1, BP_VAR_R);
+				execute_data
+#if PHP_VERSION_ID < 80000
+				, &free_op1, BP_VAR_R);
+#else
+				);
+#endif
 
 		do {
 			if (Z_TYPE_P(estatus) == IS_LONG) {
@@ -263,9 +275,11 @@ int uopz_vm_exit(UOPZ_OPCODE_HANDLER_ARGS) { /* {{{ */
 			}
 		} while (0);
 
+#if PHP_VERSION_ID < 80000
 		if (free_op1) {
 			zval_ptr_dtor_nogc(free_op1);
 		}
+#endif
 
 		ZVAL_COPY(&UOPZ(estatus), estatus);
 	}
diff --git a/src/hook.c b/src/hook.c
index 7319ac7..6c03c02 100644
--- a/src/hook.c
+++ b/src/hook.c
@@ -162,7 +162,11 @@ void uopz_execute_hook(uopz_hook_t *uhook, zend_execute_data *execute_data, zend
 
 	uhook->busy = 1;
 
+#if PHP_VERSION_ID >= 80000
+	zend_create_closure(&closure, (zend_function*) zend_get_closure_method_def(Z_OBJ(uhook->closure)), 
+#else
 	zend_create_closure(&closure, (zend_function*) zend_get_closure_method_def(&uhook->closure), 
+#endif
 		uhook->clazz, uhook->clazz, Z_OBJ(EX(This)) ? &EX(This) : NULL);
 
 	zend_fcall_info_init(&closure, 0, &fci, &fcc, NULL, &error);
diff --git a/src/return.c b/src/return.c
index f47948b..3b6b0c0 100644
--- a/src/return.c
+++ b/src/return.c
@@ -172,7 +172,11 @@ void uopz_execute_return(uopz_return_t *ureturn, zend_execute_data *execute_data
 
 	ureturn->flags ^= UOPZ_RETURN_BUSY;
 
+#if PHP_VERSION_ID >= 80000
+	zend_create_closure(&closure, (zend_function*) zend_get_closure_method_def(Z_OBJ(ureturn->value)), 
+#else
 	zend_create_closure(&closure, (zend_function*) zend_get_closure_method_def(&ureturn->value), 
+#endif
 		ureturn->clazz, ureturn->clazz, Z_OBJ(EX(This)) ? &EX(This) : NULL);
 
 	zend_fcall_info_init(&closure, 0, &fci, &fcc, NULL, &error);
diff --git a/src/util.c b/src/util.c
index 707b236..311e1cb 100644
--- a/src/util.c
+++ b/src/util.c
@@ -90,8 +90,13 @@ void uopz_handle_magic(zend_class_entry *clazz, zend_string *name, zend_function
 				case 7: clazz->__call = function; break;
 				case 8: clazz->__callstatic = function; break;
 				case 9: clazz->__tostring = function; break;
+#if PHP_VERSION_ID >= 80000
+				case 10: clazz->__serialize = function; break;
+				case 11: clazz->__unserialize = function; break;
+#else
 				case 10: clazz->serialize_func = function; break;
 				case 11: clazz->unserialize_func = function; break;
+#endif
 				case 12: clazz->__debugInfo = function; break;
 			}
 			return;
@@ -148,7 +153,11 @@ zend_bool uopz_is_magic_method(zend_class_entry *clazz, zend_string *function) /
 } /* }}} */
 
 static inline int uopz_closure_equals(zval *closure, zend_function *function) { /* {{{ */
+#if PHP_VERSION_ID >= 80000
+	const zend_function *cmp = zend_get_closure_method_def(Z_OBJ_P(closure));
+#else
 	const zend_function *cmp = zend_get_closure_method_def(closure);
+#endif
 
 	if (cmp->common.prototype == function) {
 		return 1;
@@ -160,7 +169,8 @@ static inline int uopz_closure_equals(zval *closure, zend_function *function) {
 int uopz_clean_function(zval *zv) { /* {{{ */
 	zend_function *fp = Z_PTR_P(zv);
 
-	if (fp->type == ZEND_USER_FUNCTION) {
+	if (fp->type == ZEND_USER_FUNCTION && *((zend_op_array*)fp)->refcount > 1) {
+
 		return ZEND_HASH_APPLY_REMOVE;
 	}
 
diff --git a/tests/012.phpt b/tests/012.phpt
index 018a231..2f3c6b7 100644
--- a/tests/012.phpt
+++ b/tests/012.phpt
@@ -82,7 +82,7 @@ string(%d) "string"
 string(%d) "clone"
 bool(true)
 bool(true)
-string(50) "Call to private method Foo::priv() from context ''"
+string(%d) "Call to private method Foo::priv() from %s"
 string(%d) "will not replace existing method %s::%s, use uopz_set_return instead"
 string(%d) "will not replace existing function %s, use uopz_set_return instead"
 string(%d) "__destruct"
diff --git a/tests/018.phpt b/tests/018.phpt
index 7d959bb..e570ca1 100644
--- a/tests/018.phpt
+++ b/tests/018.phpt
@@ -15,7 +15,7 @@ const UOPZ_DEFINED = "DEFINED";
 
 var_dump(uopz_undefine("UOPZ_DEFINED"));
 
-var_dump(@constant("UOPZ_DEFINED"));
+var_dump(defined("UOPZ_DEFINED"));
 
 var_dump(FOO::BAR);
 
@@ -39,7 +39,7 @@ try {
 ?>
 --EXPECT--
 bool(true)
-NULL
+bool(false)
 int(1)
 int(1)
 bool(false)
diff --git a/tests/035.phpt b/tests/035.phpt
index 96c8141..70f52d2 100644
--- a/tests/035.phpt
+++ b/tests/035.phpt
@@ -6,7 +6,7 @@ fetch class constant non existent class
 <?php
 var_dump(Test::none);
 --EXPECTF--
-Fatal error: Uncaught Error: Class 'Test' not found in %s:2
+Fatal error: Uncaught Error: Class %s not found in %s:2
 Stack trace:
 #0 {main}
   thrown in %s on line 2
diff --git a/tests/040.phpt b/tests/040.phpt
index 8098808..b19b3c2 100644
--- a/tests/040.phpt
+++ b/tests/040.phpt
@@ -7,7 +7,7 @@ error_reporting=32759
 uopz.disable=0
 --FILE--
 <?php
-var_dump($class::qux());
+var_dump(@$class::qux());
 ?>
 --EXPECTF--
 Fatal error: Uncaught Error: Class name must be a valid object or a string in %s:%d
diff --git a/tests/bugs/gh102.phpt b/tests/bugs/gh102.phpt
index 27d6ffc..74ede15 100644
--- a/tests/bugs/gh102.phpt
+++ b/tests/bugs/gh102.phpt
@@ -16,7 +16,7 @@ uopz_undefine('Test\UNDEF');
 var_dump(Test\UNDEF);
 ?>
 --EXPECTF--
-Fatal error: Uncaught Error: Undefined constant 'Test\UNDEF' in %s:7
+Fatal error: Uncaught Error: Undefined constant %s in %s:7
 Stack trace:
 #0 {main}
   thrown in %s on line 7
diff --git a/uopz.c b/uopz.c
index f6d9900..311ddc3 100644
--- a/uopz.c
+++ b/uopz.c
@@ -651,7 +651,19 @@ static PHP_FUNCTION(uopz_allow_exit) {
 
 /* {{{ uopz_functions[]
  */
-#define UOPZ_FE(f) PHP_FE(f, NULL)
+#if PHP_VERSION_ID >= 80000
+ZEND_BEGIN_ARG_INFO(uopz_ignore_arginfo, 1)
+	ZEND_ARG_VARIADIC_INFO(0, arguments)
+ZEND_END_ARG_INFO()
+# define UOPZ_FE(f) PHP_FE(f, uopz_ignore_arginfo)
+#else
+# define UOPZ_FE(f) PHP_FE(f, NULL)
+#endif
+
+ZEND_BEGIN_ARG_INFO(uopz_no_args_arginfo, 0)
+ZEND_END_ARG_INFO()
+# define UOPZ_FE_NOARGS(f) PHP_FE(f, uopz_no_args_arginfo)
+
 static const zend_function_entry uopz_functions[] = {
 	UOPZ_FE(uopz_set_return)
 	UOPZ_FE(uopz_get_return)
@@ -673,7 +685,7 @@ static const zend_function_entry uopz_functions[] = {
 	UOPZ_FE(uopz_undefine)
 	UOPZ_FE(uopz_set_property)
 	UOPZ_FE(uopz_get_property)
-	UOPZ_FE(uopz_get_exit_status)
+	UOPZ_FE_NOARGS(uopz_get_exit_status)
 	UOPZ_FE(uopz_allow_exit)
 
 	UOPZ_FE(uopz_call_user_func)
-- 
2.29.2

From 8ac783d8c151485b5bea8f917a654bb39e1a61d9 Mon Sep 17 00:00:00 2001
From: Joe Watkins <krakjoe@php.net>
Date: Thu, 1 Oct 2020 10:19:01 +0200
Subject: [PATCH 6/7] fix that

---
 src/util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/util.c b/src/util.c
index 311e1cb..fb10d7c 100644
--- a/src/util.c
+++ b/src/util.c
@@ -169,7 +169,7 @@ static inline int uopz_closure_equals(zval *closure, zend_function *function) {
 int uopz_clean_function(zval *zv) { /* {{{ */
 	zend_function *fp = Z_PTR_P(zv);
 
-	if (fp->type == ZEND_USER_FUNCTION && *((zend_op_array*)fp)->refcount > 1) {
+	if (fp->type == ZEND_USER_FUNCTION && (((zend_op_array*)fp)->refcount && *((zend_op_array*)fp)->refcount > 1)) {
 
 		return ZEND_HASH_APPLY_REMOVE;
 	}
-- 
2.29.2

From 7b0ed871029df6e58dfa071315f0979b0bc15868 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Fri, 5 Mar 2021 09:09:38 +0100
Subject: [PATCH 7/7] missing uopz.disable=0 in test

---
 tests/bugs/gh109.phpt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/bugs/gh109.phpt b/tests/bugs/gh109.phpt
index 5d440e4..6020366 100644
--- a/tests/bugs/gh109.phpt
+++ b/tests/bugs/gh109.phpt
@@ -4,6 +4,8 @@ hook closure call inconsistency
 <?php
 include(__DIR__ . '/../skipif.inc');
 ?>
+--INI--
+uopz.disable=0
 --FILE--
 <?php
 
-- 
2.29.2