guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 27/47: web: Gracefully handle premature EOF when reading


From: Andy Wingo
Subject: [Guile-commits] 27/47: web: Gracefully handle premature EOF when reading chunk header.
Date: Sun, 22 May 2016 18:23:05 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 0bcf5d78ecb40871fb48cf0f1a6065be38a3a14b
Author: Ludovic Courtès <address@hidden>
Date:   Sat Sep 26 11:04:23 2015 +0200

    web: Gracefully handle premature EOF when reading chunk header.
    
    * module/web/http.scm (read-chunk-header): Return 0 when 'read-line'
      returns EOF.
---
 module/web/http.scm            |   25 ++++++++++++++++---------
 test-suite/tests/web-http.test |   10 ++++++++++
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/module/web/http.scm b/module/web/http.scm
index 8093ed2..5ce7e7c 100644
--- a/module/web/http.scm
+++ b/module/web/http.scm
@@ -34,6 +34,7 @@
   #:use-module (srfi srfi-9)
   #:use-module (srfi srfi-19)
   #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 match)
   #:use-module (ice-9 q)
   #:use-module (ice-9 binary-ports)
   #:use-module (rnrs bytevectors)
@@ -1914,15 +1915,21 @@ treated specially, and is just returned as a plain 
string."
 
 ;; Chunked Responses
 (define (read-chunk-header port)
-  "Read a chunk header and return the chunk size."
-  (let* ((str (read-line port))
-         (extension-start (string-index str (lambda (c) (or (char=? c #\;)
-                                                       (char=? c #\return)))))
-         (size (string->number (if extension-start ; unnecessary?
-                                   (substring str 0 extension-start)
-                                   str)
-                               16)))
-    size))
+  "Read a chunk header from PORT and return the size in bytes of the
+upcoming chunk."
+  (match (read-line port)
+    ((? eof-object?)
+     ;; Connection closed prematurely: there's nothing left to read.
+     0)
+    (str
+     (let ((extension-start (string-index str
+                                          (lambda (c)
+                                            (or (char=? c #\;)
+                                                (char=? c #\return))))))
+       (string->number (if extension-start       ; unnecessary?
+                           (substring str 0 extension-start)
+                           str)
+                       16)))))
 
 (define* (make-chunked-input-port port #:key (keep-alive? #f))
   "Returns a new port which translates HTTP chunked transfer encoded
diff --git a/test-suite/tests/web-http.test b/test-suite/tests/web-http.test
index 8a7a295..bd14de9 100644
--- a/test-suite/tests/web-http.test
+++ b/test-suite/tests/web-http.test
@@ -423,6 +423,16 @@
               (utf8->string (get-bytevector-n port 6))
               (reverse requests)))))
 
+  (pass-if-equal "EOF instead of chunk header"
+      "Only chunk."
+    ;; Omit the second chunk header, leading to a premature EOF.  This
+    ;; used to cause 'read-chunk-header' to throw to wrong-type-arg.
+    ;; See the backtrace at
+    ;; <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19976#5>.
+    (let* ((str  "B\r\nOnly chunk.")
+           (port (make-chunked-input-port (open-input-string str))))
+      (get-string-all port)))
+
   (pass-if-equal
       (call-with-output-string
        (lambda (out-raw)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]