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, '+')) {
|