From 3c8c56fb9822b0a19a66442ea0d235b5d54555e3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gustavo=20Andr=C3=A9=20dos=20Santos=20Lopes?= Date: Sat, 11 Dec 2010 01:52:13 +0000 Subject: [PATCH] - Implemented request #26158/bug #53465 (open arbitrary file descriptor with fopen) --- NEWS | 3 +++ ext/standard/php_fopen_wrapper.c | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/NEWS b/NEWS index 69f34c55f6..2b1eacbbaf 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,9 @@ . Fixed bug #53515 (property_exists incorrect on ArrayObject null and 0 values). (Felipe) +- Streams + . Implemented FR #26158 (open arbitrary file descriptor with fopen) + 09 Dec 2010, PHP 5.3.4 - Upgraded bundled Sqlite3 to version 3.7.3. (Ilia) - Upgraded bundled PCRE to version 8.10. (Ilia) diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 8340da42a8..2a7a2793c7 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -257,6 +257,39 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch } else { fd = dup(STDERR_FILENO); } + } else if (!strncasecmp(path, "fd/", 3)) { + char *start, + *end; + long fildes_ori; + int dtablesize; + + start = &path[3]; + fildes_ori = strtol(start, &end, 10); + if (end == start || (*end != '\0' && *end != '/')) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, + "php://fd/ stream must be specified in the form php://fd/"); + return NULL; + } + +#if HAVE_UNISTD_H + dtablesize = getdtablesize(); +#else + dtablesize = INT_MAX; +#endif + + if (fildes_ori < 0 || fildes_ori >= dtablesize) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, + "The file descriptors must be non-negative numbers smaller than %d", dtablesize); + return NULL; + } + + fd = dup(fildes_ori); + if (fd == -1) { + php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, + "Error duping file descriptor %d; possibly it doesn't exist: " + "[%d]: %s", fildes_ori, errno, strerror(errno)); + return NULL; + } } else if (!strncasecmp(path, "filter/", 7)) { /* Save time/memory when chain isn't specified */ if (strchr(mode, 'r') || strchr(mode, '+')) { -- 2.40.0