summaryrefslogtreecommitdiff
path: root/main/streams/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/streams/memory.c')
-rw-r--r--main/streams/memory.c78
1 files changed, 48 insertions, 30 deletions
diff --git a/main/streams/memory.c b/main/streams/memory.c
index 90780ea78f..9788954988 100644
--- a/main/streams/memory.c
+++ b/main/streams/memory.c
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 5 |
+ | PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2013 The PHP Group |
+ | Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -20,9 +20,9 @@
#define _GNU_SOURCE
#include "php.h"
+#include "ext/standard/base64.h"
PHPAPI int php_url_decode(char *str, int len);
-PHPAPI unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length);
/* Memory streams use a dynamic memory buffer to emulate a stream.
* You can use php_stream_memory_open to create a readonly stream
@@ -127,7 +127,7 @@ static int php_stream_memory_flush(php_stream *stream TSRMLS_DC)
/* {{{ */
-static int php_stream_memory_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC)
+static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs TSRMLS_DC)
{
php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract;
assert(ms != NULL);
@@ -351,7 +351,8 @@ typedef struct {
php_stream *innerstream;
size_t smax;
int mode;
- zval* meta;
+ zval meta;
+ char* tmpdir;
} php_stream_temp_data;
@@ -369,7 +370,7 @@ static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t
char *membuf = php_stream_memory_get_buffer(ts->innerstream, &memsize);
if (memsize + count >= ts->smax) {
- php_stream *file = php_stream_fopen_tmpfile();
+ php_stream *file = php_stream_fopen_temporary_file(ts->tmpdir, "php", NULL);
php_stream_write(file, membuf, memsize);
php_stream_free_enclosed(ts->innerstream, PHP_STREAM_FREE_CLOSE);
ts->innerstream = file;
@@ -416,8 +417,10 @@ static int php_stream_temp_close(php_stream *stream, int close_handle TSRMLS_DC)
ret = 0;
}
- if (ts->meta) {
- zval_ptr_dtor(&ts->meta);
+ zval_ptr_dtor(&ts->meta);
+
+ if (ts->tmpdir) {
+ efree(ts->tmpdir);
}
efree(ts);
@@ -439,7 +442,7 @@ static int php_stream_temp_flush(php_stream *stream TSRMLS_DC)
/* {{{ */
-static int php_stream_temp_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC)
+static int php_stream_temp_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs TSRMLS_DC)
{
php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract;
int ret;
@@ -465,7 +468,7 @@ static int php_stream_temp_cast(php_stream *stream, int castas, void **ret TSRML
php_stream *file;
size_t memsize;
char *membuf;
- off_t pos;
+ zend_off_t pos;
assert(ts != NULL);
@@ -522,8 +525,8 @@ static int php_stream_temp_set_option(php_stream *stream, int option, int value,
switch(option) {
case PHP_STREAM_OPTION_META_DATA_API:
- if (ts->meta) {
- zend_hash_copy(Z_ARRVAL_P((zval*)ptrparam), Z_ARRVAL_P(ts->meta), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
+ if (Z_TYPE(ts->meta) != IS_UNDEF) {
+ zend_hash_copy(Z_ARRVAL_P((zval*)ptrparam), Z_ARRVAL(ts->meta), zval_add_ref);
}
return PHP_STREAM_OPTION_RETURN_OK;
default:
@@ -547,8 +550,8 @@ PHPAPI php_stream_ops php_stream_temp_ops = {
/* }}} */
-/* {{{ _php_stream_temp_create */
-PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC)
+/* {{{ _php_stream_temp_create_ex */
+PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC TSRMLS_DC)
{
php_stream_temp_data *self;
php_stream *stream;
@@ -556,7 +559,10 @@ PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STR
self = ecalloc(1, sizeof(*self));
self->smax = max_memory_usage;
self->mode = mode;
- self->meta = NULL;
+ ZVAL_UNDEF(&self->meta);
+ 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->flags |= PHP_STREAM_FLAG_NO_BUFFER;
self->innerstream = php_stream_memory_create_rel(mode);
@@ -566,13 +572,19 @@ PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STR
}
/* }}} */
+/* {{{ _php_stream_temp_create */
+PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC)
+{
+ return php_stream_temp_create_ex(mode, max_memory_usage, NULL);
+}
+/* }}} */
/* {{{ _php_stream_temp_open */
PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC)
{
php_stream *stream;
php_stream_temp_data *ts;
- off_t newoffs;
+ zend_off_t newoffs;
if ((stream = php_stream_temp_create_rel(mode, max_memory_usage)) != NULL) {
if (length) {
@@ -606,10 +618,12 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con
php_stream_temp_data *ts;
char *comma, *semi, *sep, *key;
size_t mlen, dlen, plen, vlen;
- off_t newoffs;
- zval *meta = NULL;
+ zend_off_t newoffs;
+ zval meta;
int base64 = 0, ilen;
+ zend_string *base64_comma = NULL;
+ ZVAL_NULL(&meta);
if (memcmp(path, "data:", 5)) {
return NULL;
}
@@ -639,14 +653,13 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con
return NULL;
}
- MAKE_STD_ZVAL(meta);
- array_init(meta);
+ array_init(&meta);
if (!semi) { /* there is only a mime type */
- add_assoc_stringl(meta, "mediatype", (char *) path, mlen, 1);
+ add_assoc_stringl(&meta, "mediatype", (char *) path, mlen);
mlen = 0;
} else if (sep && sep < semi) { /* there is a mime type */
plen = semi - path;
- add_assoc_stringl(meta, "mediatype", (char *) path, plen, 1);
+ add_assoc_stringl(&meta, "mediatype", (char *) path, plen);
mlen -= plen;
path += plen;
} else if (semi != path || mlen != sizeof(";base64")-1 || memcmp(path, ";base64", sizeof(";base64")-1)) { /* must be error since parameters are only allowed after mediatype */
@@ -676,7 +689,7 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con
plen = sep - path;
vlen = (semi ? semi - sep : mlen - plen) - 1 /* '=' */;
key = estrndup(path, plen);
- add_assoc_stringl_ex(meta, key, plen + 1, sep + 1, vlen, 1);
+ add_assoc_stringl_ex(&meta, key, plen, sep + 1, vlen);
efree(key);
plen += vlen + 1;
mlen -= plen;
@@ -688,22 +701,23 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con
return NULL;
}
} else {
- MAKE_STD_ZVAL(meta);
- array_init(meta);
+ array_init(&meta);
}
- add_assoc_bool(meta, "base64", base64);
+ add_assoc_bool(&meta, "base64", base64);
/* skip ',' */
comma++;
dlen--;
if (base64) {
- comma = (char*)php_base64_decode((const unsigned char *)comma, dlen, &ilen);
- if (!comma) {
+ base64_comma = php_base64_decode((const unsigned char *)comma, dlen);
+ if (!base64_comma) {
zval_ptr_dtor(&meta);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: unable to decode");
return NULL;
}
+ comma = base64_comma->val;
+ ilen = base64_comma->len;
} else {
comma = estrndup(comma, dlen);
ilen = dlen = php_url_decode(comma, dlen);
@@ -724,9 +738,13 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con
ts = (php_stream_temp_data*)stream->abstract;
assert(ts != NULL);
ts->mode = mode && mode[0] == 'r' && mode[1] != '+' ? TEMP_STREAM_READONLY : 0;
- ts->meta = meta;
+ ZVAL_COPY_VALUE(&ts->meta, &meta);
+ }
+ if (base64_comma) {
+ zend_string_free(base64_comma);
+ } else {
+ efree(comma);
}
- efree(comma);
return stream;
}