Skip to content

Commit b8b8809

Browse files
alekittokrakjoe
authored andcommitted
fix bug #76801: phpdbg too many open files error
1 parent 2e9dcce commit b8b8809

File tree

6 files changed

+52
-33
lines changed

6 files changed

+52
-33
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2019, PHP 7.2.18
44

5+
- phpdbg:
6+
. Fixed bug #76801 (too many open files). (alekitto)
7+
58
- Reflection:
69
. Fixed bug #77772 (ReflectionClass::getMethods(null) doesn't work). (Nikita)
710

sapi/phpdbg/phpdbg_list.c

+19-33
Original file line numberDiff line numberDiff line change
@@ -234,62 +234,48 @@ void phpdbg_list_function_byname(const char *str, size_t len) /* {{{ */
234234
/* Note: do not free the original file handler, let original compile_file() or caller do that. Caller may rely on its value to check success */
235235
zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
236236
phpdbg_file_source data, *dataptr;
237-
zend_file_handle fake;
238237
zend_op_array *ret;
239-
char *filename;
240238
uint32_t line;
241239
char *bufptr, *endptr;
240+
int size;
242241

243-
if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) {
244-
return PHPDBG_G(compile_file)(file, type);
242+
ret = PHPDBG_G(compile_file)(file, type);
243+
if (ret == NULL) {
244+
return ret;
245245
}
246246

247-
filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
247+
if (file->type == ZEND_HANDLE_MAPPED) {
248+
data.len = file->handle.stream.mmap.len;
249+
data.buf = emalloc(data.len + 1);
250+
memcpy(data.buf, file->handle.stream.mmap.buf, data.len);
251+
} else {
252+
if (file->type == ZEND_HANDLE_FILENAME) {
253+
zend_stream_open(file->filename, file);
254+
}
248255

249-
data.buf = emalloc(data.len + ZEND_MMAP_AHEAD + 1);
250-
if (data.len > 0) {
251-
memcpy(data.buf, bufptr, data.len);
256+
size = file->handle.stream.fsizer(file->handle.stream.handle);
257+
data.buf = emalloc(size + 1);
258+
data.len = file->handle.stream.reader(file->handle.stream.handle, data.buf, size);
252259
}
253-
memset(data.buf + data.len, 0, ZEND_MMAP_AHEAD + 1);
254-
data.line[0] = 0;
255260

256-
memset(&fake, 0, sizeof(fake));
257-
fake.type = ZEND_HANDLE_MAPPED;
258-
fake.handle.stream.mmap.buf = data.buf;
259-
fake.handle.stream.mmap.len = data.len;
260-
fake.free_filename = 0;
261-
fake.filename = filename;
262-
fake.opened_path = file->opened_path;
261+
memset(data.buf + data.len, 0, 1);
263262

263+
data.line[0] = 0;
264264
*(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint32_t) * data.len)) = data;
265265

266266
for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
267267
if (*bufptr == '\n') {
268268
dataptr->line[++line] = (uint32_t)(bufptr - data.buf) + 1;
269269
}
270270
}
271+
271272
dataptr->lines = ++line;
273+
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint32_t) * line);
272274
dataptr->line[line] = endptr - data.buf;
273275

274-
ret = PHPDBG_G(compile_file)(&fake, type);
275-
276-
if (ret == NULL) {
277-
efree(data.buf);
278-
efree(dataptr);
279-
280-
fake.opened_path = NULL;
281-
zend_file_handle_dtor(&fake);
282-
283-
return NULL;
284-
}
285-
286-
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint32_t) * line);
287276
zend_hash_add_ptr(&PHPDBG_G(file_sources), ret->filename, dataptr);
288277
phpdbg_resolve_pending_file_break(ZSTR_VAL(ret->filename));
289278

290-
fake.opened_path = NULL;
291-
zend_file_handle_dtor(&fake);
292-
293279
return ret;
294280
}
295281

sapi/phpdbg/tests/bug76801.phpt

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
include()ing files should not raise "too many open files" error
3+
--PHPDBG--
4+
r
5+
q
6+
--EXPECTF--
7+
[Successful compilation of %s]
8+
prompt> [Script ended normally]
9+
prompt>
10+
--FILE--
11+
<?php
12+
13+
for ($i = 0; $i < 25000; ++$i) {
14+
include __DIR__.'/empty.inc';
15+
}

sapi/phpdbg/tests/empty.inc

Whitespace-only changes.
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
include_once must include only once #2
3+
--PHPDBG--
4+
r
5+
q
6+
--EXPECTF--
7+
[Successful compilation of %s]
8+
prompt> 1
9+
[Script ended normally]
10+
prompt>
11+
--FILE--
12+
<?php
13+
14+
include __DIR__.'/include.inc';
15+
include_once __DIR__.'/include.inc';

0 commit comments

Comments
 (0)