summaryrefslogtreecommitdiffstats
path: root/apcu-upstream.patch
blob: 9170b6a7d76cb29b24951b88b3392ebb43e4d05b (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
diff --git a/apc_arginfo.h b/apc_arginfo.h
index 0bd61c9..8ba2686 100644
--- a/apc_arginfo.h
+++ b/apc_arginfo.h
@@ -76,6 +76,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_entry, 0, 0, 2)
 	ZEND_ARG_TYPE_INFO(0, generator, IS_CALLABLE, 0)
 	ZEND_ARG_TYPE_INFO(0, ttl, IS_LONG, 0)
 ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_apcu_inc_request_time, 0, 0, 0)
+	ZEND_ARG_INFO(0, by)
+ZEND_END_ARG_INFO()
 /* }}} */
 
 #endif
diff --git a/apc_globals.h b/apc_globals.h
index 74c8f27..87625c9 100644
--- a/apc_globals.h
+++ b/apc_globals.h
@@ -62,7 +62,7 @@ ZEND_BEGIN_MODULE_GLOBALS(apcu)
 
 	char *serializer_name;       /* the serializer config option */
 
-	volatile zend_bool recursion;
+	volatile unsigned recursion;
 ZEND_END_MODULE_GLOBALS(apcu)
 
 /* (the following is defined in php_apc.c) */
diff --git a/apc_iterator.c b/apc_iterator.c
index 302b086..f601a27 100644
--- a/apc_iterator.c
+++ b/apc_iterator.c
@@ -297,7 +297,8 @@ static void apc_iterator_totals(apc_iterator_t *iterator) {
 void apc_iterator_obj_init(apc_iterator_t *iterator, zval *search, zend_long format, zend_long chunk_size, zend_long list)
 {
 	if (!APCG(enabled)) {
-		apc_error("APC must be enabled to use " APC_ITERATOR_NAME);
+		zend_throw_error(NULL, "APC must be enabled to use " APC_ITERATOR_NAME);
+		return;
 	}
 
 	if (chunk_size < 0) {
diff --git a/apc_signal.c b/apc_signal.c
index aff13c8..22504e5 100644
--- a/apc_signal.c
+++ b/apc_signal.c
@@ -113,7 +113,7 @@ static void apc_rehandle_signal(int signo, siginfo_t *siginfo, void *context)
  */
 static int apc_register_signal(int signo, void (*handler)(int, siginfo_t*, void*))
 {
-	struct sigaction sa = {{0}};
+	struct sigaction sa;
 	apc_signal_entry_t p_sig = {0};
 
 	if (sigaction(signo, NULL, &sa) == 0) {
diff --git a/apc_sma.c b/apc_sma.c
index da457d3..3150d92 100644
--- a/apc_sma.c
+++ b/apc_sma.c
@@ -234,8 +234,8 @@ static APC_HOTSPOT size_t sma_deallocate(void* shmaddr, size_t offset)
 	block_t* nxt;       /* the block after cur */
 	size_t size;        /* size of deallocated block */
 
+	assert(offset >= ALIGNWORD(sizeof(struct block_t)));
 	offset -= ALIGNWORD(sizeof(struct block_t));
-	assert(offset >= 0);
 
 	/* find position of new block in free list */
 	cur = BLOCKAT(offset);
diff --git a/php_apc.c b/php_apc.c
index ad9351d..e08a770 100644
--- a/php_apc.c
+++ b/php_apc.c
@@ -93,7 +93,7 @@ static void php_apc_init_globals(zend_apcu_globals* apcu_globals)
 	apcu_globals->smart = 0;
 	apcu_globals->preload_path = NULL;
 	apcu_globals->coredump_unmap = 0;
-	apcu_globals->use_request_time = 1;
+	apcu_globals->use_request_time = 0;
 	apcu_globals->serializer_name = NULL;
 	apcu_globals->recursion = 0;
 }
@@ -151,7 +151,7 @@ STD_PHP_INI_BOOLEAN("apc.enable_cli",   "0",    PHP_INI_SYSTEM, OnUpdateBool,
 STD_PHP_INI_BOOLEAN("apc.slam_defense", "0",    PHP_INI_SYSTEM, OnUpdateBool,              slam_defense,     zend_apcu_globals, apcu_globals)
 STD_PHP_INI_ENTRY("apc.preload_path", (char*)NULL,              PHP_INI_SYSTEM, OnUpdateString,       preload_path,  zend_apcu_globals, apcu_globals)
 STD_PHP_INI_BOOLEAN("apc.coredump_unmap", "0", PHP_INI_SYSTEM, OnUpdateBool, coredump_unmap, zend_apcu_globals, apcu_globals)
-STD_PHP_INI_BOOLEAN("apc.use_request_time", "1", PHP_INI_ALL, OnUpdateBool, use_request_time,  zend_apcu_globals, apcu_globals)
+STD_PHP_INI_BOOLEAN("apc.use_request_time", "0", PHP_INI_ALL, OnUpdateBool, use_request_time,  zend_apcu_globals, apcu_globals)
 STD_PHP_INI_ENTRY("apc.serializer", "php", PHP_INI_SYSTEM, OnUpdateStringUnempty, serializer_name, zend_apcu_globals, apcu_globals)
 PHP_INI_END()
 
@@ -475,12 +475,14 @@ static void apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const zend_bool exclu
 		ZEND_HASH_FOREACH_KEY_VAL(hash, hkey_idx, hkey, hentry) {
 			ZVAL_DEREF(hentry);
 			if (hkey) {
-				if (!apc_cache_store(apc_user_cache, hkey, hentry, (uint32_t) ttl, exclusive)) {
-					zend_hash_add_new(Z_ARRVAL_P(return_value), hkey, &fail_zv);
-				}
+				zend_string_addref(hkey);
 			} else {
-				zend_hash_index_add_new(Z_ARRVAL_P(return_value), hkey_idx, &fail_zv);
+				hkey = zend_long_to_str(hkey_idx);
+			}
+			if (!apc_cache_store(apc_user_cache, hkey, hentry, (uint32_t) ttl, exclusive)) {
+				zend_symtable_add_new(Z_ARRVAL_P(return_value), hkey, &fail_zv);
 			}
+			zend_string_release(hkey);
 		} ZEND_HASH_FOREACH_END();
 		return;
 	} else if (Z_TYPE_P(key) == IS_STRING) {
@@ -500,6 +502,9 @@ static void apc_store_helper(INTERNAL_FUNCTION_PARAMETERS, const zend_bool exclu
 /* {{{ proto bool apcu_enabled(void)
 	returns true when apcu is usable in the current environment */
 PHP_FUNCTION(apcu_enabled) {
+	if (zend_parse_parameters_none() == FAILURE) {
+		return;
+	}
 	RETURN_BOOL(APCG(enabled));
 }
 /* }}} */
@@ -798,7 +803,7 @@ zend_function_entry apcu_functions[] = {
 	PHP_FE(apcu_exists,             arginfo_apcu_exists)
 	PHP_FE(apcu_entry,				arginfo_apcu_entry)
 #ifdef APC_DEBUG
-	PHP_FE(apcu_inc_request_time,   NULL)
+	PHP_FE(apcu_inc_request_time,   arginfo_apcu_inc_request_time)
 #endif
 	PHP_FE_END
 };
diff --git a/tests/apc_disabled.phpt b/tests/apc_disabled.phpt
index 184a759..c3f9adf 100644
--- a/tests/apc_disabled.phpt
+++ b/tests/apc_disabled.phpt
@@ -40,6 +40,13 @@ var_dump(apcu_cas("key", 10, 20));
 echo "\nentry\n";
 var_dump(apcu_entry("key", function() { return 42; }));
 
+echo "\niterator\n";
+try {
+    new APCUIterator;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+
 ?>
 --EXPECTF--
 enabled
@@ -91,3 +98,6 @@ bool(false)
 
 entry
 NULL
+
+iterator
+APC must be enabled to use APCuIterator
diff --git a/tests/apc_entry_003.phpt b/tests/apc_entry_003.phpt
index f066583..e04bf4b 100644
--- a/tests/apc_entry_003.phpt
+++ b/tests/apc_entry_003.phpt
@@ -13,4 +13,4 @@ $value = apcu_entry("test", function($key) {
 });
 ?>
 --EXPECTF--
-Fatal error: Trait 'T' not found in %s on line %d
+Fatal error: %s
diff --git a/tests/apc_store_array_int_keys.phpt b/tests/apc_store_array_int_keys.phpt
new file mode 100644
index 0000000..654f70c
--- /dev/null
+++ b/tests/apc_store_array_int_keys.phpt
@@ -0,0 +1,26 @@
+--TEST--
+apcu_store() with int keys in array should convert them to string
+--SKIPIF--
+<?php
+require_once(__DIR__ . '/skipif.inc');
+?>
+--INI--
+apc.enabled=1
+apc.enable_cli=1
+--FILE--
+<?php
+
+var_dump(apcu_add(["123" => "test"]));
+var_dump(apcu_store(["123" => "test"]));
+var_dump(apcu_add(["123" => "test"]));
+
+?>
+--EXPECT--
+array(0) {
+}
+array(0) {
+}
+array(1) {
+  [123]=>
+  int(-1)
+}
diff --git a/tests/apc_store_reference.phpt b/tests/apc_store_reference.phpt
index 2228899..d2cb991 100644
--- a/tests/apc_store_reference.phpt
+++ b/tests/apc_store_reference.phpt
@@ -4,6 +4,8 @@ The outermost value should always be a value, not a reference
 apc.enabled=1
 apc.enable_cli=1
 apc.serializer=default
+--SKIPIF--
+<?php if (PHP_VERSION_ID >= 80000) die('skip Requires PHP < 8.0.0'); ?>
 --FILE--
 <?php
 
diff --git a/tests/apc_store_reference_php8.phpt b/tests/apc_store_reference_php8.phpt
new file mode 100644
index 0000000..1eae4bb
--- /dev/null
+++ b/tests/apc_store_reference_php8.phpt
@@ -0,0 +1,26 @@
+--TEST--
+The outermost value should always be a value, not a reference
+--INI--
+apc.enabled=1
+apc.enable_cli=1
+apc.serializer=default
+--SKIPIF--
+<?php if (PHP_VERSION_ID < 80000) die('skip Requires PHP >= 8.0.0'); ?>
+--FILE--
+<?php
+
+/* The output is different for the php serializer, because it does not replicate the
+ * cycle involving the top-level value. Instead the cycle is placed one level lower.
+ * I believe this is a bug in the php serializer. */
+
+$value = [&$value];
+apcu_store(["key" => &$value]);
+$result = apcu_fetch("key");
+var_dump($result);
+
+?>
+--EXPECT--
+array(1) {
+  [0]=>
+  *RECURSION*
+}
diff --git a/tests/server_test.inc b/tests/server_test.inc
index 2aede0c..75035a3 100644
--- a/tests/server_test.inc
+++ b/tests/server_test.inc
@@ -44,6 +44,7 @@ function server_start_one($host, $port, $code = 'echo "Hello world";', $php_opts
 			$cmd .= " {$router}";
 		}
 
+		$descriptorspec[2] = array('pipe', 'w');
 		$handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true,  "suppress_errors" => true));
 	} else {
 		$cmd = "exec {$php_executable} -n $php_args -t {$doc_root} -S $host:$port";