From b36f38f48fa385e22a6fd861e87a395dec2ab502 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 5 Sep 2024 09:08:53 +0200 Subject: [PATCH] classlib: fix parsing floats and doubles with large exponents --- .../java/org/teavm/classlib/impl/text/DoubleSynthesizer.java | 5 ++++- .../java/org/teavm/classlib/impl/text/FloatSynthesizer.java | 5 ++++- .../test/java/org/teavm/classlib/java/lang/DoubleTest.java | 1 + .../test/java/org/teavm/classlib/java/lang/FloatTest.java | 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/impl/text/DoubleSynthesizer.java b/classlib/src/main/java/org/teavm/classlib/impl/text/DoubleSynthesizer.java index 71f4dc43d..3cbb6ead7 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/text/DoubleSynthesizer.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/text/DoubleSynthesizer.java @@ -21,9 +21,12 @@ public final class DoubleSynthesizer { public static double synthesizeDouble(long mantissa, int exp, boolean negative) { var indexInTable = DoubleAnalyzer.MAX_ABS_DEC_EXP + exp; - if (mantissa == 0 || indexInTable > mantissa10Table.length || indexInTable < 0) { + if (mantissa == 0 || indexInTable < 0) { return Double.longBitsToDouble(negative ? (1L << 63) : 0); } + if (indexInTable >= mantissa10Table.length) { + return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + } var binMantissa = DoubleAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0); int binExp = exp10Table[indexInTable]; diff --git a/classlib/src/main/java/org/teavm/classlib/impl/text/FloatSynthesizer.java b/classlib/src/main/java/org/teavm/classlib/impl/text/FloatSynthesizer.java index 5471153bf..164d81e9d 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/text/FloatSynthesizer.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/text/FloatSynthesizer.java @@ -21,9 +21,12 @@ public final class FloatSynthesizer { public static float synthesizeFloat(int mantissa, int exp, boolean negative) { var indexInTable = FloatAnalyzer.MAX_ABS_DEC_EXP + exp; - if (mantissa == 0 || indexInTable > mantissa10Table.length || indexInTable < 0) { + if (mantissa == 0 || indexInTable < 0) { return Float.intBitsToFloat(negative ? (1 << 31) : 0); } + if (indexInTable >= mantissa10Table.length) { + return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY; + } var binMantissa = FloatAnalyzer.mulAndShiftRight(mantissa, mantissa10Table[indexInTable], 0); var binExp = exp10Table[indexInTable] - 1; diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java index 178e7bec2..d867188f8 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/DoubleTest.java @@ -57,6 +57,7 @@ public class DoubleTest { assertEquals(4499999999999888888888888.0, Double.parseDouble("4499999999999888888888888"), 1E9); assertEquals(0.4499999999999888888888888, Double.parseDouble("0.4499999999999888888888888"), 1E-15); + assertEquals(Double.POSITIVE_INFINITY, Double.parseDouble("1e330"), 1E-15); } @Test diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java index 57190126c..9b67fca41 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/FloatTest.java @@ -55,6 +55,7 @@ public class FloatTest { assertEquals(0, Float.parseFloat("00000.0000"), 1E-12F); assertEquals(4499999285F, Float.parseFloat("4499999285"), 100F); assertEquals(0.4499999285F, Float.parseFloat("0.4499999285"), 1E-9F); + assertEquals(Float.POSITIVE_INFINITY, Float.parseFloat("1e50"), 1E-9F); } @Test