Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
* Fix a bug where the reader was double counting the CRLF newline seq in metadata (#1063)
* Conform to the `cider-nrepl` `info` ops spec by ensuring result's `:file` is URI, also added missing :column number (#1066)
* Fix a bug with `basilisp.edn/write-string` where nested double quotes were not escaped properly (#1071)

## [v0.2.3]
### Added
Expand Down
19 changes: 16 additions & 3 deletions src/basilisp/edn.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,18 @@
;; Writers ;;
;;;;;;;;;;;;;

(def ^:private str-escape-chars-translation
(python.str/maketrans
#py {"\\" "\\\\"
"\"" "\\\""
"\a" "\\a"
"\b" "\\b"
"\f" "\\f"
"\n" "\\n"
"\r" "\\r"
"\t" "\\t"
"\v" "\\v"}))

(defprotocol EDNEncodeable
(write* [this writer]
"Write the object ``this`` to the stream ``writer`` encoded as EDN.
Expand Down Expand Up @@ -617,9 +629,10 @@
nil)
python/str
(write* [this writer]
(.write writer "\"")
(.write writer this)
(.write writer "\"")
(let [decoded (.translate this str-escape-chars-translation)]
(.write writer "\"")
(.write writer decoded)
(.write writer "\""))
nil)
nil
(write* [_this writer]
Expand Down
64 changes: 44 additions & 20 deletions tests/basilisp/test_edn.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -365,28 +365,52 @@
\u03A9 "\"Ω\""

\space "\" \""
\newline "\"\n\""
\tab "\"\t\""
\return "\"\r\""))
\newline "\"\\n\""
\tab "\"\\t\""
\return "\"\\r\""))

(deftest write-string
(are [v s] (= s (edn/write-string v))
"" "\"\""
" " "\" \""
"\"" "\"\"\""
"\\" "\"\\\""
"\a" "\"\a\""
"\b" "\"\b\""
"\f" "\"\f\""
"\n" "\"\n\""
"\r" "\"\r\""
"\t" "\"\t\""
"\v" "\"\v\""

"Hello,\nmy name is\tChris." "\"Hello,\nmy name is\tChris.\""
"Regular string" "\"Regular string\""
"String with 'inner string'" "\"String with 'inner string'\""
"String with \"inner string\"" "\"String with \"inner string\"\""))
(testing "expected outputs"
(are [v s] (= s (edn/write-string v))
"" "\"\""
" " "\" \""
"\"" "\"\\\"\""
"\\" "\"\\\\\""
"\a" "\"\\a\""
"\b" "\"\\b\""
"\f" "\"\\f\""
"\n" "\"\\n\""
"\r" "\"\\r\""
"\t" "\"\\t\""
"\v" "\"\\v\""

(str ["a"]) "\"[\\\"a\\\"]\""

"Hello,\nmy name is\tChris." "\"Hello,\\nmy name is\\tChris.\""
"Regular string" "\"Regular string\""
"String with 'inner string'" "\"String with 'inner string'\""
"String with \"inner string\"" "\"String with \\\"inner string\\\"\""))

(testing "round-trip"
(are [s] (= s (edn/read-string (edn/write-string s)))
""
" "
"\""
"\\"
"\a"
"\b"
"\f"
"\n"
"\r"
"\t"
"\v"

(str ["a"])

"Hello,\nmy name is\tChris."
"Regular string"
"String with 'inner string'"
"String with \"inner string\"")))

(deftest write-dispatch
(are [v s] (= s (edn/write-string v))
Expand Down