CLJS implementation does not parse longs properly
prook opened this issue · comments
When using bidi for client-side routing, [long :param]
can be parsed incorrectly, because bidi uses js/Number to parse the parameter. Since JS numbers are double precision floats, it is only possible to store integer values in ±2^53 range. When using large long (as in 64-bit integer) values, the following loss of precision silently occurs:
(bidi.bidi/match-route [[[long :val]] :uh-oh] "9223372036854775807")
=> {:route-params {:val 9223372036854776000}, :handler :uh-oh}
This is confusing, dangerous, and can be easily missed.
Possible solutions:
- Use goog.math.Long instead of js/Number to prevent precision loss,
- add some kind of range checking when parsing the param, or check something like
(= (goog.math.Long. val) (goog.math.Long. (js/Number val))
to at least warn about precision loss, or - remove support for
long
coercion and let people know it's their responsibility to parse their numbers.