object SafeNumbers
Total, fast, number parsing.
The Java and Scala standard libraries throw exceptions when we attempt to parse an invalid number. Unfortunately, exceptions are very expensive, and untrusted data can be maliciously constructed to DOS a server.
This suite of functions mitigates against such attacks by building up the numbers one character at a time, which has been shown through extensive benchmarking to be orders of magnitude faster than exception-throwing stdlib parsers, for valid and invalid inputs. This approach, proposed by alexknvl, was also benchmarked against regexp-based pre-validation.
Note that although the behaviour is identical to the Java stdlib when given
the canonical form of a primitive (i.e. the .toString) of a number there may
be differences in behaviour for non-canonical forms. e.g. the Java stdlib
may reject "1.0" when parsed as an BigInteger
but we may parse it as a
1
, although "1.1" would be rejected. Parsing of BigDecimal
preserves the
trailing zeros on the right but not on the left, e.g. "000.00001000" will be
"1.000e-5", which is useful in cases where the trailing zeros denote
measurement accuracy.
BigInteger
, BigDecimal
, Float
and Double
have a configurable bit
limit on the size of the significand, to avoid OOM style attacks, which is
128 bits by default.
Results are contained in a specialisation of Option that avoids boxing.
- Alphabetic
- By Inheritance
- SafeNumbers
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def bigDecimal(num: String, max_bits: Int = 128): Option[BigDecimal]
- def bigInteger(num: String, max_bits: Int = 128): Option[BigInteger]
- def byte(num: String): ByteOption
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native()
- def double(num: String, max_bits: Int = 128): DoubleOption
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- def float(num: String, max_bits: Int = 128): FloatOption
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def int(num: String): IntOption
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- def long(num: String): LongOption
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- def short(num: String): ShortOption
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(x: Float): String
- def toString(x: Double): String
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()