Subject: bug#12244: closed (Re: bug#12244: [patch] URI encoding bugs)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 26 Aug 2012 21:39:02 +0000

Your bug report

#12244: [patch] URI encoding bugs

which was filed against the guile package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
12244: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=12244
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#12244: [patch] URI encoding bugs
From: [email-masked] (Ludovic Courtès)
To: Ian Price <[email-masked]>
Cc: [email-masked]
Date: Sun, 26 Aug 2012 23:37:36 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi Ian,

Applied both, thanks!

Ludo’.

Subject: [patch] URI encoding bugs
From: Ian Price <[email-masked]>
To: [email-masked]
Date: Mon, 20 Aug 2012 23:19:12 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

There are two bugs in the current uri-encode procedure in (web
uri).

Firstly, if you have an octet less than 16 it only gets encoded to %
HEXDIGIT instead of % HEXDIGIT HEXDIGIT.

scheme@(guile−user)> (uri-encode "foo\nbar")
$30 = "foo%abar"

Secondly, if you have a string with no unreserved characters, nothing
gets encoded.
scheme@(guile−user)> (uri-encode "<>\\^")
$31 = "<>\\∧"
scheme@(guile−user)> (uri-encode "<>\\^a")
$32 = "%3c%3e%5c%5ea"

Patches attached. Cheers,

-- 
Ian Price -- shift-reset.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"

>From 11f56bd6a4fdf1331ea30cd68b4d77e35215b4a5 Mon Sep 17 00:00:00 2001
From: Ian Price <[email-masked]>
Date: Mon, 20 Aug 2012 23:03:38 +0100
Subject: [PATCH 1/2] Fix uri-encoding for octets 0-15

* module/web/uri.scm (uri-encode): All encoded octets should be of the
  form % HEXDIGIT HEXDIGIT.
* test-suite/tests/web-uri.test ("encode"): Add test.
---
 module/web/uri.scm            |    2 ++
 test-suite/tests/web-uri.test |    3 ++-
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/module/web/uri.scm b/module/web/uri.scm
index 109118b..3816d02 100644
--- a/module/web/uri.scm
+++ b/module/web/uri.scm
@@ -377,6 +377,8 @@ the byte."
                     (if (< i len)
                         (let ((byte (bytevector-u8-ref bv i)))
                           (display #\% port)
+                          (when (< byte 16)
+                            (display #\0 port))
                           (display (number->string byte 16) port)
                           (lp (1+ i))))))))
           str)))
diff --git a/test-suite/tests/web-uri.test b/test-suite/tests/web-uri.test
index 4621a19..a9ded46 100644
--- a/test-suite/tests/web-uri.test
+++ b/test-suite/tests/web-uri.test
@@ -258,4 +258,5 @@
     (equal? "foo bar" (uri-decode "foo+bar"))))
 
 (with-test-prefix "encode"
-  (pass-if (equal? "foo%20bar" (uri-encode "foo bar"))))
+  (pass-if (equal? "foo%20bar" (uri-encode "foo bar")))
+  (pass-if (equal? "foo%0a%00bar" (uri-encode "foo\n\x00bar"))))
-- 
1.7.7.6

>From ae4fa3f65c1d49822b5a284a065017673c81e65e Mon Sep 17 00:00:00 2001
From: Ian Price <[email-masked]>
Date: Mon, 20 Aug 2012 23:12:23 +0100
Subject: [PATCH 2/2] Fix uri-encoding for strings with no unreserved chars

* module/web/uri.scm (uri-encode): Change test to check for unreserved
  chars instead of reserved chars.
* test-suite/tests/web-uri.test ("encode"): Add test.
---
 module/web/uri.scm            |    4 +++-
 test-suite/tests/web-uri.test |    3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/module/web/uri.scm b/module/web/uri.scm
index 3816d02..78614a5 100644
--- a/module/web/uri.scm
+++ b/module/web/uri.scm
@@ -364,7 +364,9 @@ Percent-encoding first writes out the given character to a bytevector
 within the given @var{encoding}, then encodes each byte as
 @code{%@var{HH}}, where @var{HH} is the hexadecimal representation of
 the byte."
-  (if (string-index str unescaped-chars)
+  (define (needs-escaped? ch)
+    (not (char-set-contains? unescaped-chars ch)))
+  (if (string-index str needs-escaped?)
       (call-with-output-string*
        (lambda (port)
          (string-for-each
diff --git a/test-suite/tests/web-uri.test b/test-suite/tests/web-uri.test
index a9ded46..3f6e7e3 100644
--- a/test-suite/tests/web-uri.test
+++ b/test-suite/tests/web-uri.test
@@ -259,4 +259,5 @@
 
 (with-test-prefix "encode"
   (pass-if (equal? "foo%20bar" (uri-encode "foo bar")))
-  (pass-if (equal? "foo%0a%00bar" (uri-encode "foo\n\x00bar"))))
+  (pass-if (equal? "foo%0a%00bar" (uri-encode "foo\n\x00bar")))
+  (pass-if (equal? "%3c%3e%5c%5e" (uri-encode "<>\\^"))))
-- 
1.7.7.6