Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions conditions.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should probably also get type-declared, if possible; some fascist implementations might like allocating conditions on the stack and bitch about boxed pointer safety garbage

:documentation "The limit which was exceeded."))
(:report (lambda (condition stream)
(with-slots (maximum)
condition
(format stream "Input exceeded ~d characters." maximum))))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that format call will definitely be more efficient with at least one e.g. (the fixnum maximum)

(:documentation "A condition of this type is signaled if an
maximum-character limit is exceeded."))
6 changes: 5 additions & 1 deletion read.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -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*
Expand Down Expand Up @@ -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*)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'll never fit in stack frames if python doesn't compute integer-length at compile time

(labels ((read-header-line ()
"Reads one header line, considering continuations."
(with-output-to-string (header-line)
Expand Down
7 changes: 7 additions & 0 deletions specials.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add declaim of type for this and the other special var. I assume the correct type is (or null unsigned-byte), but it may be (or null (and fixnum unsigned-byte)) or something.

@adlai adlai Sep 28, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(or null unsigned-byte), but it may be (or null (and fixnum unsigned-byte))

(cl:deftype chunga:maybe-pointer
  '(or null fixnum) "I'm useless")

The point of this PR is to provably bound memory consumption, and thus the type specifier must not allow any non-fixnum values.

"Maximum length of a line. If NIL, lines may be any length.")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd appreciate more documentation. The docstring should address:

  • what happens when attempting to read an overlong line.
  • appropriate types and values this variable may take

@adlai adlai Sep 28, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • appropriate types and values this variable may take

why can't compilers rely on humans to read this out of #'cl:describe-object output?


(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
Expand Down