juxt / bidi

Bidirectional URI routing

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.