From 2819ab4ae9dca184bab57d4c3790847899f186bb Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Wed, 18 Sep 2019 03:17:32 +0300 Subject: [PATCH] Avoid division in string-to-unsigned conversions (KT-26309) --- .../stdlib/unsigned/src/kotlin/UStrings.kt | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/libraries/stdlib/unsigned/src/kotlin/UStrings.kt b/libraries/stdlib/unsigned/src/kotlin/UStrings.kt index f9dc3b77bd2..255d0dfa6e8 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UStrings.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UStrings.kt @@ -198,14 +198,26 @@ public fun String.toUIntOrNull(radix: Int): UInt? { start = 0 } + val limitForMaxRadix = 119304647u // limit / 36 + + var limitBeforeMul = limitForMaxRadix val uradix = radix.toUInt() - val limitBeforeMul = limit / uradix var result = 0u for (i in start until length) { val digit = digitOf(this[i], radix) if (digit < 0) return null - if (result > limitBeforeMul) return null + if (result > limitBeforeMul) { + if (limitBeforeMul == limitForMaxRadix) { + limitBeforeMul = limit / uradix + + if (result > limitBeforeMul) { + return null + } + } else { + return null + } + } result *= uradix @@ -251,14 +263,26 @@ public fun String.toULongOrNull(radix: Int): ULong? { } - val uradix = radix.toUInt() - val limitBeforeMul = limit / uradix + val limitForMaxRadix = 512409557603043100uL // limit / 36 + + var limitBeforeMul = limitForMaxRadix + val uradix = radix.toULong() var result = 0uL for (i in start until length) { val digit = digitOf(this[i], radix) if (digit < 0) return null - if (result > limitBeforeMul) return null + if (result > limitBeforeMul) { + if (limitBeforeMul == limitForMaxRadix) { + limitBeforeMul = limit / uradix + + if (result > limitBeforeMul) { + return null + } + } else { + return null + } + } result *= uradix