diff options
| author | Ondřej Surý <ondrej@sury.org> | 2011-02-16 10:13:02 +0100 |
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2011-02-16 10:13:02 +0100 |
| commit | fd5a0b31640419ca63d1ddeaffd6d3cf2a741814 (patch) | |
| tree | bfd17d84c5181d7b98d7d66f56573f4fc897e31c /main/streams | |
| parent | 01fcdff3849c3691d9aaeaab735846ab6d8895ca (diff) | |
| download | php-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.c | 52 | ||||
| -rwxr-xr-x | main/streams/glob_wrapper.c | 4 | ||||
| -rw-r--r-- | main/streams/php_streams_int.h | 9 | ||||
| -rw-r--r-- | main/streams/plain_wrapper.c | 23 | ||||
| -rwxr-xr-x | main/streams/streams.c | 23 |
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; |
