]> granicus.if.org Git - php/commitdiff
fix bug #76801: phpdbg too many open files error
authorAlessandro Chitolina <alekitto@gmail.com>
Tue, 19 Mar 2019 16:34:34 +0000 (17:34 +0100)
committerJoe Watkins <krakjoe@php.net>
Sat, 23 Mar 2019 08:47:49 +0000 (09:47 +0100)
NEWS
sapi/phpdbg/phpdbg_list.c
sapi/phpdbg/tests/bug76801.phpt [new file with mode: 0644]
sapi/phpdbg/tests/empty.inc [new file with mode: 0644]
sapi/phpdbg/tests/include_once_001.phpt [moved from sapi/phpdbg/tests/include_once.phpt with 100% similarity]
sapi/phpdbg/tests/include_once_002.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index dbce1af2995dba7707a5035b4f7c61c56e00e32c..d2e5043518599c74a368a285285c8f6d65bbe840 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2019, PHP 7.2.18
 
+- phpdbg:
+  . Fixed bug #76801 (too many open files). (alekitto)
+
 - Reflection:
   . Fixed bug #77772 (ReflectionClass::getMethods(null) doesn't work). (Nikita)
 
index 865f75bc27cbcd7338533a16e22b584fe29ab830..cb0250e9e08fd22fdd5b2fc47b9b99bdc15822b3 100644 (file)
@@ -234,33 +234,33 @@ void phpdbg_list_function_byname(const char *str, size_t len) /* {{{ */
 /* 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 */
 zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
        phpdbg_file_source data, *dataptr;
-       zend_file_handle fake;
        zend_op_array *ret;
-       char *filename;
        uint32_t line;
        char *bufptr, *endptr;
+       int size;
 
-       if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) {
-               return PHPDBG_G(compile_file)(file, type);
+       ret = PHPDBG_G(compile_file)(file, type);
+       if (ret == NULL) {
+               return ret;
        }
 
-       filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
+       if (file->type == ZEND_HANDLE_MAPPED) {
+               data.len = file->handle.stream.mmap.len;
+               data.buf = emalloc(data.len + 1);
+               memcpy(data.buf, file->handle.stream.mmap.buf, data.len);
+       } else {
+               if (file->type == ZEND_HANDLE_FILENAME) {
+                       zend_stream_open(file->filename, file);
+               }
 
-       data.buf = emalloc(data.len + ZEND_MMAP_AHEAD + 1);
-       if (data.len > 0) {
-               memcpy(data.buf, bufptr, data.len);
+               size = file->handle.stream.fsizer(file->handle.stream.handle);
+               data.buf = emalloc(size + 1);
+               data.len = file->handle.stream.reader(file->handle.stream.handle, data.buf, size);
        }
-       memset(data.buf + data.len, 0, ZEND_MMAP_AHEAD + 1);
-       data.line[0] = 0;
 
-       memset(&fake, 0, sizeof(fake));
-       fake.type = ZEND_HANDLE_MAPPED;
-       fake.handle.stream.mmap.buf = data.buf;
-       fake.handle.stream.mmap.len = data.len;
-       fake.free_filename = 0;
-       fake.filename = filename;
-       fake.opened_path = file->opened_path;
+       memset(data.buf + data.len, 0, 1);
 
+       data.line[0] = 0;
        *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint32_t) * data.len)) = data;
 
        for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
@@ -268,28 +268,14 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
                        dataptr->line[++line] = (uint32_t)(bufptr - data.buf) + 1;
                }
        }
+
        dataptr->lines = ++line;
+       dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint32_t) * line);
        dataptr->line[line] = endptr - data.buf;
 
-       ret = PHPDBG_G(compile_file)(&fake, type);
-
-       if (ret == NULL) {
-               efree(data.buf);
-               efree(dataptr);
-
-               fake.opened_path = NULL;
-               zend_file_handle_dtor(&fake);
-
-               return NULL;
-       }
-
-       dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint32_t) * line);
        zend_hash_add_ptr(&PHPDBG_G(file_sources), ret->filename, dataptr);
        phpdbg_resolve_pending_file_break(ZSTR_VAL(ret->filename));
 
-       fake.opened_path = NULL;
-       zend_file_handle_dtor(&fake);
-
        return ret;
 }
 
diff --git a/sapi/phpdbg/tests/bug76801.phpt b/sapi/phpdbg/tests/bug76801.phpt
new file mode 100644 (file)
index 0000000..12ec8c7
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+include()ing files should not raise "too many open files" error
+--PHPDBG--
+r
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Script ended normally]
+prompt> 
+--FILE--
+<?php
+
+for ($i = 0; $i < 25000; ++$i) {
+    include __DIR__.'/empty.inc';
+}
diff --git a/sapi/phpdbg/tests/empty.inc b/sapi/phpdbg/tests/empty.inc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sapi/phpdbg/tests/include_once_002.phpt b/sapi/phpdbg/tests/include_once_002.phpt
new file mode 100644 (file)
index 0000000..742decf
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+include_once must include only once #2
+--PHPDBG--
+r
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> 1
+[Script ended normally]
+prompt> 
+--FILE--
+<?php
+
+include __DIR__.'/include.inc';
+include_once __DIR__.'/include.inc';