Round 4 review found two gaps in the gwg2 runtime pin. The carrier list
(png, jpeg, webp) was hand-written and left out BMP, whose 3.1.12
decoder also constructs an IccProfile (BmpDecoderCore::ReadInfoHeader)
and which remote-URL and on-disk graphics can reach. And the record
said every hostile-ICC case asserts the profile is still attached,
while the WatermarkElement case asserts only allocation (its images are
private).
- IccCarriers is now bmp, jpeg, png, webp, with a BmpEncoder arm.
- Icc_Carriers_Are_Every_Configured_Format_That_Round_Trips_A_Profile
round-trips the hostile profile through each format of
ImageSharpDecoding.Configuration via its default encoder and requires
the formats that come back carrying a profile to equal IccCarriers.
Witnessed red by dropping "bmp" from the list.
- A Cecil scan of the 3.1.12 package (2026-10-28) lists the decoders that
construct an IccProfile as BMP, JPEG, PNG, WebP and TIFF, so the
round trip's blind spot (a decoder reading a profile its encoder never
writes) is empty today; the record says so, dated.
- The record and the element test's comment now say only the validator
cases assert attachment; the element case shares their fixture.
Measured: product path 38-94 KiB, element 368-834 KiB, Entries control
about 129,545 KiB for all four carriers.
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: f9ce6bc6-5b36-491a-8d72-89c1f70dd3e1
Round-3 review: the record said every bound is enforced over compiled code,
but half of the gwg2 (ICC CLUT) bound is ImageSharp 3.1.12's own runtime
behaviour, which the IL scan cannot see.
A 208-byte ICC profile declaring an mft2 CLUT (3 in, 15 out, 255 grid
points), carried in PNG, JPEG and WebP, now goes through
RemoteImageValidator.DecodeAndValidate + CloneFrame/Resize/CloneAs and
through a real remote WatermarkElement. Each case asserts the profile is
still attached and fails above 16 MiB allocated. The positive control reads
Entries on the same profile and must allocate over 64 MiB.
Measured 2026-10-28 on 3.1.12: the product paths allocate 38-94 KiB and
the element 322-390 KiB; Entries allocates about 129,550 KiB. Mutation
witnesses: a try/catch read of IccProfile.Entries injected after the
validator's post-decode check reddens all 6 product-path cases on the
allocation assertion. The same read after ImageElementBase's per-frame
Resize reddens the 3 element cases. Both were restored from git.
The record's gwg2 row and 'What holds the bounds' now name the two halves
and which test holds each. docs/testing.md names the ICC cases.
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: f9ce6bc6-5b36-491a-8d72-89c1f70dd3e1
security.imagesharp-3x-tiff-decoder-disabled now says the bounds are
enforced by ImageSharpSurfaceTests rather than by its own prose. The
"Load pass is masked" claim is dropped from the record and from the two
code comments that repeated it: with the architecture pin, reverting the
Load pass's options alone now reddens
Only_ImageSharpDecoding_constructs_DecoderOptions (witnessed
2026-10-27), so the claim had become false. The residual it cannot see,
an extension-dispatched Save(path), is named.
Renovate: a packageRule holds SixLabors.ImageSharp on 3.1.x. The
existing "range pins are respected" sentence in ci-cd.md and the EF
group's description were wrong: Dependency Dashboard #22 offers EF Core
v10 and MediatR 14.2.0 over their range pins, so a range does not hold
Renovate. Whether the rule holds the OSV security PR (#923) cannot be
measured before merge, and the record says so.
guard-inventory.md's hand-written C# guard list gains the new fixture
and its two Architecture.Tests siblings, and stops quoting a count.
This branch also edits the rationale prose of
ffmpeg.remote-image-fetcher-bounded (commit 73045865f: the MaxFrames
measurement is dated to 3.1.12 and TIFF is no longer in play), which
the decisions lifecycle check requires this trailer for.
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: f9ce6bc6-5b36-491a-8d72-89c1f70dd3e1
New record security.imagesharp-3x-tiff-decoder-disabled: the license-key
build gate in every patched release (measured on 3.2.0 and 4.1.3 Release
builds), the per-advisory reachability table, the masked Load-pass clause
(measured: reverting it alone leaves the suite green), that dotnet list
--vulnerable ignores NuGetAuditSuppress (measured), and the revisit trigger.
ci-cd.md Dependency management records the Pkcs direct pin, the rejected
central transitive pin (NU1109), and that the weekly scan is red by design
on ImageSharp until then. The #511 record's MaxFrames measurement is dated
to 3.1.12 and no longer lists TIFF as in play.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: f9ce6bc6-5b36-491a-8d72-89c1f70dd3e1
The Pkcs 9.0.4 that EFCore.BulkExtensions' Oracle/SqlServer providers pull
transitively carries GHSA-846f-f764-76mx (High) and GHSA-2fmv-rv2c-59x7.
It is overridden by a direct reference in ErsatzTV.Infrastructure, the
existing pattern (Microsoft.OpenApi, SQLitePCLRaw). The central transitive
pin the issue suggested was measured and rejected: enabling
CentralPackageTransitivePinningEnabled fails restore with NU1109 in every
project, because Microsoft.Extensions.DependencyModel is exact-pinned [8.0.2]
below the >= 9.0.x EF Core requires.
ImageSharp stays on 3.1.12. Every patched release (3.2.0, 4.1.2, 4.1.3)
ships a build-time Six Labors license check that fails a Release build
without a key (measured: dotnet build -c Release errors 'No Six Labors
license found'), and CI and the image build Release. Of the six 3.1.12
advisories now listed, the two DECODER ones are TIFF; every ImageSharp
decode now goes through a configuration that cannot detect TIFF. The rest
are an encoder, a processor and an accessor ErsatzTV never calls.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: f9ce6bc6-5b36-491a-8d72-89c1f70dd3e1