Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
2853 commits
Select commit Hold shift + click to select a range
d4bc21e
Merge pull request #2803 from microsoft/release-please--branches--mai…
baywet Mar 31, 2026
c4bb175
Bump Microsoft.NET.Test.Sdk from 18.3.0 to 18.4.0
dependabot[bot] Apr 7, 2026
495a809
Merge pull request #2807 from microsoft/dependabot/nuget/test/Microso…
github-actions[bot] Apr 8, 2026
da5439c
ci: updates outdated parameter
baywet Apr 13, 2026
4b5468d
Merge pull request #2808 from microsoft/ci/outdated-parameter
baywet Apr 13, 2026
8c22ab2
fix(hidi): update Microsoft.OpenApi.OData to 3.2.1
gavinbarron Apr 14, 2026
b0a68fb
Merge pull request #2814 from microsoft/fix/update-odata-v3
baywet Apr 14, 2026
7c5376f
chore(main): release 3.5.2 (#2818)
release-please-token-provider[bot] Apr 14, 2026
382ed09
chore(deps): bump dotnet-sdk from 8.0.419 to 8.0.420
dependabot[bot] Apr 14, 2026
dbf5540
Bump Microsoft.SourceLink.GitHub from 10.0.201 to 10.0.202
dependabot[bot] Apr 14, 2026
0648cd4
Merge pull request #2822 from microsoft/dependabot/nuget/Microsoft.So…
github-actions[bot] Apr 15, 2026
1b0c11d
Merge pull request #2820 from microsoft/dependabot/dotnet_sdk/dotnet-…
github-actions[bot] Apr 15, 2026
aee44be
Bump the microsoftextensions group with 6 updates
dependabot[bot] Apr 15, 2026
cf2aa71
build(tests): bump system.text.json to 10.0.6
Copilot Apr 15, 2026
d3c4dc2
chore: trigger CI
baywet Apr 15, 2026
101979e
Merge pull request #2821 from microsoft/dependabot/nuget/performance/…
github-actions[bot] Apr 15, 2026
b6ed9eb
ci: upgrades repository to net10
baywet Apr 16, 2026
4bdc8b1
Merge pull request #2825 from microsoft/ci/upgrade-net-10
baywet Apr 17, 2026
97d3772
Bump the coverlet group with 2 updates
dependabot[bot] Apr 17, 2026
60f8f74
Merge pull request #2829 from microsoft/dependabot/nuget/test/Microso…
baywet Apr 18, 2026
4071fb3
chore(deps): bump dependabot/fetch-metadata from 3.0.0 to 3.1.0
dependabot[bot] Apr 20, 2026
69a464b
Merge pull request #2831 from microsoft/dependabot/github_actions/dep…
github-actions[bot] Apr 21, 2026
3f82eb9
ci: skip release-please job when secret is not defined (#2830)
baywet Apr 21, 2026
572b0b6
chore(deps): bump dotnet-sdk from 10.0.202 to 10.0.203
dependabot[bot] Apr 21, 2026
9991c71
Bump the microsoftextensions group with 6 updates
dependabot[bot] Apr 21, 2026
43895ae
Bump Microsoft.SourceLink.GitHub from 10.0.202 to 10.0.203
dependabot[bot] Apr 21, 2026
145bf44
Merge pull request #2834 from microsoft/dependabot/nuget/Microsoft.So…
github-actions[bot] Apr 21, 2026
4c78e8f
Merge pull request #2832 from microsoft/dependabot/dotnet_sdk/dotnet-…
github-actions[bot] Apr 21, 2026
baf0e74
Merge pull request #2833 from microsoft/dependabot/nuget/performance/…
github-actions[bot] Apr 21, 2026
cb50481
chore(deps): bump googleapis/release-please-action from 4 to 5
dependabot[bot] Apr 22, 2026
78e17ca
Merge pull request #2836 from microsoft/dependabot/github_actions/goo…
baywet Apr 23, 2026
fe0b50a
fix: null reference exception for boolean component schemas
baywet Apr 27, 2026
b6c1fe8
test(schema): validate empty schema serialization across all OpenAPI …
baywet Apr 27, 2026
b9b9b75
test(schema): add deserialization tests for empty and boolean schemas
baywet Apr 27, 2026
7d43b15
test(schema): validate false schema deserializes to not with empty ob…
baywet Apr 27, 2026
15c1305
tests: pass serialization format to disambiguate
baywet Apr 27, 2026
05b44be
fix(schema): support boolean schemas in deserializer for OpenAPI 3.1/3.2
baywet Apr 27, 2026
509f332
docs(schema): document boolean schema serialization and deserialization
baywet Apr 27, 2026
7316e3f
perf(schema): optimize boolean schema deserialization
baywet Apr 27, 2026
a54c0fd
test(schema): rename deserialization test for clarity
baywet Apr 27, 2026
f97f91a
Merge pull request #2839 from microsoft/fix/true-schema-component
baywet Apr 27, 2026
8dce238
chore(main): release 3.5.3
release-please-token-provider[bot] Apr 27, 2026
776af11
Merge pull request #2842 from microsoft/release-please--branches--mai…
baywet Apr 27, 2026
561e33c
Bump Microsoft.NET.Test.Sdk from 18.4.0 to 18.5.1
dependabot[bot] Apr 28, 2026
54713e8
Merge pull request #2843 from microsoft/dependabot/nuget/test/Microso…
github-actions[bot] Apr 28, 2026
0fcdf65
chore(deps): bump dotnet-sdk from 10.0.203 to 10.0.300
dependabot[bot] May 13, 2026
0bbc23e
Merge pull request #2846 from microsoft/dependabot/dotnet_sdk/dotnet-…
github-actions[bot] May 13, 2026
d69ed7d
Bump Microsoft.Extensions.DependencyInjection and 5 others
dependabot[bot] May 13, 2026
b0ed823
Merge pull request #2847 from microsoft/dependabot/nuget/performance/…
github-actions[bot] May 13, 2026
2c41ac9
Updated for https://dev.azure.com/microsoftgraph/0985d294-5762-4bc2-a…
microsoft-github-policy-service[bot] Jan 28, 2025
634aa2f
Updated for https://dev.azure.com/microsoftgraph/0985d294-5762-4bc2-a…
microsoft-github-policy-service[bot] Apr 28, 2025
a923502
Updated for https://dev.azure.com/microsoftgraph/0985d294-5762-4bc2-a…
microsoft-github-policy-service[bot] Jun 3, 2025
f187c94
Updated for https://dev.azure.com/microsoftgraph/0985d294-5762-4bc2-a…
microsoft-github-policy-service[bot] May 13, 2026
c8c3fe5
Merge pull request #2850 from microsoft/users/merlinbot/1es-pt-auto-b…
baywet May 14, 2026
93448a9
Bump the coverlet group with 2 updates
dependabot[bot] May 19, 2026
575244b
Merge pull request #2851 from microsoft/dependabot/nuget/test/Microso…
github-actions[bot] May 19, 2026
eb8a215
Bump Microsoft.SourceLink.GitHub from 10.0.203 to 10.0.300
dependabot[bot] May 19, 2026
32905c7
Merge pull request #2848 from microsoft/dependabot/nuget/Microsoft.So…
github-actions[bot] May 19, 2026
b75709a
Initial plan
Copilot May 26, 2026
94b606d
fix(reader): preserve nullable Null flag when type appears after null…
Copilot May 26, 2026
91a989f
fix(library): handle circular schema references
baywet May 26, 2026
de72b1d
test(reader): add nullable-before-type tests for V3.0 and V3.2
Copilot May 26, 2026
18637f9
chore(benchmark): refresh benchmark reports
Copilot May 26, 2026
b3cd42b
Merge pull request #2854 from microsoft/security/ref-loop
baywet May 26, 2026
26071cb
chore(main): release 3.5.4
release-please-token-provider[bot] May 26, 2026
0f8bffa
Merge pull request #2857 from microsoft/release-please--branches--mai…
baywet May 26, 2026
2b9d7f4
Merge pull request #2853 from microsoft/copilot/fix-openapi-deseriali…
baywet May 26, 2026
d298917
Bump Microsoft.NET.Test.Sdk from 18.5.1 to 18.6.0
dependabot[bot] May 27, 2026
4d6bd48
Merge pull request #2862 from microsoft/dependabot/nuget/test/Microso…
github-actions[bot] May 27, 2026
2368305
ci: integrate GitHub code coverage uploads
baywet May 28, 2026
ea95d88
Merge pull request #2863 from microsoft/ci/coverage-information
baywet May 28, 2026
92e9505
chore(main): release 3.5.5
release-please-token-provider[bot] May 28, 2026
75f3144
ci: skip coverage uploads off default branch
baywet May 28, 2026
d40952a
Merge pull request #2865 from microsoft/ci/coverage-information-uploa…
baywet May 28, 2026
157e72b
feat(reader): remove ParseNode infrastructure
baywet May 25, 2026
83ea307
chore(reader): prune unused JsonNode helpers
baywet May 26, 2026
582563f
chore(reader): remove CreateAny helper
baywet May 26, 2026
78b6d60
chore(benchmark): update performance reports
baywet May 26, 2026
0fec6aa
chore: remove unused parameters
baywet May 29, 2026
f3f7adb
chore: renames files to match new class name
baywet May 29, 2026
8cafa7b
chore: renames files to match new class name
baywet May 29, 2026
2d0af62
Merge pull request #2859 from microsoft/release-please--branches--mai…
baywet May 29, 2026
b509007
chore(reader): normalize JsonNode variable casing
baywet May 29, 2026
929b8e4
chore(reader): discard unused callback parameters
baywet May 29, 2026
8ae59af
chore(reader): normalize JsonNode local casing
baywet May 29, 2026
d1d0fcb
chore: reverts hallucinations
baywet May 29, 2026
54cf5dc
chore: moves using after the copyright
baywet May 29, 2026
9b4f45b
Merge pull request #2852 from microsoft/chore/refactor-no-parse-node
baywet Jun 1, 2026
5c2ddda
chore(main): release 3.6.0
release-please-token-provider[bot] Jun 1, 2026
25fb628
test(coverage): exclude test assembly from merged reports
baywet Jun 1, 2026
b8ad022
test(coverage): add reference and reader edge tests
baywet Jun 1, 2026
b65bbe5
test(coverage): add reader and walker edge tests
baywet Jun 1, 2026
a9bc177
Merge pull request #2869 from microsoft/release-please--branches--mai…
baywet Jun 1, 2026
21488c6
Merge pull request #2870 from microsoft/chore/additional-coverage
baywet Jun 3, 2026
7a443c2
fix(library): avoid false circular refs for external schema re-exports
baywet Jun 9, 2026
82f84e0
feat(library): add missing json schema properties
baywet Jun 9, 2026
6e22ec6
fix(library): use version-specific schema keyword callbacks
baywet Jun 9, 2026
c62769a
docs(library): add json schema spec links
baywet Jun 9, 2026
eb1891a
fix(library): use x-jsonschema schema extensions
baywet Jun 9, 2026
cf54bb3
fix(library): remove unshipped schema extension fallback
baywet Jun 9, 2026
1a974f8
feat: add contains/minContains/maxContains members
Poltuu Jun 9, 2026
9672f95
chore(library): use constants for new schema keywords
baywet Jun 9, 2026
68f9bd2
chore(benchmark): refresh performance reports
baywet Jun 9, 2026
4907d1c
fix(library): always copy unevaluated properties
baywet Jun 9, 2026
9cf0916
test(library): consolidate unevaluated properties extension tests
baywet Jun 9, 2026
9b1aed6
Merge pull request #2880 from microsoft/feat/missing-json-schema-prop…
baywet Jun 9, 2026
b635242
Merge pull request #2873 from microsoft/fix/invalid-circular-ref
baywet Jun 9, 2026
5c152ae
Merge branch 'main' into Poltuu/main
baywet Jun 9, 2026
8990afa
chore(library): use schema contains constants in readers
baywet Jun 9, 2026
fe5ecbb
chore(library): serialize contains keywords as v3 extensions
baywet Jun 9, 2026
7927d30
chore(benchmark): refresh performance reports
baywet Jun 9, 2026
24c2a0b
chore(library): add v3 contains extension deserialization
baywet Jun 9, 2026
78475e3
Merge pull request #2876 from Poltuu/main
baywet Jun 9, 2026
3c058fd
chore(deps): bump dotnet-sdk from 10.0.300 to 10.0.301
dependabot[bot] Jun 9, 2026
b1104e2
Bump the microsoftextensions group with 6 updates
dependabot[bot] Jun 9, 2026
0138361
Merge pull request #2885 from microsoft/dependabot/dotnet_sdk/dotnet-…
github-actions[bot] Jun 9, 2026
37991b4
Merge pull request #2886 from microsoft/dependabot/nuget/performance/…
github-actions[bot] Jun 9, 2026
bab6dc1
chore: promote shipped APIs
github-actions[bot] Jun 10, 2026
b4ab94c
Merge pull request #2888 from microsoft/promote-shipped-apis-main
baywet Jun 10, 2026
d186b42
chore(main): release 3.7.0
release-please-token-provider[bot] Jun 10, 2026
39d3cc2
Merge pull request #2882 from microsoft/release-please--branches--mai…
baywet Jun 10, 2026
24469a7
docs: fixes comment for Responses property
baywet Jun 15, 2026
68e16e8
Merge pull request #2891 from microsoft/baywet-patch-1
baywet Jun 16, 2026
4d8429c
chore(deps): bump actions/checkout from 6 to 7
dependabot[bot] Jun 18, 2026
7345caa
Merge pull request #2894 from microsoft/dependabot/github_actions/act…
baywet Jun 18, 2026
0e6851e
chore(deps): bump actions/cache from 5 to 6
dependabot[bot] Jun 23, 2026
5f2a32d
Bump Microsoft.NET.Test.Sdk from 18.6.0 to 18.7.0
dependabot[bot] Jun 23, 2026
607f2a2
Merge pull request #2899 from microsoft/dependabot/nuget/test/Microso…
github-actions[bot] Jun 24, 2026
4ced0e9
Merge pull request #2898 from microsoft/dependabot/github_actions/act…
baywet Jun 24, 2026
d703a5b
Bump Microsoft.VisualStudio.Threading.Analyzers from 17.14.15 to 18.7.23
dependabot[bot] Jun 22, 2026
6e675d9
fix: use async method for crypto flush
baywet Jun 26, 2026
8d30c08
Merge pull request #2897 from microsoft/dependabot/nuget/src/Microsof…
baywet Jun 26, 2026
08160c8
fix: preserve JSON Schema 2020-12 keyword siblings on $ref schemas fo…
aqeelat Jun 26, 2026
a805070
chore: promote shipped APIs
github-actions[bot] Jun 26, 2026
26c2358
Merge pull request #2904 from microsoft/promote-shipped-apis-main
baywet Jun 26, 2026
66a9d04
feat(library): support schema keywords on references
baywet Jun 26, 2026
9d71746
chore(benchmark): update performance reports
baywet Jun 26, 2026
c938727
fix(library): keep v3 schema references ref-only
baywet Jun 26, 2026
e50649c
chore(benchmark): update performance reports
baywet Jun 26, 2026
6043551
chore: refactor to avoid duplicate deserialization logic
baywet Jun 26, 2026
434b2f8
Merge pull request #2906 from microsoft/feat/additional-siblings
baywet Jun 26, 2026
625d780
chore: promote shipped APIs
github-actions[bot] Jun 26, 2026
2bad4da
Merge pull request #2910 from microsoft/promote-shipped-apis-main
baywet Jun 26, 2026
3764142
fix: Don't silently skip null assignment to OpenApiDocument.Tags
Youssef1313 Jun 29, 2026
2f8b3d2
feat: add JsonConverter for OpenApiSchema System.Text.Json serializat…
Mahdigln Jul 2, 2026
2d23192
chore: promote shipped APIs (#2923)
release-please-token-provider[bot] Jul 2, 2026
ce09f41
Bump Microsoft.CodeAnalysis.PublicApiAnalyzers from 3.3.4 to 5.6.0 (#…
dependabot[bot] Jul 2, 2026
beb68f5
fix: handling of nullable enums for 3.0 (#2920)
Youssef1313 Jul 3, 2026
bac87f2
chore(main): release 3.8.0 (#2902)
release-please-token-provider[bot] Jul 6, 2026
1591007
feat: adds support for anchor and id external resolution
baywet Jul 7, 2026
fe4a25f
fix: default mapping is not being serialized with the correct shape
baywet Jul 8, 2026
6347c7a
tests: adds tests for discriminator mappings formatting
baywet Jul 8, 2026
7fcd1fb
chore: null forgiving because of lack of annotations for netstandard2.0
baywet Jul 8, 2026
2a6ebec
chore: linting
baywet Jul 8, 2026
1aeb913
Merge pull request #2931 from microsoft/fix/default-mapping-serializa…
baywet Jul 9, 2026
0ace243
fix: handle nullability more accurately during serialization for 3.0/…
Youssef1313 Jul 13, 2026
eacc2fc
feat(schema): resolve bare $dynamicRef via $dynamicAnchor index (#2913)
aqeelat Jul 14, 2026
2b8fe22
chore: promote shipped APIs (#2940)
release-please-token-provider[bot] Jul 14, 2026
0f19a01
tests: renames typo in filename
baywet Jul 14, 2026
07b525f
fix: differentiate unset value from null value in OpenApiSchema.Const…
Youssef1313 Jul 14, 2026
4076513
ci: adds a dev container configuration
baywet Jul 14, 2026
bc93efe
fix: adds explicit error message for invalid json pointers
baywet Jul 14, 2026
7be32b9
chore: linting
baywet Jul 14, 2026
02b5266
chore: fixes implementation for pointer validation
baywet Jul 14, 2026
527a2cf
chore: reverts range index unavailable on netstandard2.0
baywet Jul 14, 2026
dd0737f
docs: adds a mention of the shallow copy
baywet Jul 14, 2026
be6de4a
Merge pull request #2942 from microsoft/tests/file-name
baywet Jul 14, 2026
1d7aa76
Merge pull request #2944 from microsoft/ci/dev-container
baywet Jul 14, 2026
6cd35dc
Bump Microsoft.NET.Test.Sdk from 18.7.0 to 18.8.1
dependabot[bot] Jul 14, 2026
1872c1b
Bump Microsoft.OData.Edm from 8.4.3 to 8.4.4
dependabot[bot] Jul 14, 2026
8783e82
Merge pull request #2950 from microsoft/dependabot/nuget/src/Microsof…
github-actions[bot] Jul 14, 2026
3ef2b9e
Merge pull request #2949 from microsoft/dependabot/nuget/test/Microso…
github-actions[bot] Jul 14, 2026
f692e45
Merge pull request #2947 from microsoft/docs/shallow-copy-documentation
baywet Jul 14, 2026
63fc55d
Merge pull request #2946 from microsoft/fix/pointer-validation
baywet Jul 14, 2026
f31b192
fix: validate required properties of security scheme before serializa…
baywet Jul 14, 2026
b35c799
chore(deps): bump dotnet-sdk from 10.0.301 to 10.0.302
dependabot[bot] Jul 14, 2026
68927bd
Bump the microsoftextensions group with 6 updates
dependabot[bot] Jul 14, 2026
8d2ba65
Bump Microsoft.SourceLink.GitHub from 10.0.300 to 10.0.301
dependabot[bot] Jul 14, 2026
d4660b3
Merge pull request #2958 from microsoft/dependabot/nuget/Microsoft.So…
github-actions[bot] Jul 14, 2026
1a59658
Merge pull request #2956 from microsoft/dependabot/dotnet_sdk/dotnet-…
github-actions[bot] Jul 14, 2026
9fc177b
Merge pull request #2957 from microsoft/dependabot/nuget/performance/…
github-actions[bot] Jul 14, 2026
821053b
feat: support relative URI resolution in $dynamicRef (#2928) (#2945)
aqeelat Jul 15, 2026
13ab77d
chore(main): release 3.9.0
release-please-token-provider[bot] Jul 15, 2026
0fd4e59
Merge pull request #2930 from microsoft/release-please--branches--mai…
baywet Jul 15, 2026
0b31edd
Merge pull request #2921 from aqeelat/fix/schema-reference-sibling-se…
aqeelat Jul 16, 2026
1984e31
chore(deps): bump actions/setup-dotnet from 5 to 6
dependabot[bot] Jul 16, 2026
f2b9aa5
Merge pull request #2964 from microsoft/dependabot/github_actions/act…
baywet Jul 16, 2026
eac3d66
Route NuGet restore through the CFS central package feed
gavinbarron Jul 17, 2026
60971ba
feat: serialize license identifier as extension for earlier versions
baywet Jul 20, 2026
edf3c67
fix: serialize examples as extension in v2/v3
baywet Jul 20, 2026
2441224
Initial plan
Copilot Jul 20, 2026
5d8ec3a
fix(schema): serialize compatibility examples from examples list
Copilot Jul 20, 2026
f0e3901
test(schema): shorten compatibility example test names
Copilot Jul 20, 2026
86b6e49
Merge pull request #2971 from microsoft/copilot/wip-address-feedback-…
baywet Jul 20, 2026
04bd04e
Merge pull request #2965 from microsoft/gavinbarron/cfs-package-feeds
baywet Jul 20, 2026
9387b01
fix: deserialize metadata url from extension in earlier version
baywet Jul 20, 2026
d090989
Merge pull request #2968 from microsoft/feat/license-identifier
baywet Jul 20, 2026
e5a1080
feat: adds deserialization of the example extension
baywet Jul 20, 2026
990719b
Merge branch 'main' into fix/examples-serialization
baywet Jul 20, 2026
ff1dbc9
Merge pull request #2970 from microsoft/fix/examples-serialization
baywet Jul 20, 2026
5fefd0a
chore: promote shipped APIs
github-actions[bot] Jul 20, 2026
953c22a
fix: marks deprecated properties from the specification as obsolete
baywet Jul 20, 2026
787b045
Merge pull request #2973 from microsoft/feat/mark-obsolete-apis
baywet Jul 20, 2026
8f4a60b
chore(deps): Fix System.Security.Cryptography.Xml vulnerabilities (#2…
gavinbarron Jul 21, 2026
2c75365
ci(dependabot): add cooldown default delay
baywet Jul 22, 2026
f7680ae
Merge pull request #2986 from microsoft/ci/dependabot-cooldown
baywet Jul 22, 2026
4905fc8
chore(deps): bump github/codeql-action from 4 to 4.37.0
dependabot[bot] Jul 22, 2026
39f510f
chore(deps): bump actions/upload-code-coverage from 1 to 1.3.0
dependabot[bot] Jul 22, 2026
aaef78a
Merge pull request #2987 from microsoft/dependabot/github_actions/git…
github-actions[bot] Jul 22, 2026
3632439
Merge pull request #2988 from microsoft/dependabot/github_actions/act…
github-actions[bot] Jul 22, 2026
76ee72e
chore(deps): bump actions/upload-code-coverage from 1.3.0 to 1.4.0
dependabot[bot] Jul 23, 2026
de388c9
chore(deps): bump github/codeql-action from 4.37.0 to 4.37.1
dependabot[bot] Jul 23, 2026
1b0cb3d
Merge pull request #2993 from microsoft/dependabot/github_actions/git…
github-actions[bot] Jul 23, 2026
870fce0
Merge pull request #2992 from microsoft/dependabot/github_actions/act…
github-actions[bot] Jul 23, 2026
f64aff7
chore(deps): bump actions/upload-code-coverage from 1.4.0 to 1.4.1
dependabot[bot] Jul 27, 2026
0acd7a7
Merge pull request #2995 from microsoft/dependabot/github_actions/act…
github-actions[bot] Jul 28, 2026
a3104da
chore(deps): bump github/codeql-action from 4.37.1 to 4.37.2
dependabot[bot] Jul 28, 2026
196a306
Merge pull request #2996 from microsoft/dependabot/github_actions/git…
github-actions[bot] Jul 29, 2026
13960d9
chore(deps): bump github/codeql-action from 4.37.2 to 4.37.3
dependabot[bot] Jul 29, 2026
c6e940a
Merge pull request #2997 from microsoft/dependabot/github_actions/git…
github-actions[bot] Jul 30, 2026
f9a0fb1
chore(deps): bump actions/setup-java from 5 to 5.6.0
dependabot[bot] Jul 31, 2026
7f1d904
Merge pull request #2998 from microsoft/dependabot/github_actions/act…
github-actions[bot] Aug 3, 2026
655c2c8
fix: better nullability round-tripping
Youssef1313 Aug 3, 2026
28e43a8
chore(deps): bump github/codeql-action from 4.37.3 to 4.37.4
dependabot[bot] Aug 6, 2026
4ecb4e4
Merge pull request #2999 from microsoft/dependabot/github_actions/git…
github-actions[bot] Aug 7, 2026
ebaf27a
feat: do not ignore multiple types when serializing to 3.0 (#2960)
Youssef1313 Aug 7, 2026
fe7d573
chore(deps): bump actions/setup-java from 5.6.0 to 5.7.0
dependabot[bot] Aug 7, 2026
91c5d41
Merge pull request #3001 from microsoft/dependabot/github_actions/act…
github-actions[bot] Aug 8, 2026
080c271
Merge pull request #2980 from microsoft/promote-shipped-apis-main
baywet Aug 10, 2026
0ef8aa0
chore(deps): bump github/codeql-action from 4.37.4 to 4.37.5
dependabot[bot] Aug 10, 2026
2a1c346
Merge pull request #3002 from microsoft/dependabot/github_actions/git…
github-actions[bot] Aug 11, 2026
2179326
fix: bound YAML anchor/alias expansion to prevent OOM (billion laughs…
Treicysg Aug 11, 2026
8697a18
chore: promote shipped APIs
github-actions[bot] Aug 11, 2026
dbf1f9e
chore: promote shipped APIs (#3004)
baywet Aug 11, 2026
aaf62a9
chore: upgrades dependencies not picked up by dependabot
baywet Aug 11, 2026
a32c1da
chore: adds xunit to known words
baywet Aug 11, 2026
9b68313
tests: upgrades to xunit v3
baywet Aug 11, 2026
e4938be
tests: use unique file names to avoid race conditions
baywet Aug 11, 2026
acb80ca
linting: use path join instead of combine
baywet Aug 11, 2026
7dd25c7
linting: additional path combine replacement
baywet Aug 11, 2026
0a7c001
linting: further path combine replacement
baywet Aug 11, 2026
9082e03
Merge pull request #3006 from microsoft/chore/dependencies
baywet Aug 11, 2026
577df4e
ci(pipeline): pin .NET 10 SDK to global.json version (#3010)
gavinbarron Aug 11, 2026
42bbd79
chore(deps): bump github/codeql-action from 4.37.5 to 4.37.6 (#3009)
dependabot[bot] Aug 11, 2026
25f1974
chore(main): release 3.10.0 (#2976)
release-please-token-provider[bot] Aug 12, 2026
97e7327
Pin GitHub Actions to full-length commit SHAs (#3016)
danfiedler-msft Aug 12, 2026
b7a7308
ci/nuget deploy cfs take 2 (#3015)
baywet Aug 12, 2026
95a77d8
chore: retarget branch history to support/v1
Copilot Aug 12, 2026
71b6174
fix(readers): bound YAML anchor/alias expansion to prevent OOM (billi…
Copilot Aug 12, 2026
adec1a0
refactor(readers): move YAML expansion limits into OpenApiReaderSettings
Copilot Aug 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/Microsoft.OpenApi.Readers/OpenApiReaderSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,64 @@ public enum ReferenceResolutionSetting
/// </summary>
public class OpenApiReaderSettings
{
/// <summary>
/// Default maximum nesting depth allowed when materializing values from a YAML/JSON node graph.
/// Mirrors the default System.Text.Json depth limit (64), protecting the recursive readers
/// from stack exhaustion on deeply nested documents.
/// </summary>
public const uint DefaultMaxDepth = 64;

/// <summary>
/// Default maximum number of nodes that may be materialized from a single document.
/// Guards against YAML anchor/alias expansion ("billion laughs") attacks, where a tiny document
/// expands exponentially when its shared node graph is materialized into an independent tree.
/// </summary>
public const uint DefaultMaxNodeCount = 5_000_000;

private uint _maxDepth = DefaultMaxDepth;
private uint _maxNodeCount = DefaultMaxNodeCount;

/// <summary>
/// Gets or sets the maximum nesting depth allowed when materializing values from a node graph.
/// Defaults to <see cref="DefaultMaxDepth"/>. Raise this if legitimate deeply nested documents are
/// being rejected, or lower it to fail faster when only shallow documents are expected.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Thrown when set to zero.</exception>
public uint MaxDepth
{
get => _maxDepth;
set
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "MaxDepth must be greater than zero.");
}

_maxDepth = value;
}
}

/// <summary>
/// Gets or sets the maximum number of nodes that may be materialized from a single document.
/// Defaults to <see cref="DefaultMaxNodeCount"/>, guarding against YAML anchor/alias expansion
/// ("billion laughs") attacks. Raise this if legitimate large documents are being rejected, or lower
/// it to fail faster when only small documents are expected.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Thrown when set to zero.</exception>
public uint MaxNodeCount
{
get => _maxNodeCount;
set
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "MaxNodeCount must be greater than zero.");
}

_maxNodeCount = value;
}
}

/// <summary>
/// Indicates how references in the source document should be handled.
/// </summary>
Expand Down
12 changes: 9 additions & 3 deletions src/Microsoft.OpenApi.Readers/OpenApiYamlDocumentReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ public OpenApiDocument Read(YamlDocument input, out OpenApiDiagnostic diagnostic
{
ExtensionParsers = _settings.ExtensionParsers,
BaseUrl = _settings.BaseUrl,
DefaultContentType = _settings.DefaultContentType
DefaultContentType = _settings.DefaultContentType,
MaxDepth = _settings.MaxDepth,
MaxNodeCount = _settings.MaxNodeCount
};

OpenApiDocument document = null;
Expand Down Expand Up @@ -91,7 +93,9 @@ public async Task<ReadResult> ReadAsync(YamlDocument input, CancellationToken ca
var context = new ParsingContext(diagnostic)
{
ExtensionParsers = _settings.ExtensionParsers,
BaseUrl = _settings.BaseUrl
BaseUrl = _settings.BaseUrl,
MaxDepth = _settings.MaxDepth,
MaxNodeCount = _settings.MaxNodeCount
};

OpenApiDocument document = null;
Expand Down Expand Up @@ -184,7 +188,9 @@ public T ReadFragment<T>(YamlDocument input, OpenApiSpecVersion version, out Ope
diagnostic = new();
var context = new ParsingContext(diagnostic)
{
ExtensionParsers = _settings.ExtensionParsers
ExtensionParsers = _settings.ExtensionParsers,
MaxDepth = _settings.MaxDepth,
MaxNodeCount = _settings.MaxNodeCount
};

IOpenApiElement element = null;
Expand Down
5 changes: 3 additions & 2 deletions src/Microsoft.OpenApi.Readers/ParseNodes/ListNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,13 @@ IEnumerator IEnumerable.GetEnumerator()
/// Create a <see cref="OpenApiArray"/>
/// </summary>
/// <returns>The created Any object.</returns>
public override IOpenApiAny CreateAny()
internal override IOpenApiAny CreateAny(uint depth)
{
EnsureDepthWithinLimit(depth);
var array = new OpenApiArray();
foreach (var node in this)
{
array.Add(node.CreateAny());
array.Add(node.CreateAny(depth + 1));
}

return array;
Expand Down
5 changes: 3 additions & 2 deletions src/Microsoft.OpenApi.Readers/ParseNodes/MapNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,13 @@ public string GetScalarValue(ValueNode key)
/// Create a <see cref="OpenApiObject"/>
/// </summary>
/// <returns>The created Any object.</returns>
public override IOpenApiAny CreateAny()
internal override IOpenApiAny CreateAny(uint depth)
{
EnsureDepthWithinLimit(depth);
var apiObject = new OpenApiObject();
foreach (var node in this)
{
apiObject.Add(node.Name, node.Value.CreateAny());
apiObject.Add(node.Name, node.Value.CreateAny(depth + 1));
}

return apiObject;
Expand Down
25 changes: 24 additions & 1 deletion src/Microsoft.OpenApi.Readers/ParseNodes/ParseNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal abstract class ParseNode
protected ParseNode(ParsingContext parsingContext)
{
Context = parsingContext;
Context?.CountNode();
}

public ParsingContext Context { get; }
Expand Down Expand Up @@ -73,11 +74,33 @@ public virtual Dictionary<string, T> CreateSimpleMap<T>(Func<ValueNode, T> map)
throw new OpenApiReaderException("Cannot create simple map from this type of node.", Context);
}

public virtual IOpenApiAny CreateAny()
public IOpenApiAny CreateAny()
{
return CreateAny(0);
}

/// <summary>
/// Materializes the node, and everything below it, into an <see cref="IOpenApiAny"/>.
/// </summary>
/// <param name="depth">Nesting depth of the current node, bounded by <see cref="OpenApiReaderSettings.MaxDepth"/>.</param>
internal virtual IOpenApiAny CreateAny(uint depth)
{
throw new OpenApiReaderException("Cannot create an Any object this type of node.", Context);
}

/// <summary>
/// Fails fast when the node graph is nested more deeply than the reader supports,
/// protecting the recursive readers from stack exhaustion.
/// </summary>
protected void EnsureDepthWithinLimit(uint depth)
{
var maxDepth = Context?.MaxDepth ?? OpenApiReaderSettings.DefaultMaxDepth;
if (depth > maxDepth)
{
throw new OpenApiReaderException($"The document exceeds the maximum supported nesting depth of {maxDepth}.", Context);
}
}

public virtual string GetRaw()
{
throw new OpenApiReaderException("Cannot get raw value from this type of node.", Context);
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi.Readers/ParseNodes/PropertyNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void ParseField<T>(
}
}

public override IOpenApiAny CreateAny()
internal override IOpenApiAny CreateAny(uint depth)
{
throw new NotImplementedException();
}
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.OpenApi.Readers/ParseNodes/ValueNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public override string GetScalarValue()
/// Create a <see cref="IOpenApiPrimitive"/>
/// </summary>
/// <returns>The created Any object.</returns>
public override IOpenApiAny CreateAny()
internal override IOpenApiAny CreateAny(uint depth)
{
EnsureDepthWithinLimit(depth);
var value = GetScalarValue();
return new OpenApiString(value, this._node.Style is ScalarStyle.SingleQuoted or ScalarStyle.DoubleQuoted or ScalarStyle.Literal or ScalarStyle.Folded);
}
Expand Down
17 changes: 17 additions & 0 deletions src/Microsoft.OpenApi.Readers/ParsingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public class ParsingContext
private readonly Dictionary<string, object> _tempStorage = new();
private readonly Dictionary<object, Dictionary<string, object>> _scopedTempStorage = new();
private readonly Dictionary<string, Stack<string>> _loopStacks = new();
private uint _nodeCount;
internal uint MaxDepth { get; set; } = OpenApiReaderSettings.DefaultMaxDepth;
internal uint MaxNodeCount { get; set; } = OpenApiReaderSettings.DefaultMaxNodeCount;
internal Dictionary<string, Func<IOpenApiAny, OpenApiSpecVersion, IOpenApiExtension>> ExtensionParsers { get; set; } = new();
internal RootNode RootNode { get; set; }
internal List<OpenApiTag> Tags { get; private set; } = new();
Expand Down Expand Up @@ -198,6 +201,20 @@ public void StartObject(string objectName)
_currentLocation.Push(objectName);
}

/// <summary>
/// Counts a node materialized while parsing the current document and fails fast when the
/// document expands beyond <see cref="OpenApiReaderSettings.MaxNodeCount"/>. YAML anchors and
/// aliases share a single node in the source graph, so a tiny document can expand
/// exponentially ("billion laughs") when it is materialized into an independent tree.
/// </summary>
internal void CountNode()
{
if (++_nodeCount > MaxNodeCount)
{
throw new OpenApiReaderException($"The document expands to more than the maximum supported number of nodes ({MaxNodeCount}). This may indicate a YAML anchor/alias expansion (billion laughs) attack.");
}
}

/// <summary>
/// Maintain history of traversals to avoid stack overflows from cycles
/// </summary>
Expand Down
142 changes: 142 additions & 0 deletions test/Microsoft.OpenApi.Readers.Tests/YamlAliasExpansionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using FluentAssertions;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Readers;
using Microsoft.OpenApi.Readers.Exceptions;
using Microsoft.OpenApi.Readers.ParseNodes;
using Xunit;

namespace Microsoft.OpenApi.Tests
{
[Collection("DefaultSettings")]
public class YamlAliasExpansionTests
{
// A "billion laughs" YAML bomb: each level references the previous one multiple times,
// so materializing the shared node graph into an independent object tree expands
// exponentially. The conversion must fail fast instead of exhausting memory.
private const string YamlBomb =
"""
a: &a ["x","x","x","x","x","x","x","x","x"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
""";

[Fact]
public void ExponentialAliasExpansionIsRejected()
{
var node = ParseNode.Create(new(new()), YamlHelper.ParseYamlString(YamlBomb));

Assert.Throws<OpenApiReaderException>(() => node.CreateAny());
}

[Fact]
public void ExcessiveNestingDepthIsRejected()
{
// Deeper than the conversion depth limit, which protects the recursive
// converter from stack exhaustion.
const int depth = 70;
var deeplyNested = new string('[', depth) + new string(']', depth);

var node = ParseNode.Create(new(new()), YamlHelper.ParseYamlString(deeplyNested));

Assert.Throws<OpenApiReaderException>(() => node.CreateAny());
}

[Fact]
public void ReadReturnsDiagnosticErrorForExponentialAliasExpansion()
{
// A "billion laughs" YAML bomb must surface as a diagnostic error
// rather than throwing or exhausting memory.
var input =
$$"""
openapi: 3.0.0
info:
title: bomb
version: 1.0.0
paths: {}
x-bomb:
{{YamlBombIndented()}}
""";

var reader = new OpenApiStringReader();
reader.Read(input, out var diagnostic);

diagnostic.Errors.Should().NotBeEmpty();
}

[Fact]
public void LegitimateAliasesStillConvert()
{
var input =
"""
a: &val hello
b: *val
""";

var node = ParseNode.Create(new(new()), YamlHelper.ParseYamlString(input));

var anyObject = Assert.IsType<OpenApiObject>(node.CreateAny());
Assert.Equal("hello", ((OpenApiString)anyObject["a"]).Value);
Assert.Equal("hello", ((OpenApiString)anyObject["b"]).Value);
}

[Fact]
public void ConversionLimitsDefaultToDocumentedValues()
{
var settings = new OpenApiReaderSettings();

Assert.Equal(64u, OpenApiReaderSettings.DefaultMaxDepth);
Assert.Equal(5_000_000u, OpenApiReaderSettings.DefaultMaxNodeCount);
Assert.Equal(OpenApiReaderSettings.DefaultMaxDepth, settings.MaxDepth);
Assert.Equal(OpenApiReaderSettings.DefaultMaxNodeCount, settings.MaxNodeCount);
}

[Fact]
public void SettingMaxDepthToZeroThrows()
{
var settings = new OpenApiReaderSettings();

Assert.Throws<ArgumentOutOfRangeException>(() => settings.MaxDepth = 0);
// The invalid assignment must not have changed the effective limit.
Assert.Equal(OpenApiReaderSettings.DefaultMaxDepth, settings.MaxDepth);
}

[Fact]
public void SettingMaxNodeCountToZeroThrows()
{
var settings = new OpenApiReaderSettings();

Assert.Throws<ArgumentOutOfRangeException>(() => settings.MaxNodeCount = 0);
// The invalid assignment must not have changed the effective limit.
Assert.Equal(OpenApiReaderSettings.DefaultMaxNodeCount, settings.MaxNodeCount);
}

[Fact]
public void RaisingMaxDepthAllowsDocumentsDeeperThanTheDefault()
{
// A document nested deeper than the default depth limit (64) is rejected by default
// but can be permitted by a consumer that opts into a higher limit.
const int depth = 70;
var deeplyNested = new string('[', depth) + new string(']', depth);

var context = new ParsingContext(new()) { MaxDepth = depth + 10 };
var node = ParseNode.Create(context, YamlHelper.ParseYamlString(deeplyNested));

Assert.IsType<OpenApiArray>(node.CreateAny());
}

private static string YamlBombIndented()
{
return " " + YamlBomb.Replace("\r\n", "\n").Replace("\n", "\n ");
}
}
}
Loading