From: Marcus Boerger Date: Sun, 14 May 2006 00:40:53 +0000 (+0000) Subject: - RFC 2397 meta data handling X-Git-Tag: BEFORE_NEW_OUTPUT_API~209 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f29479a22c02dfc4cca9cab646c3842678ad354;p=php - RFC 2397 meta data handling --- diff --git a/ext/standard/tests/file/stream_rfc2397_002.phpt b/ext/standard/tests/file/stream_rfc2397_002.phpt new file mode 100755 index 0000000000..9980968747 --- /dev/null +++ b/ext/standard/tests/file/stream_rfc2397_002.phpt @@ -0,0 +1,192 @@ +--TEST-- +Stream: RFC2397 getting meta data +--FILE-- + +===DONE=== + +--EXPECTF-- +array(8) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(4) "TEMP" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + int(0) + ["unread_chars"]=> + int(0) + ["seekable"]=> + bool(true) + ["uri"]=> + string(8) "data://," + ["base64"]=> + bool(false) +} +NULL + +Warning: fopen(data://): failed to open stream: rfc2397: no comma in url in %sstream_rfc2397_002.php on line %d +bool(false) +NULL +array(8) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(4) "TEMP" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + int(0) + ["unread_chars"]=> + int(0) + ["seekable"]=> + bool(true) + ["uri"]=> + string(15) "data://;base64," + ["base64"]=> + bool(true) +} +NULL + +Warning: fopen(data://;base64): failed to open stream: rfc2397: no comma in url in %sstream_rfc2397_002.php on line %d +bool(false) +NULL + +Warning: fopen(data://foo,): failed to open stream: rfc2397: illegal media type in %sstream_rfc2397_002.php on line %d +bool(false) +NULL + +Warning: fopen(data://foo=bar,): failed to open stream: rfc2397: illegal media type in %sstream_rfc2397_002.php on line %d +bool(false) +NULL +array(9) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(4) "TEMP" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + int(0) + ["unread_chars"]=> + int(0) + ["seekable"]=> + bool(true) + ["uri"]=> + string(18) "data://text/plain," + ["mediatype"]=> + string(10) "text/plain" + ["base64"]=> + bool(false) +} +NULL + +Warning: fopen(data://text/plain;foo,): failed to open stream: rfc2397: illegal parameter in %sstream_rfc2397_002.php on line %d +bool(false) +NULL +array(10) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(4) "TEMP" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + int(0) + ["unread_chars"]=> + int(0) + ["seekable"]=> + bool(true) + ["uri"]=> + string(26) "data://text/plain;foo=bar," + ["mediatype"]=> + string(10) "text/plain" + ["foo"]=> + string(3) "bar" + ["base64"]=> + bool(false) +} +string(3) "bar" + +Warning: fopen(data://text/plain;foo=bar;bla,): failed to open stream: rfc2397: illegal parameter in %sstream_rfc2397_002.php on line %d +bool(false) +NULL +array(10) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(4) "TEMP" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + int(0) + ["unread_chars"]=> + int(0) + ["seekable"]=> + bool(true) + ["uri"]=> + string(33) "data://text/plain;foo=bar;base64," + ["mediatype"]=> + string(10) "text/plain" + ["foo"]=> + string(3) "bar" + ["base64"]=> + bool(true) +} +string(3) "bar" + +Warning: fopen(data://text/plain;foo=bar;bar=baz): failed to open stream: rfc2397: no comma in url in %sstream_rfc2397_002.php on line %d +bool(false) +NULL +array(11) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(4) "TEMP" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + int(0) + ["unread_chars"]=> + int(0) + ["seekable"]=> + bool(true) + ["uri"]=> + string(34) "data://text/plain;foo=bar;bar=baz," + ["mediatype"]=> + string(10) "text/plain" + ["foo"]=> + string(3) "bar" + ["bar"]=> + string(3) "baz" + ["base64"]=> + bool(false) +} +string(3) "bar" +===DONE=== \ No newline at end of file diff --git a/main/streams/memory.c b/main/streams/memory.c index 7b646d6083..426635fad3 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,13 +583,73 @@ 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--; @@ -597,6 +659,7 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, cha 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;