diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/standard/php_fopen_wrapper.c | 13 | ||||
-rw-r--r-- | ext/standard/tests/streams/bug75031.phpt | 25 | ||||
-rw-r--r-- | main/php_memory_streams.h | 12 | ||||
-rw-r--r-- | main/streams/memory.c | 30 |
5 files changed, 65 insertions, 16 deletions
@@ -6,6 +6,7 @@ PHP NEWS . Redesigned the old ext_skel program written in PHP, run: 'php ext_skel.php' for all options. This means there is no dependencies thrus making it work on Windows out of the box. (Kalle) + . Fixed bug #75031 (support append mode in temp/memory streams). (adsr) - cURL: . Fixed bug #74125 (Fixed finding CURL on systems with multiarch support). diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 0031440704..34f5d3afbf 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -28,6 +28,7 @@ #include "php.h" #include "php_globals.h" #include "php_standard.h" +#include "php_memory_streams.h" #include "php_fopen_wrappers.h" #include "SAPI.h" @@ -203,20 +204,12 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *pa return NULL; } } - if (strpbrk(mode, "wa+")) { - mode_rw = TEMP_STREAM_DEFAULT; - } else { - mode_rw = TEMP_STREAM_READONLY; - } + mode_rw = php_stream_mode_from_str(mode); return php_stream_temp_create(mode_rw, max_memory); } if (!strcasecmp(path, "memory")) { - if (strpbrk(mode, "wa+")) { - mode_rw = TEMP_STREAM_DEFAULT; - } else { - mode_rw = TEMP_STREAM_READONLY; - } + mode_rw = php_stream_mode_from_str(mode); return php_stream_memory_create(mode_rw); } diff --git a/ext/standard/tests/streams/bug75031.phpt b/ext/standard/tests/streams/bug75031.phpt new file mode 100644 index 0000000000..f0d67a3524 --- /dev/null +++ b/ext/standard/tests/streams/bug75031.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #75031: Append mode in php://temp and php://memory +--FILE-- +<?php + +function test_75031($type, $mode) { + $fp = fopen($type, $mode); + fwrite($fp, "hello"); + fseek($fp, 0, SEEK_SET); + fwrite($fp, "world"); + var_dump(stream_get_contents($fp, -1, 0)); + fclose($fp); +} + +test_75031("php://temp", "w+"); +test_75031("php://memory", "w+"); +test_75031("php://temp", "a+"); +test_75031("php://memory", "a+"); + +?> +--EXPECT-- +string(5) "world" +string(5) "world" +string(10) "helloworld" +string(10) "helloworld" diff --git a/main/php_memory_streams.h b/main/php_memory_streams.h index f8989d261b..271a9276e0 100644 --- a/main/php_memory_streams.h +++ b/main/php_memory_streams.h @@ -25,9 +25,10 @@ #define PHP_STREAM_MAX_MEM 2 * 1024 * 1024 -#define TEMP_STREAM_DEFAULT 0 -#define TEMP_STREAM_READONLY 1 -#define TEMP_STREAM_TAKE_BUFFER 2 +#define TEMP_STREAM_DEFAULT 0x0 +#define TEMP_STREAM_READONLY 0x1 +#define TEMP_STREAM_TAKE_BUFFER 0x2 +#define TEMP_STREAM_APPEND 0x4 #define php_stream_memory_create(mode) _php_stream_memory_create((mode) STREAMS_CC) #define php_stream_memory_create_rel(mode) _php_stream_memory_create((mode) STREAMS_REL_CC) @@ -41,6 +42,7 @@ #define php_stream_temp_open(mode, max_memory_usage, buf, length) _php_stream_temp_open((mode), (max_memory_usage), (buf), (length) STREAMS_CC) BEGIN_EXTERN_C() + PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC); PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length STREAMS_DC); PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC); @@ -48,6 +50,10 @@ PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length ST PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC); PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC); PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC); + +PHPAPI int php_stream_mode_from_str(const char *mode); +PHPAPI const char *_php_stream_mode_to_str(int mode); + END_EXTERN_C() extern PHPAPI php_stream_ops php_stream_memory_ops; diff --git a/main/streams/memory.c b/main/streams/memory.c index 7af87c7efb..2809e22ed0 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -53,10 +53,11 @@ static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_ if (ms->mode & TEMP_STREAM_READONLY) { return 0; + } else if (ms->mode & TEMP_STREAM_APPEND) { + ms->fpos = ms->fsize; } if (ms->fpos + count > ms->fsize) { char *tmp; - if (!ms->data) { tmp = emalloc(ms->fpos + count); } else { @@ -276,6 +277,29 @@ PHPAPI php_stream_ops php_stream_memory_ops = { php_stream_memory_set_option }; +/* {{{ */ +PHPAPI int php_stream_mode_from_str(const char *mode) +{ + if (strpbrk(mode, "a")) { + return TEMP_STREAM_APPEND; + } else if (strpbrk(mode, "w+")) { + return TEMP_STREAM_DEFAULT; + } + return TEMP_STREAM_READONLY; +} +/* }}} */ + +/* {{{ */ +PHPAPI const char *_php_stream_mode_to_str(int mode) +{ + if (mode == TEMP_STREAM_READONLY) { + return "rb"; + } else if (mode == TEMP_STREAM_APPEND) { + return "a+b"; + } + return "w+b"; +} +/* }}} */ /* {{{ */ PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC) @@ -290,7 +314,7 @@ PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC) self->smax = ~0u; self->mode = mode; - stream = php_stream_alloc_rel(&php_stream_memory_ops, self, 0, mode & TEMP_STREAM_READONLY ? "rb" : "w+b"); + stream = php_stream_alloc_rel(&php_stream_memory_ops, self, 0, _php_stream_mode_to_str(mode)); stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; return stream; } @@ -564,7 +588,7 @@ PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, if (tmpdir) { self->tmpdir = estrdup(tmpdir); } - stream = php_stream_alloc_rel(&php_stream_temp_ops, self, 0, mode & TEMP_STREAM_READONLY ? "rb" : "w+b"); + stream = php_stream_alloc_rel(&php_stream_temp_ops, self, 0, _php_stream_mode_to_str(mode)); stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; self->innerstream = php_stream_memory_create_rel(mode); php_stream_encloses(stream, self->innerstream); |