Good Morning!
Morning!
👋
☀️
Morning
mogge
Good morning
morning
morning
Good morning!
I’m currently working on a Clojure codebase that makes quite heavy use of spec. Today the app crashes on me during a demo because I use brackets in a text field whose contents are used in an HTTP request to the backend. The regex doesn’t allow ‘(’
(def url-regex
(re-pattern "(http|ftp|https)://[\\w-]+(\\.[\\w-]+)*([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?"))
(s/def ::url (s/and string? #(re-matches url-regex %)))
Now if I’m reading the spec correctly brackets are allowed:So now I could revise the regex to allow brackets, but is there value in keeping this spec at all?
And perhaps more generally, has anyone had the experience that overspeccing ends up making a system more brittle than it has to be?
As I work with the same project, I might add that the Uri component is first escaped using js/encodeURIComponent
, then checked with that spec. 😃
I would struggle to write a regexp that covered all valid URIs
Seems like the URL spec there could help with it, but indeed, it is daunting anyway.
Expert answer is that “it depends”
What are the ramifications of someone fatfingering here?
My version of a URI spec would be using java.net.URI or JS’s URL classes to parse the string, catch the error and return nil such that the spec fails when it’s unparseable
And what do you actually care about? Seems like you care about limiting your protocols to http(s) and ftp?
@slipset Thing is that all that is provided by us, the user only provides a query string. We encode that string and build the URL. The result is then spec checked. I think it feels like we are specing js/encodeUriComponent
, and also don’t feel like that is our responsibility.
I guess y’all seen the complete regex for emails? How much value does it bring to the table over just checking for a string that contains an @
?
We have had failures to register with our app because our email-regex was stopping valid email addresses too. 😃
So the user provides “/foo/bar/baz?lol” and based on that you create “http://wahtever.com/foo/bar/baz?lol” then I wouldn’t bother with the spec.
The user provides lol
, but yeah. 😃
A perhaps stupid questions, regarding specs… Is anyone using fdef
s in their unit test namespaces to instrument the functions under test there, instead of doing it where the functions are defined?
Indeed, but also, given how the URL is being built it would be redundant to validate it anyways.
@pez I’ve got a library for this, called re-speced
Ah, that looks nice!
Thanks for the feedback, I’ve seen a couple of situations were an app crashes unnecessarily because of a spec being too narrow, and so I’m questioning the very liberal use of specs throughout a codebase. I have found the guideline to “only spec what is necessary” useful. Wondering if other people have had similar experiences
Regarding mails: I’d verify for @ and a single dot in the host part. You maybe don’t want to support bang paths but who cares? #"\s.+@[^.]+\.[^.]+\s"
This reminded me of something that popped up on hacker news, I found the article <https://www.netmeister.org/blog/email.html>
There is a lot to email validation
@anthony-galea My rule of thumb: Spec vulnerable points of your system: E.g. where data enters or leaves (the outer shell), untrusted sources and the like. Loosen it for (core) layers which highly benefit from data flexibility.
I really like how @weavejester tackled this: https://github.com/weavejester/valip/blob/master/src/valip/predicates.clj#L50-L65