From 14c295d9309f0f6287979d3bfd1be8a7e0073630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gro=C3=9F?= Date: Wed, 11 Nov 2026 06:35:07 +0100 Subject: [PATCH 1/3] test: hostile-input rows carry only their name, so no megabyte string is a test argument (#535) A DynamicData row's arguments travel in every message the test host sends about the row. With the hostile text as an argument, one results message of ParserResilienceTests was 20 MB, and vstest.console in SDK 11.0.100 ran at full CPU on it for ten minutes without ending the run. The same assembly passed in 8 seconds through SDK 11.0.100-rc.2's runner. The rows now hold the name, and each test builds its text from it. The largest message in a --diag log is 31 KB, and the suite ends in 3 seconds on SDK 11.0.100. Found-By: CA Defect-Class: PKG Co-Authored-By: Claude Fable 5.2 --- .../ParserResilienceTests.cs | 79 +++++++++++-------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/test/CodoMetis.ValueRanges.Tests/ParserResilienceTests.cs b/test/CodoMetis.ValueRanges.Tests/ParserResilienceTests.cs index 8a704818..9eb80df0 100644 --- a/test/CodoMetis.ValueRanges.Tests/ParserResilienceTests.cs +++ b/test/CodoMetis.ValueRanges.Tests/ParserResilienceTests.cs @@ -23,40 +23,52 @@ public sealed class ParserResilienceTests // Each entry: a name, and the hostile text. Rejection is expected for most; a few are valid and // must simply not be slow (whitespace flood, huge but well-formed sets). - public static IEnumerable HostileRangeLiterals() => - [ - ["digit run of a million characters", $"[{new string('1', Size)},2]"], - ["a million opening brackets", new string('[', Size)], - ["a million characters of garbage bound", $"[{new string('x', Size)},1]"], - ["a million characters of whitespace", $"{new string(' ', Size)}[1,2]"], - ["a million quotes inside the bound", $"[\"{new string('"', Size)},2]"], - ["a million backslashes inside quotes", $"[\"{new string('\\', Size)}\",2]"], - ["a million commas", $"[{new string(',', Size)}]"], - ]; - - public static IEnumerable HostileSetLiterals() => - [ - ["two hundred thousand ranges", "{" + string.Join(",", Enumerable.Range(0, 200_000).Select(i => $"[{i * 2},{i * 2 + 1}]")) + "}"], - ["two hundred thousand identical ranges", "{" + string.Join(",", Enumerable.Repeat("[1,10]", 200_000)) + "}"], - ["a million nested brackets", "{" + new string('[', Size) + "}"], - ["a million characters, never closed", "{" + new string('[', Size)], - ]; - - public static IEnumerable HostileArrayLiterals() => - [ - ["two hundred thousand elements", "{" + string.Join(",", Enumerable.Range(0, 200_000).Select(i => $"e{i}")) + "}"], - ["a million escaped quotes in one element", "{\"" + string.Concat(Enumerable.Repeat("\\\"", Size / 2)) + "\"}"], - ["an unterminated quoted element", "{\"" + new string('a', Size)], - ["an unterminated escape", "{\"" + new string('a', Size) + "\\"], - ["a million commas", "{" + new string(',', Size) + "}"], - ["one element of a million characters", "{" + new string('a', Size) + "}"], - ]; + // + // A row carries only the name, and the test builds its text from it. A row's arguments travel in + // every message the test host sends about that row, so with the text as an argument one results + // message was 20 MB, and vstest.console in SDK 11.0.100 did not get through it in ten minutes: `dotnet test` + // ran at full CPU after the last test had passed (#535). SDK 11.0.100-rc.2 read it in seconds. + private static readonly Dictionary> RangeLiterals = new() + { + ["digit run of a million characters"] = () => $"[{new string('1', Size)},2]", + ["a million opening brackets"] = () => new string('[', Size), + ["a million characters of garbage bound"] = () => $"[{new string('x', Size)},1]", + ["a million characters of whitespace"] = () => $"{new string(' ', Size)}[1,2]", + ["a million quotes inside the bound"] = () => $"[\"{new string('"', Size)},2]", + ["a million backslashes inside quotes"] = () => $"[\"{new string('\\', Size)}\",2]", + ["a million commas"] = () => $"[{new string(',', Size)}]", + }; + + public static IEnumerable HostileRangeLiterals() => RangeLiterals.Keys.Select(name => new object[] { name }); + + private static readonly Dictionary> SetLiterals = new() + { + ["two hundred thousand ranges"] = () => "{" + string.Join(",", Enumerable.Range(0, 200_000).Select(i => $"[{i * 2},{i * 2 + 1}]")) + "}", + ["two hundred thousand identical ranges"] = () => "{" + string.Join(",", Enumerable.Repeat("[1,10]", 200_000)) + "}", + ["a million nested brackets"] = () => "{" + new string('[', Size) + "}", + ["a million characters, never closed"] = () => "{" + new string('[', Size), + }; + + public static IEnumerable HostileSetLiterals() => SetLiterals.Keys.Select(name => new object[] { name }); + + private static readonly Dictionary> ArrayLiterals = new() + { + ["two hundred thousand elements"] = () => "{" + string.Join(",", Enumerable.Range(0, 200_000).Select(i => $"e{i}")) + "}", + ["a million escaped quotes in one element"] = () => "{\"" + string.Concat(Enumerable.Repeat("\\\"", Size / 2)) + "\"}", + ["an unterminated quoted element"] = () => "{\"" + new string('a', Size), + ["an unterminated escape"] = () => "{\"" + new string('a', Size) + "\\", + ["a million commas"] = () => "{" + new string(',', Size) + "}", + ["one element of a million characters"] = () => "{" + new string('a', Size) + "}", + }; + + public static IEnumerable HostileArrayLiterals() => ArrayLiterals.Keys.Select(name => new object[] { name }); // ---- bounded time, documented failure modes ------------------------------------------------ [TestMethod, DynamicData(nameof(HostileRangeLiterals)), Timeout(10_000)] - public void RangeParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string name, string input) + public void RangeParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string name) { + var input = RangeLiterals[name](); AssertRejectedOrParsed(() => Int32Range.Parse(input, null)); AssertRejectedOrParsed(() => DecimalRange.Parse(input, null)); AssertRejectedOrParsed(() => DateTimeRange.Parse(input, null)); @@ -65,15 +77,17 @@ public void RangeParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string nam } [TestMethod, DynamicData(nameof(HostileSetLiterals)), Timeout(10_000)] - public void RangeSetParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string name, string input) + public void RangeSetParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string name) { + var input = SetLiterals[name](); AssertRejectedOrParsed(() => RangeSet.Parse(input, null)); Assert.IsFalse(Throws(() => RangeSet.TryParse(input, null, out _)), "RangeSet.TryParse threw on hostile input."); } [TestMethod, DynamicData(nameof(HostileArrayLiterals)), Timeout(10_000)] - public void SetParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string name, string input) + public void SetParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string name) { + var input = ArrayLiterals[name](); AssertRejectedOrParsed(() => StringSet.Parse(input, null)); AssertRejectedOrParsed(() => Int32Set.Parse(input, null)); Assert.IsFalse(Throws(() => StringSet.TryParse(input, null, out _)), "StringSet.TryParse threw on hostile input."); @@ -81,8 +95,9 @@ public void SetParse_HostileInput_IsAcceptedOrRejectedInBoundedTime(string name, } [TestMethod, DynamicData(nameof(HostileRangeLiterals)), Timeout(10_000)] - public void JsonRead_HostileRangeString_IsAcceptedOrRejectedInBoundedTime(string name, string input) + public void JsonRead_HostileRangeString_IsAcceptedOrRejectedInBoundedTime(string name) { + var input = RangeLiterals[name](); var payload = JsonSerializer.Serialize(input); AssertRejectedOrParsed(() => JsonSerializer.Deserialize(payload, Json), typeof(JsonException)); AssertRejectedOrParsed(() => JsonSerializer.Deserialize>(payload, Json), typeof(JsonException)); From c03726951757331cb9a83dad051e00a117742c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gro=C3=9F?= Date: Wed, 11 Nov 2026 06:35:07 +0100 Subject: [PATCH 2/3] build: move main to the .NET 11 GA SDK, the 11.0.0 test packages and Npgsql's provider rc.3 (#532) - global.json names SDK 11.0.100, and release.yml no longer asks setup-dotnet for a preview build. - Npgsql.EntityFrameworkCore.PostgreSQL and its NodaTime plugin move to 11.0.0-rc.3, and Microsoft.EntityFrameworkCore.Design with them: rc.3 pins EF Core to exactly rc.3, so EF Core 11.0.0 waits for Npgsql (#533). - The test packages that don't depend on EF Core move to 11.0.0 (ASP.NET Core OpenApi and TestHost, Microsoft.Extensions.Configuration and its Binder), and MSTest to 4.5.2. - The changelogs and docs/efcore.md name rc.3. Co-Authored-By: Claude Fable 5.2 --- .github/workflows/release.yml | 3 --- CHANGELOG.md | 2 +- docs/efcore.md | 2 +- global.json | 2 +- .../CHANGELOG.md | 2 +- .../CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.csproj | 2 +- src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CHANGELOG.md | 2 +- .../CodoMetis.ValueRanges.EFCore.PostgreSQL.csproj | 2 +- .../CodoMetis.ValueRanges.AspNetCore.Tests.csproj | 6 +++--- .../CodoMetis.ValueRanges.Conventions.Tests.csproj | 6 +++--- ...Core.PostgreSQL.InfinityDisabled.IntegrationTests.csproj | 2 +- ...is.ValueRanges.EFCore.PostgreSQL.IntegrationTests.csproj | 6 +++--- ...etis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests.csproj | 2 +- .../CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests.csproj | 4 ++-- .../CodoMetis.ValueRanges.NodaTime.Tests.csproj | 2 +- .../CodoMetis.ValueRanges.Tests.csproj | 2 +- 16 files changed, 22 insertions(+), 25 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cfbb4da9..36938403 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -197,13 +197,10 @@ jobs: steps: # No checkout here, so no global.json to read: this job only pushes the verified packages # and any SDK of the line can do that. Bump it with global.json when the line moves. - # `dotnet-quality: preview` is there only because 11.0.x has no GA build yet for setup-dotnet to - # resolve. Drop it at .NET 11 GA, in the change that moves global.json to the GA SDK. - name: Setup .NET uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5.4.0 with: dotnet-version: 11.0.x - dotnet-quality: preview # Publishes exactly what was verified — the packages are not rebuilt here. - name: Download packages diff --git a/CHANGELOG.md b/CHANGELOG.md index 2581d599..1a750aa0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ The first preview of the 11 line: the same public API as 10.0.0, on .NET 11. Not ### Breaking -- All four packages target `net11.0` and need the .NET 11 runtime, one target framework per line; the EF Core packages reference EF Core 11 and `Npgsql.EntityFrameworkCore.PostgreSQL` 11 (release candidates while .NET 11 is in preview). PostgreSQL 16 or later, as in 10.x. +- All four packages target `net11.0` and need the .NET 11 runtime, one target framework per line; the EF Core packages reference EF Core 11 and `Npgsql.EntityFrameworkCore.PostgreSQL` 11 (`11.0.0-rc.3`, which pins EF Core to rc.3, until Npgsql ships 11.0.0). PostgreSQL 16 or later, as in 10.x. - Ranges: `RangeAgg()` and `RangeIntersectAgg()` skip a `null` range or set, as `range_agg` and `range_intersect_agg` skip a NULL row. With a `null` after another range, `RangeIntersectAgg()` returned `empty`, or threw after `(,)`, and `RangeAgg()` threw unless an input was `(,)` ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#check-rangeagg-and-rangeintersectagg-over-null-ranges)). - Ranges: `RangeSet.From`, a collection expression and `RangeSet.Create` throw `ArgumentException` for a `null` range, where they built a set holding `null`, whose `IsEmpty()` was `false`. `Union` and `Except` called on a `null` range throw too ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#keep-null-out-of-a-range-set)). - Ranges: a predicate called on a `null` range, or given a `null` range or set, returns `false`, as a query does over a NULL column. `Contains(Empty)`, `IsContainedBy((,))` and `(,).Contains(null)` returned `true`, and `Contains(T)` and a `null` set operand threw ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#check-predicates-over-a-null-range-or-a-null-column)). diff --git a/docs/efcore.md b/docs/efcore.md index 5e2e18fc..4807b68b 100644 --- a/docs/efcore.md +++ b/docs/efcore.md @@ -384,7 +384,7 @@ Good to know: - **Migrations and `EnsureCreated()` both create the key.** It is part of EF Core's own model, so no extra registration is needed. -Everything in this section was run against PostgreSQL 18 with Npgsql 11.0.0-rc.2, over a `DateRange`, +Everything in this section was run against PostgreSQL 18 with Npgsql 11.0.0-rc.3, over a `DateRange`, a `RangeSet`, a `TimeRange` and a `YearMonthRange` column for the key, and a `DateRange` column for the foreign key. diff --git a/global.json b/global.json index 9eb43a98..e26c590b 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "11.0.100-rc.2.26504.105", + "version": "11.0.100", "rollForward": "latestFeature" } } diff --git a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CHANGELOG.md b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CHANGELOG.md index e98a8985..b776b54b 100644 --- a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CHANGELOG.md +++ b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CHANGELOG.md @@ -9,7 +9,7 @@ The first preview of the 11 line: the same public API as 10.0.0, on .NET 11, EF ### Breaking -- Targets `net11.0` and references `Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime` 11 (a release candidate while .NET 11 is in preview). PostgreSQL 16 or later, as in 10.x. +- Targets `net11.0` and references `Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime` 11 (`11.0.0-rc.3` until Npgsql ships 11.0.0). PostgreSQL 16 or later, as in 10.x. - EF Core: `LowerBound()` and `UpperBound()` of a NodaTime range or multirange column, `YearMonthRange` included, are `NULL` in a query for an empty value and on an unbounded side, as in memory. So `== null` selects those rows, where it selected none on a required column, and `?? fallback` returns the fallback, where the row was missing ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#check-bound-comparisons-with-null-in-queries)). - EF Core: a range, multirange or value set predicate over a NULL column is `false`, so its negation keeps the row, as EF Core does for `string` and `string[]`. `!b.Period.Overlaps(p)` dropped the NULL rows, and a projected predicate threw ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#check-predicates-over-a-null-range-or-a-null-column)). - EF Core: `Contains(T)` on a range or multirange is `false` in a query when the element is NULL: a column of a missing child in an outer join, or a nullable column read with `.Value`. Its negation dropped the row, and a projection threw ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#check-predicates-over-a-null-range-or-a-null-column)). diff --git a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.csproj b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.csproj index e70774dc..7152ab86 100644 --- a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.csproj +++ b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.csproj @@ -24,7 +24,7 @@ The full range algebra translates from LINQ to SQL exactly as for the BCL-based - + diff --git a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CHANGELOG.md b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CHANGELOG.md index 53a7551d..922afdce 100644 --- a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CHANGELOG.md +++ b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CHANGELOG.md @@ -9,7 +9,7 @@ The first preview of the 11 line: the same public API as 10.0.0, on .NET 11, EF ### Breaking -- Targets `net11.0` and references EF Core 11 and `Npgsql.EntityFrameworkCore.PostgreSQL` 11 (release candidates while .NET 11 is in preview). PostgreSQL 16 or later, as in 10.x. +- Targets `net11.0` and references EF Core 11 and `Npgsql.EntityFrameworkCore.PostgreSQL` 11 (`11.0.0-rc.3`, which pins EF Core to rc.3, until Npgsql ships 11.0.0). PostgreSQL 16 or later, as in 10.x. - EF Core: `EFCore.ComplexIndexes.PostgreSQL` 5.x stays on EF Core 10 and can't be installed beside the 11 packages. Its EF Core 11 successor, `CodoMetis.EFCore.SchemaKit.PostgreSQL`, isn't on NuGet yet ([CaffeinatedCoder/EFCore.ComplexIndexes#38](https://github.com/CaffeinatedCoder/EFCore.ComplexIndexes/issues/38)). For exclusion constraints until then, stay on 10.x or add the constraint with explicit SQL. Temporal keys are Npgsql's own on EF Core 11 ([Exclusion constraints](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/efcore.md#reject-overlapping-rows-with-an-exclusion-constraint)). - EF Core: `LowerBound()` and `UpperBound()` in a query are `NULL` for an empty range or set and on an unbounded side, as in memory. So `== null` selects those rows, where it selected none on a required column, and `?? fallback` returns the fallback, where the row was missing ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#check-bound-comparisons-with-null-in-queries)). - EF Core: a range, multirange or value set predicate over a NULL column is `false`, so its negation keeps the row, as EF Core does for `string` and `string[]`. `!b.Period.Overlaps(p)` dropped the NULL rows, and a projected predicate threw ([Migration](https://github.com/CaffeinatedCoder/CodoMetis.ValueRanges/blob/main/docs/migration.md#check-predicates-over-a-null-range-or-a-null-column)). diff --git a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CodoMetis.ValueRanges.EFCore.PostgreSQL.csproj b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CodoMetis.ValueRanges.EFCore.PostgreSQL.csproj index a8e8eb3c..b92789a7 100644 --- a/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CodoMetis.ValueRanges.EFCore.PostgreSQL.csproj +++ b/src/CodoMetis.ValueRanges.EFCore.PostgreSQL/CodoMetis.ValueRanges.EFCore.PostgreSQL.csproj @@ -30,7 +30,7 @@ v6 also maps the value set types to native PostgreSQL arrays (StringSet to text[ - + diff --git a/test/CodoMetis.ValueRanges.AspNetCore.Tests/CodoMetis.ValueRanges.AspNetCore.Tests.csproj b/test/CodoMetis.ValueRanges.AspNetCore.Tests/CodoMetis.ValueRanges.AspNetCore.Tests.csproj index 08fbc3e1..2c293d68 100644 --- a/test/CodoMetis.ValueRanges.AspNetCore.Tests/CodoMetis.ValueRanges.AspNetCore.Tests.csproj +++ b/test/CodoMetis.ValueRanges.AspNetCore.Tests/CodoMetis.ValueRanges.AspNetCore.Tests.csproj @@ -13,9 +13,9 @@ - - - + + + diff --git a/test/CodoMetis.ValueRanges.Conventions.Tests/CodoMetis.ValueRanges.Conventions.Tests.csproj b/test/CodoMetis.ValueRanges.Conventions.Tests/CodoMetis.ValueRanges.Conventions.Tests.csproj index e33bdb2b..bc400f85 100644 --- a/test/CodoMetis.ValueRanges.Conventions.Tests/CodoMetis.ValueRanges.Conventions.Tests.csproj +++ b/test/CodoMetis.ValueRanges.Conventions.Tests/CodoMetis.ValueRanges.Conventions.Tests.csproj @@ -11,9 +11,9 @@ - - - + + + diff --git a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests.csproj b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests.csproj index d02d4254..88ff4fc3 100644 --- a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests.csproj +++ b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.InfinityDisabled.IntegrationTests.csproj @@ -20,7 +20,7 @@ - + diff --git a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests.csproj b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests.csproj index cf46bb80..f6541919 100644 --- a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests.csproj +++ b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests.csproj @@ -9,7 +9,7 @@ - + - + @@ -82,7 +82,7 @@ --> - + diff --git a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests.csproj b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests.csproj index a426f8cb..84ef8379 100644 --- a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests.csproj +++ b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests.csproj b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests.csproj index 0457380f..9a19a31d 100644 --- a/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests.csproj +++ b/test/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests.csproj @@ -9,12 +9,12 @@ - + - + diff --git a/test/CodoMetis.ValueRanges.NodaTime.Tests/CodoMetis.ValueRanges.NodaTime.Tests.csproj b/test/CodoMetis.ValueRanges.NodaTime.Tests/CodoMetis.ValueRanges.NodaTime.Tests.csproj index d64b5e8a..913c798f 100644 --- a/test/CodoMetis.ValueRanges.NodaTime.Tests/CodoMetis.ValueRanges.NodaTime.Tests.csproj +++ b/test/CodoMetis.ValueRanges.NodaTime.Tests/CodoMetis.ValueRanges.NodaTime.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/CodoMetis.ValueRanges.Tests/CodoMetis.ValueRanges.Tests.csproj b/test/CodoMetis.ValueRanges.Tests/CodoMetis.ValueRanges.Tests.csproj index 4dc71a0d..10e6f653 100644 --- a/test/CodoMetis.ValueRanges.Tests/CodoMetis.ValueRanges.Tests.csproj +++ b/test/CodoMetis.ValueRanges.Tests/CodoMetis.ValueRanges.Tests.csproj @@ -9,7 +9,7 @@ - + From cbfa4b1809d00de3b4ed2d5599f920243cc92a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gro=C3=9F?= Date: Wed, 11 Nov 2026 06:37:38 +0100 Subject: [PATCH 3/3] chore: record that the Native AOT trap of dotnet/runtime#136073 is still in .NET 11.0.0 (#532) The minimal repro from the upstream issue, published with Native AOT on SDK 11.0.100, ends with SIGTRAP (exit 133) when the default IFormattable.ToString may be inlined, and prints its two lines with NoInlining. The fix's backport to release/11.0 (dotnet/runtime#136148) is approved for servicing and not merged, so the NoInlining attribute and the per-family overrides stay. Co-Authored-By: Claude Fable 5.2 --- src/CodoMetis.ValueRanges/Core/IValueSetFactory.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CodoMetis.ValueRanges/Core/IValueSetFactory.cs b/src/CodoMetis.ValueRanges/Core/IValueSetFactory.cs index de046d0e..b819ab2f 100644 --- a/src/CodoMetis.ValueRanges/Core/IValueSetFactory.cs +++ b/src/CodoMetis.ValueRanges/Core/IValueSetFactory.cs @@ -138,7 +138,8 @@ static bool ISpanParsable.TryParse(ReadOnlySpan s, IFormatProvider? // NoInlining: ILCompiler 11 inlines this default into the instantiating thunk of the shared-generic // interface, where the receiver is typed as the thunk's module type, so the cast of `this` fails and // the thunk is compiled to a trap (SIGTRAP, exit 133) in a net11.0 Native AOT consumer — measured on - // 11.0.100-rc.2.26504.105 (#291, #299, #315, dotnet/runtime#136073). Every set family also overrides + // 11.0.100-rc.2.26504.105, and again on 11.0.100: the fix is in dotnet/runtime's main, and its backport + // (dotnet/runtime#136148) is not in 11.0.0 (#291, #299, #315, #532, dotnet/runtime#136073). Every set family also overrides // IFormattable.ToString itself, which is what keeps the trap out of a compiled consumer today; the // attribute keeps a family that forgets the override from trapping. The range default (IRangeFactory) did not trap in // the same publish, which prints range text through it, so it is left alone.