Skip to content

Commit e3a3bf0

Browse files
authored
Fix double quote encoding in basilisp.edn/write-string (#1073)
Fixes #1071
1 parent f0514ed commit e3a3bf0

File tree

3 files changed

+61
-23
lines changed

3 files changed

+61
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
### Fixed
1414
* Fix a bug where the reader was double counting the CRLF newline seq in metadata (#1063)
1515
* Conform to the `cider-nrepl` `info` ops spec by ensuring result's `:file` is URI, also added missing :column number (#1066)
16+
* Fix a bug with `basilisp.edn/write-string` where nested double quotes were not escaped properly (#1071)
1617

1718
## [v0.2.3]
1819
### Added

src/basilisp/edn.lpy

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,18 @@
539539
;; Writers ;;
540540
;;;;;;;;;;;;;
541541

542+
(def ^:private str-escape-chars-translation
543+
(python.str/maketrans
544+
#py {"\\" "\\\\"
545+
"\"" "\\\""
546+
"\a" "\\a"
547+
"\b" "\\b"
548+
"\f" "\\f"
549+
"\n" "\\n"
550+
"\r" "\\r"
551+
"\t" "\\t"
552+
"\v" "\\v"}))
553+
542554
(defprotocol EDNEncodeable
543555
(write* [this writer]
544556
"Write the object ``this`` to the stream ``writer`` encoded as EDN.
@@ -617,9 +629,10 @@
617629
nil)
618630
python/str
619631
(write* [this writer]
620-
(.write writer "\"")
621-
(.write writer this)
622-
(.write writer "\"")
632+
(let [decoded (.translate this str-escape-chars-translation)]
633+
(.write writer "\"")
634+
(.write writer decoded)
635+
(.write writer "\""))
623636
nil)
624637
nil
625638
(write* [_this writer]

tests/basilisp/test_edn.lpy

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -365,28 +365,52 @@
365365
\u03A9 "\"Ω\""
366366

367367
\space "\" \""
368-
\newline "\"\n\""
369-
\tab "\"\t\""
370-
\return "\"\r\""))
368+
\newline "\"\\n\""
369+
\tab "\"\\t\""
370+
\return "\"\\r\""))
371371

372372
(deftest write-string
373-
(are [v s] (= s (edn/write-string v))
374-
"" "\"\""
375-
" " "\" \""
376-
"\"" "\"\"\""
377-
"\\" "\"\\\""
378-
"\a" "\"\a\""
379-
"\b" "\"\b\""
380-
"\f" "\"\f\""
381-
"\n" "\"\n\""
382-
"\r" "\"\r\""
383-
"\t" "\"\t\""
384-
"\v" "\"\v\""
385-
386-
"Hello,\nmy name is\tChris." "\"Hello,\nmy name is\tChris.\""
387-
"Regular string" "\"Regular string\""
388-
"String with 'inner string'" "\"String with 'inner string'\""
389-
"String with \"inner string\"" "\"String with \"inner string\"\""))
373+
(testing "expected outputs"
374+
(are [v s] (= s (edn/write-string v))
375+
"" "\"\""
376+
" " "\" \""
377+
"\"" "\"\\\"\""
378+
"\\" "\"\\\\\""
379+
"\a" "\"\\a\""
380+
"\b" "\"\\b\""
381+
"\f" "\"\\f\""
382+
"\n" "\"\\n\""
383+
"\r" "\"\\r\""
384+
"\t" "\"\\t\""
385+
"\v" "\"\\v\""
386+
387+
(str ["a"]) "\"[\\\"a\\\"]\""
388+
389+
"Hello,\nmy name is\tChris." "\"Hello,\\nmy name is\\tChris.\""
390+
"Regular string" "\"Regular string\""
391+
"String with 'inner string'" "\"String with 'inner string'\""
392+
"String with \"inner string\"" "\"String with \\\"inner string\\\"\""))
393+
394+
(testing "round-trip"
395+
(are [s] (= s (edn/read-string (edn/write-string s)))
396+
""
397+
" "
398+
"\""
399+
"\\"
400+
"\a"
401+
"\b"
402+
"\f"
403+
"\n"
404+
"\r"
405+
"\t"
406+
"\v"
407+
408+
(str ["a"])
409+
410+
"Hello,\nmy name is\tChris."
411+
"Regular string"
412+
"String with 'inner string'"
413+
"String with \"inner string\"")))
390414

391415
(deftest write-dispatch
392416
(are [v s] (= s (edn/write-string v))

0 commit comments

Comments
 (0)