From 53426c0a3e190a3329a28f5cd645389992d5bfea Mon Sep 17 00:00:00 2001 From: Phil Hagelberg Date: Sun, 19 Oct 2025 13:28:44 -0700 Subject: [PATCH] Don't loop endlessly on EOF in server mode. --- src/fennel-ls/json-rpc.fnl | 19 +++++++++---------- test/cli.fnl | 2 +- test/json-rpc.fnl | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/fennel-ls/json-rpc.fnl b/src/fennel-ls/json-rpc.fnl index 086c1b7..5bd7cfc 100644 --- a/src/fennel-ls/json-rpc.fnl +++ b/src/fennel-ls/json-rpc.fnl @@ -19,16 +19,15 @@ on the empty table to tell dkjson to serialize as {}." (λ read-header [in ?header] "Reads the header of a JSON-RPC message" - (let [header (or ?header {})] - (case (in:read) - nil nil ;; I've hit end of stream, return nil instead of a header - line (case (line:match "^(.-)\r?$") ;; strip trailing \r - "" header ;; base case. empty line marks end of header - line (let [(k v) (line:match "^(.-): (.-)$")] - (if (not (and k v)) - (error (.. "fennel-ls encountered a malformed json-rpc header: \"" line "\""))) - (tset header k v) - (read-header in header)))))) + (let [header (or ?header {}) + line (assert (in:read) "EOF")] + (case (line:match "^(.-)\r?$") ;; strip trailing \r + "" header ;; base case. empty line marks end of header + line (let [(k v) (line:match "^(.-): (.-)$")] + (if (not (and k v)) + (error (.. "fennel-ls encountered a malformed json-rpc header: \"" line "\""))) + (tset header k v) + (read-header in header))))) (λ read-n [in len ?buffer] "read a string of exactly `len` characters from the `in` stream. diff --git a/test/cli.fnl b/test/cli.fnl index b70911d..f60ee80 100644 --- a/test/cli.fnl +++ b/test/cli.fnl @@ -26,7 +26,7 @@ (with-temp-form [f [(let [(a b) (values 1 (+ 2))] (+ a b)) [(do (print "done doing all the fun things we did!"))]] out "./fennel-ls --fix --yes"] - (faith.= "[(let [[a b] [(values 1 2)]] (+ a b)) + (faith.= "[(let [(a b) (values 1 2)] (+ a b)) [(print \"done doing all the fun things we did!\")]]" (with-open [file (assert (io.open f))] (file:read :*a)) out))) diff --git a/test/json-rpc.fnl b/test/json-rpc.fnl index a9fa596..cc26c5f 100644 --- a/test/json-rpc.fnl +++ b/test/json-rpc.fnl @@ -9,7 +9,7 @@ (let [out (stringio.open "Content-Length: 29\r\n\r\n{\"my json content\":\"is cool\"}Content-Length: 29\r\n\r\n{\"my json content\":\"is neat\"}")] (faith.= {"my json content" "is cool"} (json-rpc.read out)) (faith.= {"my json content" "is neat"} (json-rpc.read out)) - (faith.= nil (json-rpc.read out))) + (faith.error "EOF" #(json-rpc.read out))) (let [out (stringio.open "Content-Length: 9\r\n\r\n{{{{{}}}}")] (faith.= :string (type (json-rpc.read out)) "json-rpc returns a table on successful read, and a string on unsuccessful read. It's jank and should probably be replaced with an ok, err system")))