php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #53465
Patch php_fd_open.diff revision 2010-12-06 22:24 UTC by cataphract@php.net

Patch php_fd_open.diff for Filesystem function related Bug #53465

Patch version 2010-12-06 22:24 UTC

Return to Bug #53465 | Download this patch
Patch Revisions:

Developer: cataphract@php.net

Index: main/php_streams.h
===================================================================
--- main/php_streams.h	(revision 305891)
+++ main/php_streams.h	(working copy)
@@ -580,6 +580,15 @@
 END_EXTERN_C()
 #endif
 
+BEGIN_EXTERN_C()
+/* This functions transforms the first char to 'w' if it's not 'r', 'a' or 'w'
+ * and strips any subsequent chars except '+' and 'b'.
+ * Use this to sanitize stream modes if you call e.g. fdopen, fopencookie or
+ * any other function that expects standard modes and you allow non-standard
+ * ones. result should be a char[5]. */
+PHPAPI void php_stream_mode_sanitize_fdopen_fopencookie(const char *cur_mode, char *result);
+END_EXTERN_C()
+
 /* Definitions for user streams */
 #define PHP_STREAM_IS_URL		1
 /*
Index: main/streams/plain_wrapper.c
===================================================================
--- main/streams/plain_wrapper.c	(revision 305853)
+++ main/streams/plain_wrapper.c	(working copy)
@@ -491,7 +491,7 @@
 					/* we were opened as a plain file descriptor, so we
 					 * need fdopen now */
 					char fixed_mode[5];
-					php_stream_mode_sanitize_fdopen_fopencookie(stream, fixed_mode);
+					php_stream_mode_sanitize_fdopen_fopencookie(stream->mode, fixed_mode);
 					data->file = fdopen(data->fd, fixed_mode);
 					if (data->file == NULL) {
 						return FAILURE;
@@ -922,7 +922,7 @@
 				if (realpath) {
 					efree(realpath);
 				}
-				efree(persistent_id);;
+				efree(persistent_id);
 				return ret;
 		}
 	}
Index: main/streams/php_streams_int.h
===================================================================
--- main/streams/php_streams_int.h	(revision 305853)
+++ main/streams/php_streams_int.h	(working copy)
@@ -59,13 +59,6 @@
 #define S_ISREG(mode)	(((mode)&S_IFMT) == S_IFREG)
 #endif
 
-/* This functions transforms the first char to 'w' if it's not 'r', 'a' or 'w'
- * and strips any subsequent chars except '+' and 'b'.
- * Use this to sanitize stream->mode if you call e.g. fdopen, fopencookie or
- * any other function that expects standard modes and you allow non-standard
- * ones. result should be a char[5]. */
-void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *result);
-
 void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC);
 void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption TSRMLS_DC);
 
Index: main/streams/php_stream_filter_api.h
===================================================================
--- main/streams/php_stream_filter_api.h	(revision 305853)
+++ main/streams/php_stream_filter_api.h	(working copy)
@@ -131,7 +131,7 @@
 PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC);
 PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC);
 PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC);
-PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC);
+PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC);
 END_EXTERN_C()
 #define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC TSRMLS_CC)
 #define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC TSRMLS_CC)
Index: main/streams/filter.c
===================================================================
--- main/streams/filter.c	(revision 305853)
+++ main/streams/filter.c	(working copy)
@@ -292,7 +292,7 @@
 	return filter;
 }
 
-PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC)
+PHPAPI php_stream_filter *_php_stream_filter_alloc(const php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC)
 {
 	php_stream_filter *filter;
 
Index: main/streams/cast.c
===================================================================
--- main/streams/cast.c	(revision 305853)
+++ main/streams/cast.c	(working copy)
@@ -146,11 +146,10 @@
 
 /* {{{ php_stream_mode_sanitize_fdopen_fopencookie
  * Result should have at least size 5, e.g. to write wbx+\0 */
-void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *result)
+void php_stream_mode_sanitize_fdopen_fopencookie(const char *cur_mode, char *result)
 {
 	/* replace modes not supported by fdopen and fopencookie, but supported 
 	 * by PHP's fread(), so that their calls won't fail */
-	const char *cur_mode = stream->mode;
 	int         has_plus = 0,
 		        has_bin  = 0,
 				i,
@@ -233,7 +232,7 @@
 
 		{
 			char fixed_mode[5];
-			php_stream_mode_sanitize_fdopen_fopencookie(stream, fixed_mode);
+			php_stream_mode_sanitize_fdopen_fopencookie(stream->mode, fixed_mode);
 			*(FILE**)ret = fopencookie(stream, fixed_mode, PHP_STREAM_COOKIE_FUNCTIONS);
 		}
 
Index: ext/standard/php_fopen_wrapper.c
===================================================================
--- ext/standard/php_fopen_wrapper.c	(revision 305853)
+++ ext/standard/php_fopen_wrapper.c	(working copy)
@@ -257,6 +257,37 @@
 		} else {
 			fd = dup(STDERR_FILENO);
 		}
+	} else if (!strncasecmp(path, "fd/", 3)) {
+		char	   *end,
+				   sanitized_mode[5];
+		long	   fildes,
+				   newfd;
+		FILE	   *f;
+
+		fildes = strtol(&path[3], &end, 10);
+		if (end == &path[3] || *end != '\0' || fildes <= 0 || fildes > INT_MAX) {
+			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
+ 				"php://fd/ was not followed by a potentially valid file descriptor; "
+				"it should be a positive number not larger than %d", INT_MAX);
+			return NULL;
+		}
+		php_stream_mode_sanitize_fdopen_fopencookie(mode, sanitized_mode);
+
+		newfd = dup(fildes);
+		if (newfd == -1) {
+			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
+ 				"Inexistent file descriptor: %d", fildes);
+			return NULL;
+		}
+
+		f = fdopen(newfd, sanitized_mode);
+		if (f == NULL) {
+			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC,
+ 				"Call to fdopen() failed (errno: %d)", errno);
+			return NULL;
+		}
+
+		return php_stream_fopen_from_file(f, sanitized_mode);
 	} else if (!strncasecmp(path, "filter/", 7)) {
 		/* Save time/memory when chain isn't specified */
 		if (strchr(mode, 'r') || strchr(mode, '+')) {
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Nov 24 01:01:29 2024 UTC