diff options
author | Marcus Boerger <helly@php.net> | 2006-05-14 01:06:09 +0000 |
---|---|---|
committer | Marcus Boerger <helly@php.net> | 2006-05-14 01:06:09 +0000 |
commit | 0c09d4cb63930a79203481aa3168bd863d5df6f3 (patch) | |
tree | a2b32044333500fa1ef521566187a4c423d221f6 /main | |
parent | fc06fb4a070c2237842efa8fab065dee9b075273 (diff) | |
download | php-git-0c09d4cb63930a79203481aa3168bd863d5df6f3.tar.gz |
- MFH RFC 2397 meta data handling
Diffstat (limited to 'main')
-rw-r--r-- | main/streams/memory.c | 85 |
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; |