From 6e218fa979f0f079062c272ec5d2e1b9a1d57cf3 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 6 Aug 2026 23:41:03 +0200 Subject: [PATCH] Fix overflow approximating fractions of large negative constants FractionApprox rejects inputs above 0x7FFFFFFF because they cannot be stored as a fraction, but the check was one-sided while the sign is stripped right after it. A large negative value therefore reached the continued-fraction loop and overflowed the terms it accumulates. ICSharpCode.Decompiler is built with CheckForOverflowUnderflow, so that aborted decompilation of the whole member instead of wrapping. Found by fuzzing nuget.org; reproduces on MathNet.Numerics, whose constants reach the approximation through their ratio to PI. Assisted-by: Claude:claude-opus-5[1m]:Claude Code --- .../TestCases/Pretty/WellKnownConstants.cs | 5 +++++ ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.cs index b77d38dfd..c26aeb947 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/WellKnownConstants.cs @@ -202,5 +202,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty public const double Double_Negated_E = -Math.E; public const double Double_Negated_BeforeE = -2.7182818284590446; public const double Double_Negated_AfterE = -2.7182818284590455; + + // Values of either sign whose ratio to PI or E is outside the range expressible as + // a fraction must be left alone rather than run through the approximation. + public const double Double_TooLargeForFraction = 3085105840164255.5; + public const double Double_Negated_TooLargeForFraction = -3085105840164255.5; } } diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index ad07cb6fc..2d8654a18 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -1724,7 +1724,10 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax // we just keep the last partial product of these matrices. static (long Num, long Den) FractionApprox(double value, int maxDenominator) { - if (value > 0x7FFFFFFF) + // The range check has to be on the magnitude: the sign is stripped below, so a + // large negative value would otherwise reach the continued-fraction loop and + // overflow the terms it accumulates. + if (Math.Abs(value) > 0x7FFFFFFF) return (0, 0); double startValue = value;