Edit report at https://bugs.php.net/bug.php?id=47070&edit=1

 ID:                 47070
 Comment by:         dopry at rynassociates dot com
 Reported by:        darrel dot opry at gmail dot com
 Summary:            php_stream_locate_url_wrapper fails without
                     authority section
 Status:             Open
 Type:               Feature/Change Request
 Package:            Streams related
 Operating System:   Ubuntu 8.10
 PHP Version:        5.2.8
 Block user comment: N
 Private report:     N

 New Comment:

I believe the code that needs to be modified to be in main/streams/streams.c

in the function 
php_stream_locate_url_wrapper

// iterate over path while the current character is alpha numeric
// +, -, or .
for (p = path; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) {
                n++;
}

// if the current value of p is :  and n is not the first character
// and the characters following p are // || the first five charaters are not 
// data:
        if ((*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || (n == 4 && 
!memcmp("data:", path, 5)))) {
                protocol = path;
        } else if (n == 5 && strncasecmp(path, "zlib:", 5) == 0) {
                /* BC with older php scripts and zlib wrapper */
                protocol = "compress.zlib";
                n = 13;
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Use of \"zlib:\" 
wrapper is deprecated; please use \"compress.zlib://\" instead");
        }

I believe the solution to be removing (!strncmp("//", p+1, 2) from the if 
statement above so that // is not a required part of the validation. 

The following logic for returning the stream wrapper looks like it can be 
further optimized by re-ordering/grouping some of the conditionals.


Previous Comments:
------------------------------------------------------------------------
[2009-07-27 08:39:56] j...@php.net

Reclassified.

------------------------------------------------------------------------
[2009-01-15 16:25:37] darrel dot opry at gmail dot com

a note regarding backwards compatibility. This change shouldn't 
interfere with existing user defined stream wrappers, since they 
would not be called with if they used without the authority section 
currently.

------------------------------------------------------------------------
[2009-01-15 16:14:16] darrel dot opry at gmail dot com

I did RTFM. As a developer and user of PHP I disagree with your 
assertion. The use and parsing of the URL schema for streams is not 
the same as that of parse_url which is recommended for parsing 
incoming paths.

The documentation specifically uses the wording URL in many places, 
right to the point of having a setting for allow_url_fopen. 

The issue with the current approach is that it does not recognize 
legally delimited scheme's properly, and pass them to the underlying 
stream wrapper. It seems to make the invalid assumption that :// or 
// is the scheme delimiter when it is in fact :. It's a minor parsing 
issue that could probably be corrected by an experienced C developer 
in under 20 minutes.

Why is this an issue you may ask... 

parse_url properly parses the scheme, user, password, host, port, and 
path. 

If I want to use parse_url within my stream wrapper I have to 
concatenate the host and path elements if I use a URL in the form of 
file://path/to/file.txt or I have to use a url in the form of 
file://localhost/path/to/file.txt if I want to avoid this 
concatenation.

A secondary impact, if I'm storing URLs to resources in the database 
I now have to store the authority section as well. This is suboptimal 
for me as a application developer as the number of resources I'm 
storing references to increases. 

So maybe you should go RYOFM, before dismissing something out of hand 
just because it references and RFC without thinking of the 
implications.

Basically I think most developers really want their stream wrapper 
called if scheme: is properly designated, so they can write standards 
compliant code.

------------------------------------------------------------------------
[2009-01-15 15:26:34] j...@php.net

RTFM: http://www.php.net/fopen  (look for explanation what PHP expects the 
filename parameter to look like...you can put as many RFCs here, but it's never 
said anywhere that fopen() expects some RFCs style scheme.. :)

------------------------------------------------------------------------
[2009-01-12 03:01:10] darrel dot opry at gmail dot com

Description:
------------
php_stream_locate_url_wrapper fails without authority section.

If a URL is not in the Common Internet Scheme Syntax 
(scheme://<<user>:<pass>@>host<:port>/url-path) the scheme is not be located 
properly. So URLs of scheme:relative/path and scheme:/absolute/path will not be 
handled by the registered user defined stream wrapper.

see http://www.ietf.org/rfc/rfc1738.txt for URL specific syntax.

see section 3 of http://labs.apache.org/webarch/uri/rfc/rfc3986.html#intro for 
URI syntax.

Reproduce code:
---------------
<?php

class wrapper {
  function stream_open() {
    print_r(func_get_args());
    return TRUE;
  }
}

stream_wrapper_register('public', 'wrapper');

fopen('public:path/file.txt', 'r+');
fopen('public:/path/file.txt', 'r+');
fopen('public://path/file.txt', 'r+');


Expected result:
----------------
I expect wrapper::stream_open to be called and fopen to print_r the function 
arguments.

Array
(
    [0] => public:path/file.txt
    [1] => r+
    [2] => 4
    [3] => 
)
Array
(
    [0] => public:/path/file.txt
    [1] => r+
    [2] => 4
    [3] => 
)
Array
(
    [0] => public://path/file.txt
    [1] => r+
    [2] => 4
    [3] => 
)

Actual result:
--------------
Warning: fopen(public:path/file.txt): failed to open stream: No such file or 
directory in 
/home/dopry/public_html/drupal-media/sites/default/modules/media/resource/test.php
 on line 13

Warning: fopen(public:/path/file.txt): failed to open stream: No such file or 
directory in 
/home/dopry/public_html/drupal-media/sites/default/modules/media/resource/test.php
 on line 14
Array
(
    [0] => public://path/file.txt
    [1] => r+
    [2] => 4
    [3] => 
)



------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=47070&edit=1

Reply via email to