]> granicus.if.org Git - php/commitdiff
- MFH RFC 2397 meta data handling
authorMarcus Boerger <helly@php.net>
Sun, 14 May 2006 01:06:09 +0000 (01:06 +0000)
committerMarcus Boerger <helly@php.net>
Sun, 14 May 2006 01:06:09 +0000 (01:06 +0000)
ext/standard/tests/file/stream_rfc2397_002.phpt [new file with mode: 0755]
main/streams/memory.c

diff --git a/ext/standard/tests/file/stream_rfc2397_002.phpt b/ext/standard/tests/file/stream_rfc2397_002.phpt
new file mode 100755 (executable)
index 0000000..7aba2e2
--- /dev/null
@@ -0,0 +1,180 @@
+--TEST--
+Stream: RFC2397 getting meta data
+--FILE--
+<?php
+
+$streams = array(
+       'data://,',
+       'data://',
+       'data://;base64,',
+       'data://;base64',
+       'data://foo,',
+       'data://foo=bar,',
+       'data://text/plain,',
+       'data://text/plain;foo,',
+       'data://text/plain;foo=bar,',
+       'data://text/plain;foo=bar;bla,',
+       'data://text/plain;foo=bar;base64,',
+       'data://text/plain;foo=bar;bar=baz',
+       'data://text/plain;foo=bar;bar=baz,',
+       );
+
+foreach($streams as $stream)
+{
+       $stream = fopen($stream, 'r');
+       $meta = @stream_get_meta_data($stream);
+       var_dump($meta);
+       var_dump(isset($meta['foo']) ? $meta['foo'] : null);
+}
+
+?>
+===DONE===
+<?php exit(0); ?>
+--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
index 7b646d60831f19a1ec87b92024577729f03005d9..344b7c7a6cc7010055a0778868ec200ee262b8b3 100644 (file)
@@ -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;