diff --git a/conditions.lisp b/conditions.lisp index c04a53a..c03c78c 100644 --- a/conditions.lisp +++ b/conditions.lisp @@ -82,3 +82,13 @@ Read character ~S, but expected ~:[a member of ~S~;~S~]." (:documentation "A condition of this type is signaled if an unexpected character \(octet) is read while reading from a chunked stream with input chunking enabled.")) + +(define-condition input-exceeded-limit (chunga-error) + ((maximum :initarg :maximum + :documentation "The limit which was exceeded.")) + (:report (lambda (condition stream) + (with-slots (maximum) + condition + (format stream "Input exceeded ~d characters." maximum)))) + (:documentation "A condition of this type is signaled if an +maximum-character limit is exceeded.")) diff --git a/read.lisp b/read.lisp index 83c63bc..3eba9a2 100644 --- a/read.lisp +++ b/read.lisp @@ -100,8 +100,11 @@ Additionally logs this string to LOG-STREAM if it is not NIL." (let ((result (with-output-to-string (line) (loop for char-seen-p = nil then t + for count from 0 for char = (read-char* stream nil) for is-cr-p = (and char (char= char #\Return)) + when (and *max-line-length* (> count *max-line-length*)) + do (error 'input-exceeded-limit :maximum *max-line-length*) until (or (null char) is-cr-p (and *accept-bogus-eols* @@ -155,7 +158,8 @@ separated by commas. Header lines which are spread across multiple lines are recognized and treated correctly. Additonally logs the header lines to LOG-STREAM if it is not NIL." (let (headers - (*current-error-message* "While reading HTTP headers:")) + (*current-error-message* "While reading HTTP headers:") + (*max-line-length* (or *max-header-line-length* *max-line-length*))) (labels ((read-header-line () "Reads one header line, considering continuations." (with-output-to-string (header-line) diff --git a/specials.lisp b/specials.lisp index 27c17b6..5d84391 100644 --- a/specials.lisp +++ b/specials.lisp @@ -78,6 +78,13 @@ variable has a true value, though.") "A `buffer' for one character. Used by PEEK-CHAR* and UNREAD-CHAR*.") +(defvar *max-line-length* nil + "Maximum length of a line. If NIL, lines may be any length.") + +(defvar *max-header-line-length* nil + "Maximum length of HTTP header lines. If NIL, defaults to +*MAX-LINE-LENGTH*.") + (pushnew :chunga *features*) ;; stuff for Nikodemus Siivola's HYPERDOC