Is the #= tag described anywhere at all in the clojure docs? I don't see it mentioned on either the reader page, or on the "weird characters" page. It seems like an important oversight.
Thank you @p-himik - it's too bad, since it is the justification to use things like clojure.edn/read and it's harder to understand why if people can't even read about it in the first place.
"Here Be #=agons!"
I don't follow - why isn't read useful without #=?
I never said it wasn't useful - I meant to say that it's not clear to people (such as my coworkers who are learning clojure) why to use one reader over another, given the described/documented features of them. Since the "unsafe" parts aren't documented, it is hard to understand beyond "don't do it, it's not safe", which isn't too satisfying.
read's docstring says:
Note that read can execute code (controlled by *read-eval*),
and as such should be used only with trusted sources.(I'm reading the upcoming 4th edition of the prag prog book along with my coworkers, and I'm trying to clarify things for them along the way. When I learned clojure, there weren't any books.)
So that should be a flag that caution is needed.
Thanks for pointing that out as well @seancorfield.
It also says:
For data structure interop use clojure.edn/read(I hadn't noticed that last one until just now)
I think it's clear what the recommendations are - it's just "hard" to understand the whys.
Anyway, I appreciate all the clarifications.
I was curious, so I compared the docstring for read across multiple Clojure versions:
• the cautionary wording and reference to clojure.edn/read was added in Clojure 1.5 (when clojure.edn was added I believe?)
• clojure.repl/doc did not exist in Clojure 1.2 and earlier apparently
I believe doc was moved at some point
I think there is some hesitance to document read-eval because it is sort of an implementation detail that has partly escaped confinement. it exists as a feature to support the compiler serializing arbitrary objects into bytecode (the fallback case being a string constant created with pr-str and then read back with read-string)
Ah, doc was in clojure.core in 1.2 and earlier. I initially thought it was in clojure.main...
Yes, I understand that point of view (not wanting to spread the knowledge around) as well. Personally, if I use code everyday that has a certain built-in vulnerability, I'd want it to be clearly documented and obvious. You can discover its existence by reading the main github page for clojure.tools.reader - it's not exactly a secret.
On the other hand, I wouldn't argue that this is something that must change. I understand - I was mostly just confused by it not being mentioned at all, while clearly existing.
yeah, it seems like the general approach is instead of documenting the specific feature that makes clojure.core/read unsuitable for untrusted input, to instead document that you should use clojure.edn/read-string for untrusted input
https://github.com/clojure/clojure/blob/master/changes.md#212-new-edn-reader-improvements-to-read-eval is the relevant bit in the release docs re read-eval in 1.5
and https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/*read-eval* is the referenced docstring
the set of cases where read may eval arbitrary code is a potentially open set in the future. existing cases are #=, java constructor readers