diff --git a/sources/Text/Parser.uc b/sources/Text/Parser.uc index 86a9265..f7a67d6 100644 --- a/sources/Text/Parser.uc +++ b/sources/Text/Parser.uc @@ -568,7 +568,9 @@ public final function Parser MUnsignedInteger( nextPosition = _.text.CharacterToInt(GetCharacter(), base); if (nextPosition < 0) break; - result = result * base + nextPosition; + // This `result = result * base + nextPosition`, + // but protected from integer overflow + result = SafeIntegerCombination(result, base, nextPosition); consumedCodePoints += 1; ShiftPointer(); } @@ -580,6 +582,36 @@ public final function Parser MUnsignedInteger( return self; } +/** + * Auxiliary method for a adding another numeric position `addition` to the + * given `baseValue` in base the `multiplier`, effectively performing: + * `baseValue * multiplier + addition`, but safely truncated at + * `MaxInt = 0x7fffffff`, preventing integer overflow. + * + * @param baseValue Initial value to modify by multiplication and addition. + * @param multiplier Value to first multiply given `baseValue` first. + * @param addition Value to add to the result of multiplication of + * `baseValue` and `multiplier`. + * @return `baseValue * multiplier + addition` truncated at + * `MaxInt = 0x7fffffff`, preventing integer overflow. + */ +protected final function int SafeIntegerCombination( + int baseValue, + int multiplier, + int addition) +{ + local int safeThreshold; + safeThreshold = MaxInt / multiplier; + if (baseValue > safeThreshold) { + return MaxInt; + } + baseValue *= multiplier; + if (MaxInt - baseValue < addition) { + return MaxInt; + } + return baseValue + addition; +} + /** * Parses escaped sequence of the type that is usually used in * string literals: backslash "\"", followed by any character diff --git a/sources/Text/Tests/TEST_Parser.uc b/sources/Text/Tests/TEST_Parser.uc index 75faa58..37d2da9 100644 Binary files a/sources/Text/Tests/TEST_Parser.uc and b/sources/Text/Tests/TEST_Parser.uc differ