On 2016/01/08 14:55, Lauri Tirkkonen wrote:
> On Fri, Jan 08 2016 12:43:59 +0000, Stuart Henderson wrote:
> > On 2016/01/08 14:04, Lauri Tirkkonen wrote:
> > > On Wed, Dec 30 2015 11:26:48 +0200, Lauri Tirkkonen wrote:
> > > > >Synopsis:      ftp(1) fails when HTTP redirected to a relative URI 
> > > > >containing the string "://"
> > > 
> > > > >Fix:
> > > >         Patch attached.
> > > 
> > > No takers?
> > 
> > The problem is valid, but the diff doesn't go far enough, it needs
> > an additional check to avoid breaking currently-working cases.
> > 
> > Before patching:
> > 
> > $ ftp -Mo- https://junkpile.org/redir-to-colon
> > Trying 195.95.187.26...
> > Requesting https://junkpile.org/redir-to-colon
> > Redirected to https://junkpile.org/test:file.txt
> > Trying 195.95.187.26...
> > Requesting https://junkpile.org/test:file.txt
> > testing...
> > 11 bytes received in 0.00 seconds (44.02 KB/s)
> > 
> > After:
> > 
> > $ obj/ftp -Mo- https://junkpile.org/redir-to-colon
> > Trying 195.95.187.26...
> > Requesting https://junkpile.org/redir-to-colon
> > Redirected to test:file.txt
> > ftp: url_get: Invalid URL 'test:file.txt'
> > 
> > This is a contrived test, but there are definitely URLs in the
> > wild containing : and it wouldn't be entirely unexpected to see
> > a relative redirect to them.
> 
> I was following RFC 3986 which states that relative-path segments
> containing a colon cannot be used as the first segment [0].
> 
> [0]: https://tools.ietf.org/html/rfc3986#section-4.2

Ah, thanks for pointing that out. In which case, I think we
should refer to the RFC (and use KNF style for the multi-line
comment). While there, I'd like to add an XXX comment that
we don't handle // redirects.

Any OKs to commit this?

Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.143
diff -u -p -r1.143 fetch.c
--- fetch.c     13 Oct 2015 08:53:43 -0000      1.143
+++ fetch.c     8 Jan 2016 13:13:42 -0000
@@ -833,10 +833,15 @@ again:
                } else if (isredirect &&
                    strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) {
                        cp += sizeof(LOCATION) - 1;
-                       if (strstr(cp, "://") == NULL) {
+                       /*
+                        * If there is a colon before the first slash, this URI
+                        * is not relative. RFC 3986 4.2
+                        */
+                       if (cp[strcspn(cp, ":/")] != ':') {
 #ifdef SMALL
                                errx(1, "Relative redirect not supported");
 #else /* SMALL */
+                               /* XXX doesn't handle protocol-relative URIs */
                                if (*cp == '/') {
                                        locbase = NULL;
                                        cp++;

Reply via email to