Skip to content

Commit

Permalink
Merge pull request #155 from ionspin/152-invalid-string-parsed
Browse files Browse the repository at this point in the history
Check for base, and check if character belongs to base. Fixes #152
  • Loading branch information
ionspin authored Feb 11, 2021
2 parents abbc0a1 + 54bd3f7 commit fa306ad
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class BigInteger internal constructor(wordArray: WordArray, requestedSign: Sign)
val LOG_10_OF_2 = log10(2.0)

override fun parseString(string: String, base: Int): BigInteger {
if (base < 2 || base > 36) {
throw NumberFormatException("Unsupported base: $base. Supported base range is from 2 to 36")
}
val decimal = string.contains('.')
if (decimal) {
val bigDecimal = BigDecimal.parseString(string)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ internal object BigInteger32Arithmetic : BigInteger32ArithmeticInterface {
override fun parseForBase(number: String, base: Int): UIntArray {
var parsed = ZERO
number.forEach { char ->
parsed = (parsed * base.toUInt()) + char.toDigit().toUInt()
parsed = (parsed * base.toUInt()) + char.toDigit(base).toUInt()
}
return parsed
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerList63Arithmetic {
override fun parseForBase(number: String, base: Int): List<ULong> {
var parsed = ZERO
number.toLowerCase().forEach { char ->
parsed = (parsed * base.toULong()) + (char.toDigit()).toULong()
parsed = (parsed * base.toULong()) + (char.toDigit(base)).toULong()
}
return removeLeadingZeros(parsed)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1925,7 +1925,7 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic {
override fun parseForBase(number: String, base: Int): ULongArray {
var parsed = ZERO
number.toLowerCase().forEach { char ->
parsed = (parsed * base.toULong()) + (char.toDigit()).toULong()
parsed = (parsed * base.toULong()) + (char.toDigit(base)).toULong()
}
return removeLeadingZeros(
parsed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ package com.ionspin.kotlin.bignum.integer.util
* [email protected]
* on 18-Mar-2019
*/
fun Char.toDigit(): Int {
return when (this) {
fun Char.toDigit(base: Int = 10): Int {
// Check if number belongs to est used in base

val digit = when (this) {
in '0'..'9' -> (this - 48).toInt()
in 'a'..'z' -> this - 'a' + 10
in 'A'..'Z' -> this - 'A' + 10
Expand All @@ -32,4 +34,8 @@ fun Char.toDigit(): Int {
'.' -> throw NumberFormatException("Invalid digit for radix $this (Possibly a decimal value, which is not supported by BigInteger parser")
else -> throw NumberFormatException("Invalid digit for radix $this")
}
if (digit < 0 || digit >= base) {
throw NumberFormatException("$this is not a valid digit for number system with base $base")
}
return digit
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package com.ionspin.kotlin.bignum.integer

import kotlin.test.Test
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

/**
Expand Down Expand Up @@ -219,6 +220,22 @@ class BigIntegerReadmeTest {
val expected = BigInteger.parseString("12", 10)
bigint == expected
}

assertFailsWith(NumberFormatException::class) {
val parsed = BigInteger.parseString("a", 10)
}

assertFailsWith(NumberFormatException::class) {
val parsed = BigInteger.parseString("Z", 35)
}

assertFailsWith(NumberFormatException::class) {
val parsed = BigInteger.parseString("A", 37)
}

assertFailsWith(NumberFormatException::class) {
val parsed = BigInteger.parseString("A", 1)
}
}

@Test
Expand Down

0 comments on commit fa306ad

Please sign in to comment.