bidi icon indicating copy to clipboard operation
bidi copied to clipboard

CLJS implementation does not parse longs properly

Open prook opened this issue 6 years ago • 0 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.

prook avatar Jan 30 '20 15:01 prook