summaryrefslogtreecommitdiff
path: root/main/streams
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-02-16 10:13:02 +0100
committerOndřej Surý <ondrej@sury.org>2011-02-16 10:13:02 +0100
commitfd5a0b31640419ca63d1ddeaffd6d3cf2a741814 (patch)
treebfd17d84c5181d7b98d7d66f56573f4fc897e31c /main/streams
parent01fcdff3849c3691d9aaeaab735846ab6d8895ca (diff)
downloadphp-upstream/5.3.5.tar.gz
Imported Upstream version 5.3.5upstream/5.3.5
Diffstat (limited to 'main/streams')
-rw-r--r--main/streams/cast.c52
-rwxr-xr-xmain/streams/glob_wrapper.c4
-rw-r--r--main/streams/php_streams_int.h9
-rw-r--r--main/streams/plain_wrapper.c23
-rwxr-xr-xmain/streams/streams.c23
5 files changed, 91 insertions, 20 deletions
diff --git a/main/streams/cast.c b/main/streams/cast.c
index 91174665b..85136f016 100644
--- a/main/streams/cast.c
+++ b/main/streams/cast.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: cast.c 293732 2010-01-19 13:44:08Z jani $ */
+/* $Id: cast.c 305108 2010-11-05 18:53:48Z cataphract $ */
#define _GNU_SOURCE
#include "php.h"
@@ -144,6 +144,50 @@ static COOKIE_IO_FUNCTIONS_T stream_cookie_functions =
#endif
/* }}} */
+/* {{{ 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)
+{
+ /* 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,
+ res_curs = 0;
+
+ if (cur_mode[0] == 'r' || cur_mode[0] == 'w' || cur_mode[0] == 'a') {
+ result[res_curs++] = cur_mode[0];
+ } else {
+ /* assume cur_mode[0] is 'c' or 'x'; substitute by 'w', which should not
+ * truncate anything in fdopen/fopencookie */
+ result[res_curs++] = 'w';
+
+ /* x is allowed (at least by glibc & compat), but not as the 1st mode
+ * as in PHP and in any case is (at best) ignored by fdopen and fopencookie */
+ }
+
+ /* assume current mode has at most length 4 (e.g. wbn+) */
+ for (i = 1; i < 4 && cur_mode[i] != '\0'; i++) {
+ if (cur_mode[i] == 'b') {
+ has_bin = 1;
+ } else if (cur_mode[i] == '+') {
+ has_plus = 1;
+ }
+ /* ignore 'n', 't' or other stuff */
+ }
+
+ if (has_bin) {
+ result[res_curs++] = 'b';
+ }
+ if (has_plus) {
+ result[res_curs++] = '+';
+ }
+
+ result[res_curs] = '\0';
+}
+/* }}} */
+
/* {{{ php_stream_cast */
PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err TSRMLS_DC)
{
@@ -187,7 +231,11 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show
goto exit_success;
}
- *(FILE**)ret = fopencookie(stream, stream->mode, PHP_STREAM_COOKIE_FUNCTIONS);
+ {
+ char fixed_mode[5];
+ php_stream_mode_sanitize_fdopen_fopencookie(stream, fixed_mode);
+ *(FILE**)ret = fopencookie(stream, fixed_mode, PHP_STREAM_COOKIE_FUNCTIONS);
+ }
if (*ret != NULL) {
off_t pos;
diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c
index cf5976738..e3c31adb4 100755
--- a/main/streams/glob_wrapper.c
+++ b/main/streams/glob_wrapper.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: glob_wrapper.c 293036 2010-01-03 09:23:27Z sebastian $ */
+/* $Id: glob_wrapper.c 303265 2010-09-10 21:33:50Z felipe $ */
#include "php.h"
#include "php_streams_int.h"
@@ -29,6 +29,7 @@
# endif
#endif
+#ifdef HAVE_GLOB
#ifndef GLOB_ONLYDIR
#define GLOB_ONLYDIR (1<<30)
#define GLOB_FLAGMASK (~GLOB_ONLYDIR)
@@ -278,6 +279,7 @@ php_stream_wrapper php_glob_stream_wrapper = {
NULL,
0
};
+#endif /* HAVE_GLOB */
/*
* Local variables:
diff --git a/main/streams/php_streams_int.h b/main/streams/php_streams_int.h
index 113c518aa..e97247724 100644
--- a/main/streams/php_streams_int.h
+++ b/main/streams/php_streams_int.h
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_streams_int.h 293036 2010-01-03 09:23:27Z sebastian $ */
+/* $Id: php_streams_int.h 305108 2010-11-05 18:53:48Z cataphract $ */
#if ZEND_DEBUG
@@ -59,6 +59,13 @@
#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);
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index 2087505ce..6cd8559a0 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: plain_wrapper.c 295308 2010-02-21 17:44:25Z pajoye $ */
+/* $Id: plain_wrapper.c 305108 2010-11-05 18:53:48Z cataphract $ */
#include "php.h"
#include "php_globals.h"
@@ -490,7 +490,9 @@ static int php_stdiop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC)
if (data->file == NULL) {
/* we were opened as a plain file descriptor, so we
* need fdopen now */
- data->file = fdopen(data->fd, stream->mode);
+ char fixed_mode[5];
+ php_stream_mode_sanitize_fdopen_fopencookie(stream, fixed_mode);
+ data->file = fdopen(data->fd, fixed_mode);
if (data->file == NULL) {
return FAILURE;
}
@@ -1017,10 +1019,18 @@ static int php_plain_files_url_stater(php_stream_wrapper *wrapper, char *url, in
return -1;
}
-#ifdef HAVE_SYMLINK
+#ifdef PHP_WIN32
+ if (EG(windows_version_info).dwMajorVersion >= 5) {
+ if (flags & PHP_STREAM_URL_STAT_LINK) {
+ return VCWD_LSTAT(url, &ssb->sb);
+ }
+ }
+#else
+# ifdef HAVE_SYMLINK
if (flags & PHP_STREAM_URL_STAT_LINK) {
return VCWD_LSTAT(url, &ssb->sb);
} else
+# endif
#endif
return VCWD_STAT(url, &ssb->sb);
}
@@ -1139,7 +1149,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, char *url_from, c
#else
php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno));
#endif
- return 0;
+ return 0;
}
/* Clear stat cache (and realpath cache) */
@@ -1221,7 +1231,7 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mod
if (*p == '\0') {
*p = DEFAULT_SLASH;
if ((*(p+1) != '\0') &&
- (ret = VCWD_MKDIR(buf, (mode_t)mode)) < 0) {
+ (ret = VCWD_MKDIR(buf, (mode_t)mode)) < 0) {
if (options & REPORT_ERRORS) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
}
@@ -1298,7 +1308,6 @@ PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, char
char *pathbuf, *ptr, *end;
char *exec_fname;
char trypath[MAXPATHLEN];
- struct stat sb;
php_stream *stream;
int path_length;
int filename_length;
@@ -1440,6 +1449,8 @@ not_relative_path:
}
if (PG(safe_mode)) {
+ struct stat sb;
+
if (VCWD_STAT(trypath, &sb) == 0) {
/* file exists ... check permission */
if ((php_check_safe_mode_include_dir(trypath TSRMLS_CC) == 0) ||
diff --git a/main/streams/streams.c b/main/streams/streams.c
index e3f79816a..e19430608 100755
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -19,7 +19,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: streams.c 299466 2010-05-18 19:39:39Z pajoye $ */
+/* $Id: streams.c 305379 2010-11-15 18:22:52Z cataphract $ */
#define _GNU_SOURCE
#include "php.h"
@@ -1093,12 +1093,17 @@ PHPAPI off_t _php_stream_tell(php_stream *stream TSRMLS_DC)
PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC)
{
+ if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) {
+ /* flush to commit data written to the fopencookie FILE* */
+ fflush(stream->stdiocast);
+ }
+
/* handle the case where we are in the buffer */
if ((stream->flags & PHP_STREAM_FLAG_NO_BUFFER) == 0) {
switch(whence) {
case SEEK_CUR:
- if (offset > 0 && offset < stream->writepos - stream->readpos) {
- stream->readpos += offset;
+ if (offset > 0 && offset <= stream->writepos - stream->readpos) {
+ stream->readpos += offset; /* if offset = ..., then readpos = writepos */
stream->position += offset;
stream->eof = 0;
return 0;
@@ -1106,7 +1111,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_
break;
case SEEK_SET:
if (offset > stream->position &&
- offset < stream->position + stream->writepos - stream->readpos) {
+ offset <= stream->position + stream->writepos - stream->readpos) {
stream->readpos += offset - stream->position;
stream->position = offset;
stream->eof = 0;
@@ -1149,14 +1154,12 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_
/* emulate forward moving seeks with reads */
if (whence == SEEK_CUR && offset > 0) {
char tmp[1024];
- while(offset >= sizeof(tmp)) {
- if (php_stream_read(stream, tmp, sizeof(tmp)) == 0) {
+ size_t didread;
+ while(offset > 0) {
+ if ((didread = php_stream_read(stream, tmp, MIN(offset, sizeof(tmp)))) == 0) {
return -1;
}
- offset -= sizeof(tmp);
- }
- if (offset && (php_stream_read(stream, tmp, offset) == 0)) {
- return -1;
+ offset -= didread;
}
stream->eof = 0;
return 0;