Updating fork to latest v2.x of upstream#6
Merged
Conversation
BrennanConroy
commented
Jun 9, 2026
Member
Refreshing updates
Add nullable ref annotations
Add more nullable ref annotations
This one may be a bit sloppy, as it is deep and complex Reflection code, and I don't have time to re-grok everything inside it. But if there are any inaccuracies, they are internal APIs, so they shouldn't adversely impact users.
Last of the nullable ref annotations
We've already done this for the 2.5 version, but this backports it for the 2.4 version since the Azure Pipelines unity agent is gone.
Switch from Azure Pipelines to GitHub Actions for unity build
Merge master to develop
…nerics Fixed issue with generics formatters generation
Also update the .NET SDK to 7.0.101
.NET Standard 2.0 is still relevant because it's the last TFM that works on all .NET runtimes. But it's also very old, depriving the developer of the nullable ref annotations that are in later versions of .NET that can help reduce bugs. There are also newer APIs that can be *automatically* consumed by the compiler based on newer TFMs even without using `#if` in your code that can improve runtime performance of the code.
Drop .NET Core 3.1 target
…unds Drop obsolete WPF workarounds
Just use `latest` so it'll be whatever the SDK version permits. Dropping the property altogether would use the formally recommended version for the TFM, which is less desirable.
Bumps [Microsoft.CodeCoverage](https://github.com/microsoft/vstest) from 17.5.0-preview-20221201-06 to 17.5.0-release-20221220-01. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/commits) --- updated-dependencies: - dependency-name: Microsoft.CodeCoverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…date-v2.x-minimal Update v2.x to build again
…fer-type-deserialization Add more types to the default disallow list of named types to be deserialized
The LZ4 block decoder accepted only the destination length and advanced through the compressed input without knowing where the source buffer ended. Malformed compressed payloads could therefore drive unchecked native reads before the existing post-decode length check ran. Pass the compressed input length into the 32-bit and 64-bit decoders and reject malformed blocks before token, literal, offset, and match-length reads would move past the source buffer. Add a regression test that verifies malformed LZ4 data fails as a normal serialization exception.
InterfaceLookupFormatter created its intermediate Dictionary with the default comparer, so ILookup<TKey,TElement> deserialization did not honor MessagePackSecurity.UntrustedData hash-collision resistance. Pass the security-provided equality comparer into the intermediate dictionary and add regression coverage that verifies colliding long keys use the hardened comparer.
Multidimensional array deserialization trusted dimension values and allocated arrays before confirming that the flattened element count matched the serialized element array header. This could let malformed data request disproportionate allocations before validation. Validate non-negative dimensions and checked flattened lengths for 2D, 3D, and 4D array formatters before allocation, and add regression coverage for mismatched element counts under untrusted data options.
ConvertFromJson now applies the configured MessagePackSecurity maximum object graph depth while translating nested JSON objects and arrays, preventing deeply nested input from recursing until stack exhaustion. Added a bounded regression test that verifies over-depth JSON is rejected for both compressed and uncompressed conversion paths.
UnsafeBlitFormatter trusted the nested byte count from extension payloads when allocating arrays, even though the surrounding extension length had already bounded the body. Malformed inputs could request allocations that were not supported by the declared extension data. Parse the extension body through a bounded reader and reject negative, unaligned, or mismatched byte counts before allocating. Add a regression test for the malformed length case.
DynamicUnionResolver emitted deserializers did not count the union formatter frame against MessagePackSecurity's object graph depth budget. That left recursive union values and skipped unknown union payloads less constrained than source-generated unions and dynamic object formatters. Emit DepthStep after nil handling and decrement reader.Depth before returning, matching the existing dynamic object formatter pattern. Add a regression test proving unknown union payloads respect the depth limit without including exploit payload details.
ConvertToJson recursively expands typeless extension values while composing JSON, but that path was not counted against MessagePackSecurity.MaximumObjectGraphDepth. Deeply nested typeless values could therefore bypass UntrustedData depth checks and exhaust the call stack. Wrap typeless extension JSON processing in DepthStep/decrement accounting and add regression coverage that expects the configured depth limit to be enforced.
TinyJsonReader previously skipped JSON separators with a recursive ReadNextToken call, so a long separator sequence supplied to ConvertFromJson could consume one stack frame per separator and terminate the process. Change separator skipping to stay within the tokenizer loop instead, preserving the existing tokenization behavior without stack growth. Add regression coverage that converts a long separator-prefixed JSON value successfully.
Promote map entry count multiplication to long when validating the minimum encoded payload length and when skipping map contents. This keeps oversized malformed map headers on the insufficient-buffer path instead of relying on Int32 arithmetic behavior. Add regression coverage for oversized map headers in ReadMapHeader and Skip.
ExpandoObject map materialization inserts each member through ExpandoObject, whose member table grows with linear scans and array copies. Under the untrusted-data resolver preset, very large maps could consume disproportionate CPU before application code sees the result. Reject oversized ExpandoObject maps when hash-collision hardening is active, covering both direct ExpandoObject deserialization and nested maps produced by ExpandoObjectResolver. Add focused regression coverage for both paths.
MessagePackInputFormatter handles HTTP request bodies, but its default/null options path fell back to MessagePackSerializerOptions.Standard and therefore TrustedData. That left hash-based model binding without the untrusted-data collision-resistance defaults expected at this trust boundary. Default null input-formatter options to Standard.WithSecurity(UntrustedData), while preserving caller-supplied options. Add a regression test that verifies the parameterless formatter deserializes dictionary request bodies with the collision-resistant comparer.
The `MessagePackReader` has no concept of a depth limit, and it implemented its `Skip()` method recursively which can easily blow the stack for deeply nested msgpack structures. Rather than introduce a new API with an adjustable depth limit, set to a 'secure' but otherwise arbitrary default, we can make `Skip()` iterate instead of recurse in order to avoid ever crashing.
Typeless deserialization previously validated only the outer wire-supplied type before resolving a formatter. Container types could therefore hide a disallowed element or generic argument from the mitigation and from custom option overrides. Validate element and constructed generic argument types before formatter resolution, and add regression coverage for nested typeless disallowed types.
Validate declared LZ4 decompressed block sizes against the compressed block size before requesting an output buffer. This rejects unreasonable Lz4Block and Lz4BlockArray declarations before allocation while preserving normal compressed payload handling.
Before this change, the length of the source span would dictate how large the destination span became and how far we advanced the writer, without any regard to how many bytes would actually be copied into that buffer.
Thanks to @svenclaesson for calling these types out as valuable to block by default.
…d-more-disallowed-types-v2.x Add several known unsafe 'gadgets' to the disallow list
wtgodbe
approved these changes
Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.