Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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

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

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
Copy link

Choose a reason for hiding this comment

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

wacky indentation

Copy link

Choose a reason for hiding this comment

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

do you lint

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*)
Copy link

Choose a reason for hiding this comment

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

again, wacky indentation

Copy link

Choose a reason for hiding this comment

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

@gefjon do you recommend any specific linter ?

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*)))
(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

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.

Copy link

@adlai adlai Sep 28, 2025

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

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

Copy link

@adlai adlai Sep 28, 2025

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