From: Marcus Boerger Date: Sun, 14 May 2006 01:06:09 +0000 (+0000) Subject: - MFH RFC 2397 meta data handling X-Git-Tag: php-5.2.0RC1~565 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c09d4cb63930a79203481aa3168bd863d5df6f3;p=php - MFH 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..7aba2e2aeb --- /dev/null +++ b/ext/standard/tests/file/stream_rfc2397_002.phpt @@ -0,0 +1,180 @@ +--TEST-- +Stream: RFC2397 getting meta data +--FILE-- + +===DONE=== + +--EXPECTF-- +array(7) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(7) "RFC2397" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + 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(7) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(7) "RFC2397" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + 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(8) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(7) "RFC2397" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + 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(9) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(7) "RFC2397" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + 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(9) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(7) "RFC2397" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + 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(10) { + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(7) "RFC2397" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + 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..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;