summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2006-05-14 01:06:09 +0000
committerMarcus Boerger <helly@php.net>2006-05-14 01:06:09 +0000
commit0c09d4cb63930a79203481aa3168bd863d5df6f3 (patch)
treea2b32044333500fa1ef521566187a4c423d221f6 /main
parentfc06fb4a070c2237842efa8fab065dee9b075273 (diff)
downloadphp-git-0c09d4cb63930a79203481aa3168bd863d5df6f3.tar.gz
- MFH RFC 2397 meta data handling
Diffstat (limited to 'main')
-rw-r--r--main/streams/memory.c85
1 files changed, 78 insertions, 7 deletions
diff --git a/main/streams/memory.c b/main/streams/memory.c
index 7b646d6083..344b7c7a6c 100644
--- a/main/streams/memory.c
+++ b/main/streams/memory.c
@@ -560,9 +560,11 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, cha
{
php_stream *stream;
php_stream_temp_data *ts;
- char *comma, *semi;
- size_t mlen, dlen;
+ char *comma, *semi, *sep, *key;
+ size_t mlen, dlen, plen, vlen;
off_t newoffs;
+ zval *meta = NULL;
+ int base64 = 0;
if (memcmp(path, "data:", 5)) {
return NULL;
@@ -581,22 +583,91 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, cha
return NULL;
}
- if ((stream = php_stream_temp_create_rel(0, ~0u)) != NULL) {
- if (comma != path) {
- /* meta info */
- mlen = comma - path;
- dlen -= mlen;
+ if (comma != path) {
+ /* meta info */
+ mlen = comma - path;
+ dlen -= mlen;
+ semi = memchr(path, ';', mlen);
+ sep = memchr(path, '/', mlen);
+
+ if (!semi && !sep) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal media type");
+ return NULL;
+ }
+
+ MAKE_STD_ZVAL(meta);
+ array_init(meta);
+ if (!semi) { /* there is only a mime type */
+ add_assoc_stringl(meta, "mediatype", path, mlen, 1);
+ mlen = 0;
+ } else if (sep && sep < semi) { /* there is a mime type */
+ plen = semi - path;
+ add_assoc_stringl(meta, "mediatype", path, plen, 1);
+ 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 */
+ zval_ptr_dtor(&meta);
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal media type");
+ return NULL;
+ }
+ /* get parameters and potentially ';base64' */
+ while(semi && (semi == path)) {
+ path++;
+ mlen--;
+ sep = memchr(path, '=', mlen);
semi = memchr(path, ';', mlen);
+ if (!sep || (semi && semi < sep)) { /* must be ';base64' or failure */
+ if (mlen != sizeof("base64")-1 || memcmp(path, "base64", sizeof("base64")-1)) {
+ /* must be error since parameters are only allowed after mediatype and we have no '=' sign */
+ zval_ptr_dtor(&meta);
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal parameter");
+ return NULL;
+ }
+ base64 = 1;
+ mlen -= sizeof("base64") - 1;
+ path += sizeof("base64") - 1;
+ break;
+ }
+ /* found parameter ... the heart of cs ppl lies in +1/-1 or was it +2 this time? */
+ 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);
+ efree(key);
+ plen += vlen + 1;
+ mlen -= plen;
+ path += plen;
}
+ if (mlen) {
+ zval_ptr_dtor(&meta);
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal url");
+ return NULL;
+ }
+ } else {
+ MAKE_STD_ZVAL(meta);
+ array_init(meta);
+ }
+ add_assoc_bool(meta, "base64", base64);
+
+ if ((stream = php_stream_temp_create_rel(0, ~0u)) != NULL) {
/* skip ',' */
comma++;
dlen--;
/* store data */
php_stream_temp_write(stream, comma, dlen TSRMLS_CC);
php_stream_temp_seek(stream, 0, SEEK_SET, &newoffs TSRMLS_CC);
+ /* set special stream stuff (enforce exact mode) */
+ vlen = strlen(mode);
+ if (vlen >= sizeof(stream->mode)) {
+ vlen = sizeof(stream->mode) - 1;
+ }
+ memcpy(stream->mode, mode, vlen);
+ stream->mode[vlen] = '\0';
+ stream->ops = &php_stream_rfc2397_ops;
ts = (php_stream_temp_data*)stream->abstract;
assert(ts != NULL);
ts->mode = mode && mode[0] == 'r' ? TEMP_STREAM_READONLY : 0;
+ ts->meta = meta;
}
return stream;