From d9efb64163976609f4f96240e2e91a41520f098d Mon Sep 17 00:00:00 2001 From: usefahmed07 Date: Tue, 22 Sep 2026 17:42:52 +0300 Subject: [PATCH 1/2] Reject non-canonical (leading-zero) numbers in older()/after() and multi() count parsing --- NBitcoin/WalletPolicies/Miniscript.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/NBitcoin/WalletPolicies/Miniscript.cs b/NBitcoin/WalletPolicies/Miniscript.cs index 358534495..25462a4e1 100644 --- a/NBitcoin/WalletPolicies/Miniscript.cs +++ b/NBitcoin/WalletPolicies/Miniscript.cs @@ -222,6 +222,11 @@ private static bool TryParseParameterCount(ParsingContext ctx, [MaybeNullWhen(tr error = null; node = null; var match = Regex.Match(ctx.Remaining, @"^[0-9]+"); + if (match.Value.Length > 1 && match.Value[0] == '0') + { + error = new MiniscriptError.CountExpected(ctx.Offset); + return false; + } if (uint.TryParse(match.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var v) && v < Int32.MaxValue) { ctx.Advance(match.Length); @@ -257,6 +262,11 @@ private static bool TryParseLocktime(ParsingContext ctx, [MaybeNullWhen(true)] o node = null; error = null; var match = Regex.Match(ctx.Remaining, @"^[0-9]+"); + if (match.Value.Length > 1 && match.Value[0] == '0') + { + error = new MiniscriptError.LocktimeExpected(ctx.Offset); + return false; + } if (uint.TryParse(match.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var v)) { ctx.Advance(match.Length); From 07beae7aa3e2abddf8158fd5db990d76604348a2 Mon Sep 17 00:00:00 2001 From: usefahmed07 Date: Tue, 22 Sep 2026 17:48:07 +0300 Subject: [PATCH 2/2] Add tests for non-canonical (leading-zero) older()/after()/multi() count values --- NBitcoin.Tests/MiniscriptTests.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/NBitcoin.Tests/MiniscriptTests.cs b/NBitcoin.Tests/MiniscriptTests.cs index d760f1739..d44881443 100644 --- a/NBitcoin.Tests/MiniscriptTests.cs +++ b/NBitcoin.Tests/MiniscriptTests.cs @@ -71,6 +71,21 @@ public void CanRoundtripMiniscript(string miniscript) Assert.Equal(miniscript, actual); } + [Theory] + // https://github.com/MetacoSA/NBitcoin/issues/1283 + [InlineData("older(000000002088829000)", false)] + [InlineData("older(01)", false)] + [InlineData("after(01)", false)] + [InlineData("multi(01,A,B)", false)] + [InlineData("older(0)", true)] + [InlineData("older(1000)", true)] + [InlineData("after(1000)", true)] + public void RejectsNonCanonicalNumbers(string miniscript, bool expected) + { + var settings = new MiniscriptParsingSettings(Network.RegTest, KeyType.Classic) { AllowedParameters = ParameterTypeFlags.All }; + Assert.Equal(expected, Miniscript.TryParse(miniscript, settings, out _)); + } + [Theory] [InlineData(ParameterTypeFlags.All, "pkh(A)", true)] [InlineData(ParameterTypeFlags.All, "pkh(@0/**)", true)]