lib/parameters.scm:parameters->alist
(define (parameters->alist p)
(map parameter->pair (string-split p #\&)))
lib/utils.scm:string-split
; Splits the input string 'str into a list of strings
; based on the delimiter character 'ch
; © (Doug Hoyte, hcsw.org)
(define (string-split str ch)
(let ((len (string-length str)))
(letrec
((split
(lambda (a b)
(cond
((>= b len) (if (= a b) '() (cons (substring str a b) '())))
((char=? ch (string-ref str b))
(if (= a b)
(split (+ 1 a) (+ 1 b))
(cons (substring str a b) (split b b))))
(else (split a (+ 1 b)))))))
(split 0 0))))
Because of the split-in-cons line this is recursive rather than iterative. This means that it can be stress tested on the stack depth. In the REPL of MIT/GNU Scheme 9.1.1:
$ mit-scheme --load lib/utils.scm --load lib/parameters.scm
[...]
Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41
LIAR/x86-64 4.118 || Edwin 3.116
;Loading "lib/utils.scm"... done
;Loading "lib/parameters.scm"... done
1 ]=> (define (test n) (parameters->alist (apply string-append (make-list n "&x=x"))) 'ok)
;Value: test
1 ]=> (test 42308)
;Value: ok
1 ]=> (test 42309)
;Aborting!: maximum recursion depth exceeded
1 ]=>
With an appropriately crafted wget post request textboard.org yields:
HTTP/1.1 502 Bad Gateway
Server: nginx/1.18.0
Date: Thu, 02 Jul 2020 00:41:44 GMT
Content-Type: text/html
Content-Length: 496
Connection: keep-alive
ETag: "5ecc391b-1f0"
The length of 'body' should be validated in post-message and post-thread, before computing 'params'. Something like (* 2 *max-post-size*) should be more than enough. And string-split should be made iterative, in the style of string-split*.
The POST server went down with a forged request of thousands of query strings.
...
nomadism
That sounds cool but please try to stay safe from pandemic stuff.