diff --git a/Tools/apiCompat/baseline/ApiCompatBaseline.net6.0.txt b/Tools/apiCompat/baseline/ApiCompatBaseline.net6.0.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Wilson.sln b/Wilson.sln
index 3b3881eec7..234b01fca6 100644
--- a/Wilson.sln
+++ b/Wilson.sln
@@ -97,6 +97,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Val
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.SampleTests", "test\Microsoft.IdentityModel.SampleTests\Microsoft.IdentityModel.SampleTests.csproj", "{578FDF8F-6568-448A-AB93-D94269593932}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Abstractions", "src\Microsoft.IdentityModel.Abstractions\Microsoft.IdentityModel.Abstractions.csproj", "{8057C69A-3D1E-46A3-86E4-E6B26249DD25}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.IdentityModel.LoggingExtensions", "src\Microsoft.IdentityModel.LoggingExtensions\Microsoft.IdentityModel.LoggingExtensions.csproj", "{C1F5A997-FAA9-45E5-8D28-D4E92D4A034D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.IdentityModel.Abstractions.Tests", "test\Microsoft.IdentityModel.Abstractions.Tests\Microsoft.IdentityModel.Abstractions.Tests.csproj", "{EF9A4431-6D2C-4DD1-BF6B-6F2CC619DEE1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -227,6 +232,18 @@ Global
{578FDF8F-6568-448A-AB93-D94269593932}.Debug|Any CPU.Build.0 = Debug|Any CPU
{578FDF8F-6568-448A-AB93-D94269593932}.Release|Any CPU.ActiveCfg = Release|Any CPU
{578FDF8F-6568-448A-AB93-D94269593932}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8057C69A-3D1E-46A3-86E4-E6B26249DD25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8057C69A-3D1E-46A3-86E4-E6B26249DD25}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8057C69A-3D1E-46A3-86E4-E6B26249DD25}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8057C69A-3D1E-46A3-86E4-E6B26249DD25}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C1F5A997-FAA9-45E5-8D28-D4E92D4A034D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C1F5A997-FAA9-45E5-8D28-D4E92D4A034D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C1F5A997-FAA9-45E5-8D28-D4E92D4A034D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C1F5A997-FAA9-45E5-8D28-D4E92D4A034D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EF9A4431-6D2C-4DD1-BF6B-6F2CC619DEE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EF9A4431-6D2C-4DD1-BF6B-6F2CC619DEE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EF9A4431-6D2C-4DD1-BF6B-6F2CC619DEE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EF9A4431-6D2C-4DD1-BF6B-6F2CC619DEE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -266,6 +283,9 @@ Global
{DA585910-0E6C-45A5-AABD-30917130FD63} = {BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}
{D17F097F-6024-40BA-A7A0-015BB90F203B} = {8905D2E3-4499-4A86-BF3E-F098F228DD59}
{578FDF8F-6568-448A-AB93-D94269593932} = {8905D2E3-4499-4A86-BF3E-F098F228DD59}
+ {8057C69A-3D1E-46A3-86E4-E6B26249DD25} = {BD2706C5-6C57-484D-89C8-A0CF5F8E3D19}
+ {C1F5A997-FAA9-45E5-8D28-D4E92D4A034D} = {EB14B99B-2255-45BC-BF14-E488DCD4A4BA}
+ {EF9A4431-6D2C-4DD1-BF6B-6F2CC619DEE1} = {8905D2E3-4499-4A86-BF3E-F098F228DD59}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2F681326-7ED4-45F6-BD1D-1119EA388F42}
diff --git a/build/apiCompat.ps1 b/build/apiCompat.ps1
new file mode 100644
index 0000000000..7aac440258
--- /dev/null
+++ b/build/apiCompat.ps1
@@ -0,0 +1,224 @@
+param(
+ [string]$feedLocation = "ADO", # or 'ADO' or 'NuGet'
+ [string]$packageNames="", # comma-separated list of packages
+ [string]$packageVersion="latest", # or the exact version e.g. "5.4.0-preview"
+ [string]$adoFeedSource="", # required only for ADO feeds
+ [string]$adoFeedName="", # required only for ADO feeds
+ [string]$adoFeedUsername="VssSessionToken", # required only for ADO feeds
+ [string]$adoFeedPat="", # required only for ADO feeds
+ [string]$apiCompatRoot="$PSScriptRoot\tools\ApiCompat",
+ [string]$nugetPackageProviderVersion="2.8.5.208",
+ [string]$adoAllowPrerelease ="false" # uses the latest release (including preview releases) if packageVersion is 'latest'
+)
+
+################################################# Functions ############################################################
+
+function CreateBasicAuthHeader {
+Param(
+ [string]$Username,
+ [string]$PAT
+)
+
+$Auth = '{0}:{1}' -f $Username, $PAT
+$Auth = [System.Text.Encoding]::UTF8.GetBytes($Auth)
+$Auth = [System.Convert]::ToBase64String($Auth)
+$Header = @{Authorization=("Basic {0}" -f $Auth)}
+$Header
+}
+
+function CreatePsCredential {
+Param(
+ [string]$Username,
+ [string]$PAT
+)
+
+ $password = ConvertTo-SecureString $PAT -AsPlainText -Force
+ $pSCredential = New-Object System.Management.Automation.PSCredential $Username, $password
+ $pSCredential
+}
+
+function CreateFolder {
+Param(
+ [string]$Folder
+)
+ if (Test-Path($folder))
+ {
+ Write-Host ">>> $folder already exists!"
+ }
+ else
+ {
+ Write-Host ">>> New-Item -ItemType directory $Folder | Out-Null"
+ New-Item -ItemType directory $Folder | Out-Null
+ }
+}
+
+function DownloadPackage {
+Param(
+ [string]$PackageDownloadUrl,
+ [string]$OutFile,
+ [System.Collections.IDictionary]$Headers,
+ [string]$apiCompatRoot
+)
+ Write-Host ">>> Invoke-WebRequest -Uri $PackageDownloadUrl -OutFile $OutFile -Headers $Headers"
+ Invoke-WebRequest -Uri $PackageDownloadUrl -OutFile $OutFile -Headers $Headers
+}
+
+function FormAdoPackageDownloadUrl {
+Param(
+ [string]$FeedSource,
+ [string]$FeedName,
+ [string]$PackageName,
+ [string]$PackageVersion
+)
+
+ $scheme = ([System.Uri]$FeedSource).Scheme
+ $baseUrl = ([System.Uri]$FeedSource).Host
+ $packageDownloadUrl = "$scheme`://$baseUrl/_apis/packaging/feeds/$FeedName/nuget/packages/$PackageName/versions/$PackageVersion/content"
+ Write-Host ">>> Formed ADO package download URL: $packageDownloadUrl"
+ $packageDownloadUrl
+}
+
+function FormNugetPackageDownloadUrl {
+ Param(
+ [string]$PackageName,
+ [string]$PackageVersion
+ )
+
+ if ($PackageVersion -Eq 'latest') {
+ $packageDownloadUrl = "https://www.nuget.org/api/v2/package/$PackageName"
+ } else {
+ $packageDownloadUrl = "https://www.nuget.org/api/v2/package/$PackageName/$PackageVersion"
+ }
+
+ Write-Host ">>> Formed NuGet package download URL: $packageDownloadUrl"
+ $packageDownloadUrl
+}
+
+function PlaceContractAssemblies([String] $apiCompatRoot) {
+ Get-ChildItem "$apiCompatRoot\unzippedPackages" -Recurse -Include '*.dll' | Foreach-Object `
+ {
+ # resolve target framework, destination directory and destination assembly file path
+ $targetFramework = Split-Path $_.Directory -leaf
+ $contractAssembliesPath = "$apiCompatRoot\contractAssemblies"
+ $destDir = Join-Path -Path $contractAssembliesPath -ChildPath $targetFramework
+
+ CreateFolder($destDir)
+
+ Write-Host ">>> Copy-Item $_ -Destination $destDir"
+ Copy-Item $_ -Destination $destDir
+ }
+}
+
+function RemoveFolder {
+Param(
+ [string]$Folder
+)
+ if (Test-Path($Folder)) {
+
+ Write-Host ">>> Remove-Item -Recurse -Force $Folder -Confirm:$false"
+ Remove-Item -Recurse -Force $Folder -Confirm:$false
+ } else {
+ Write-Host ">>> $Folder doesn't exist!"
+ }
+}
+
+function UzipPackage {
+Param(
+ [string]$Package,
+ [string]$DestinationPath
+)
+ Write-Host ">>> Expand-Archive -Path $Package -DestinationPath $DestinationPath -Force"
+ Expand-Archive -Path $Package -DestinationPath $DestinationPath -Force
+}
+
+################################################# Functions ############################################################
+
+Write-Host (">>> Start ApiCompat - Prepare contract assemblies (v2) - parameters");
+Write-Host "feedLocation: " $feedLocation;
+Write-Host "adoFeedSource: " $adoFeedSource;
+Write-Host "adoFeedName: " $adoFeedName;
+Write-Host "adoFeedUsername: " $adoFeedUsername;
+Write-Host "packageNames: " $packageNames;
+Write-Host "packageVersion: " $packageVersion;
+Write-Host "apiCompatRoot: " $apiCompatRoot;
+Write-Host "nugetPackageProviderVersion: " $nugetPackageProviderVersion;
+Write-Host "adoAllowPrerelease: " $adoAllowPrerelease;
+Write-Host (">>> End ApiCompat - Prepare contract assemblies (v2) - parameters");
+
+if ($feedLocation -Eq 'ADO' -And ($adoFeedPat -Eq '' -Or $adoFeedSource -Eq '' -Or $adoFeedName -Eq '' -Or $adoFeedUsername -Eq '')) {
+ throw ">>> adoFeedPat, adoFeedSource, adoFeedName, and adoFeedUsername are required when feed location is set to 'ADO'. Run the script again and set the required values."
+}
+
+if ($packageNames -Eq '') {
+ throw ">>> List of packageNames is empty. Run the script again and set the packageNames."
+}
+
+$packageNamesArray = $packageNames.split(" ")
+
+if ($packageVersion -Eq 'latest') {
+ $useLatestVersion = 'true'
+} else {
+ $useLatestVersion = 'false'
+}
+
+# determine the latest package version from an ADO feed
+if ($packageVersion -Eq 'latest' -And $feedLocation -Eq "ADO") {
+ $nugetPackageProviderResult = Get-PackageProvider -Name Nuget -ErrorAction SilentlyContinue
+ if ($null -Eq $nugetPackageProviderResult -Or $nugetPackageProviderResult.Version -ne [System.Version]$nugetPackageProviderVersion) {
+ Write-Host ">>> Install-PackageProvider Nuget -RequiredVersion $nugetPackageProviderVersion -Force -Scope CurrentUser | Out-Null"
+ Install-PackageProvider Nuget -RequiredVersion $nugetPackageProviderVersion -Force -Scope CurrentUser | Out-Null
+ } else {
+ Write-Host (">>> Nuget package provider (" + $nugetPackageProviderResult.Version + ") is already installed.")
+ }
+
+ $credential = CreatePsCredential -Username $adoFeedUsername -PAT $adoFeedPat
+
+ $getFeedResult = Get-PSRepository -Name $adoFeedName -ErrorAction SilentlyContinue
+ if ($null -Eq $getFeedResult) {
+ Write-Host ">>> Register-PSRepository -Name $adoFeedName -SourceLocation $adoFeedSource -InstallationPolicy Trusted -Credential $credential"
+ Register-PSRepository -Name $adoFeedName -SourceLocation $adoFeedSource -InstallationPolicy Trusted -Credential $credential
+ } else
+ {
+ Write-Host ">>> Feed $adoFeedName is already registered."
+ }
+}
+
+# prepare directories
+RemoveFolder -Folder "$apiCompatRoot\contractAssemblies"
+CreateFolder -Folder "$apiCompatRoot\contractAssemblies"
+CreateFolder("$apiCompatRoot\downloadedPackages")
+
+# download and unzip packages
+foreach($packageName in $packageNamesArray) {
+ $packageName = $packageName.trim()
+ $outFile = "$apiCompatRoot\downloadedPackages\$packageName.zip"
+ $unzippedDir = "$apiCompatRoot\unzippedPackages\$packageName"
+
+ if ($useLatestVersion -Eq 'true' -And $feedLocation -Eq "ADO") {
+ if ($adoAllowPrerelease -Eq 'true') {
+ $packageVersion = (Find-Module -Name $packageName -Repository $adoFeedName -Credential $credential -AllowPrerelease)[0].Version
+ } else {
+ $packageVersion = (Find-Module -Name $packageName -Repository $adoFeedName -Credential $credential)[0].Version
+ }
+ }
+
+ Write-Host (">>> Latest " + $packageName + " version: $packageVersion")
+
+ if ($feedLocation -eq 'ADO') {
+ $header = CreateBasicAuthHeader -Username $adoFeedUsername -PAT $adoFeedPat
+ $downloadPackageUrl = FormAdoPackageDownloadUrl -FeedSource $adoFeedSource -FeedName $adoFeedName -PackageName $packageName -PackageVersion $PackageVersion
+ DownloadPackage -packageDownloadUrl $downloadPackageUrl -header $header -outFile $outFile -apiCompatRoot $apiCompatRoot
+ } else {
+ $downloadPackageUrl = FormNugetPackageDownloadUrl -PackageName $packageName -PackageVersion $PackageVersion
+ DownloadPackage -packageDownloadUrl $downloadPackageUrl -outFile $outFile -apiCompatRoot $apiCompatRoot
+ }
+
+ UzipPackage -package $outFile -destinationPath $unzippedDir
+}
+
+# place the contract assemblies and clean-up
+PlaceContractAssemblies($apiCompatRoot)
+RemoveFolder -Folder "$apiCompatRoot\downloadedPackages"
+RemoveFolder -Folder "$apiCompatRoot\unzippedPackages"
+
+Write-Host ">>> Done - ApiCompat - Prepare contract assemblies (v2)."
\ No newline at end of file
diff --git a/build/commonTest.props b/build/commonTest.props
index f2841c11e1..9d82ef294a 100644
--- a/build/commonTest.props
+++ b/build/commonTest.props
@@ -15,14 +15,14 @@
true
$(TestTargets)
$(TestOnlyCoreTargets)
- $(DotNetCoreAppRuntimeVersion)
+ $(DotNetCoreAppRuntimeVersion)
-
+
$(DefineConstants);NET_CORE
-
+
diff --git a/build/dependencies.props b/build/dependencies.props
index f29b39a92b..472efa8d00 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -1,5 +1,6 @@
+ 2.1.1
3.0.5
1.0.3
4.5.0
diff --git a/build/dependenciesTest.props b/build/dependenciesTest.props
index 0d815f29e6..2c6874bcf6 100644
--- a/build/dependenciesTest.props
+++ b/build/dependenciesTest.props
@@ -1,11 +1,11 @@
- 2.1.19
+ 2.1.30
2.0.3
2.0.5
2.4.0-prerelease-63213-02
1.0.4.403061554
- 15.9.0
+ 16.10.0
4.0.4.403061554
4.3.4
2.4.0
diff --git a/build/releaseBuild.yml b/build/releaseBuild.yml
new file mode 100644
index 0000000000..27c213b91f
--- /dev/null
+++ b/build/releaseBuild.yml
@@ -0,0 +1,227 @@
+trigger: none
+pr: none
+
+name: $(TeamProject)_$(Build.DefinitionName)_$(SourceBranchName)_$(Date:yyyyMMdd)$(Rev:.r)
+
+# Create a daily midnight build for release builds on master to ensure our release builds function
+schedules:
+- cron: "0 0 * * *"
+ displayName: Daily midnight build
+ branches:
+ include:
+ - dev
+
+variables:
+ - group: Middleware
+ - name: BuildPlatform
+ value: 'any cpu'
+ - name: BuildConfiguration
+ value: 'Release'
+
+jobs:
+- job: build
+ pool:
+ name: MwWilson1EsHostedPool
+ demands:
+ - msbuild
+ - DotNetFramework
+ - visualstudio
+ timeoutInMinutes: 360
+
+ steps:
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core sdk 2.1.818'
+ inputs:
+ version: 2.1.818
+ installationPath: 'c:\Program Files\dotnet'
+
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core sdk 2.1.x'
+ inputs:
+ version: 2.1.x
+ installationPath: $(Agent.ToolsDirectory)/dotnet
+
+ - task: UseDotNet@2
+ displayName: 'Use .Net Core SDK 6'
+ inputs:
+ version: 6.0.x
+
+ - task: DotNetCoreCLI@2
+ displayName: 'dotnet --list-sdks '
+ inputs:
+ command: custom
+ custom: '--list-sdks '
+
+ - task: CmdLine@1
+ displayName: 'Run VerifyResourceUsage.pl'
+ inputs:
+ filename: perl
+ arguments: '$(Agent.BuildDirectory)\s\src\VerifyResourceUsage.pl'
+
+ - powershell: |
+ regedit /s .\build\strongNameBypass.reg
+ regedit /s .\build\strongNameBypass2.reg
+ displayName: 'Strong Name Bypass'
+
+ - task: PowerShell@2
+ displayName: 'Update Assembly Info'
+ inputs:
+ targetType: filePath
+ filePath: ./updateAssemblyInfo.ps1
+ arguments: '-packageType $(BuildConfiguration)'
+
+ - task: PowerShell@2
+ displayName: 'Prepare contract assemblies'
+ inputs:
+ targetType: 'filePath'
+ filePath: $(Agent.BuildDirectory)\s\build\apiCompat.ps1
+ arguments: >
+ -feedLocation "NuGet"
+ -packageNames $(Wilson6xPackageList)
+ -packageVersion: "latest"
+ -adoFeedSource: $(AdoFeedSource)
+ -adoFeedName: $(AdoFeedName)
+ -adoAllowPrerelease: "false"
+ -apiCompatRoot: $(ApiCompatRootWilson)
+ -nugetPackageProviderVersion: "2.8.5.208"
+
+ - task: MSBuild@1
+ displayName: Build
+ inputs:
+ solution: wilson.sln
+ msbuildVersion: '17.0.0'
+ msbuildArchitecture: x64
+ msbuildArguments: '/r:True /p:Configuration=$(BuildConfiguration) /p:Platform="Any CPU" /verbosity:m /p:SourceLinkCreate=true /p:RunApiCompat=true'
+
+ - task: PowerShell@2
+ displayName: 'Run Tests'
+ inputs:
+ targetType: filePath
+ filePath: ./runTests.ps1
+ arguments: '-buildType $(BuildConfiguration)'
+
+ - task: CopyFiles@2
+ displayName: 'Copy Files to: [staging]\ProductBinaries'
+ inputs:
+ SourceFolder: src
+ Contents: |
+ **\bin\$(BuildConfiguration)\**\Microsoft.IdentityModel.*.dll
+ **\bin\$(BuildConfiguration)\**\Microsoft.IdentityModel.*.pdb
+ **\bin\$(BuildConfiguration)\**\System.IdentityModel.Tokens.Jwt.dll
+ **\bin\$(BuildConfiguration)\**\System.IdentityModel.Tokens.Jwt.pdb
+ TargetFolder: '$(Build.ArtifactStagingDirectory)\ProductBinaries'
+
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@1
+ displayName: 'Run PoliCheck'
+ inputs:
+ targetType: F
+ optionsFC: 0
+ optionsXS: 0
+ optionsHMENABLE: 0
+
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@2
+ displayName: 'Run CredScan'
+ inputs:
+ suppressionsFile: 'build/credscan-exclusion.json'
+ debugMode: false
+
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-roslynanalyzers.RoslynAnalyzers@2
+ displayName: 'Run Roslyn Analyzers'
+
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@3
+ displayName: 'Run BinSkim'
+ inputs:
+ InputType: Basic
+ AnalyzeTarget: '$(Build.ArtifactStagingDirectory)\*.dll'
+ AnalyzeSymPath: '$(Build.ArtifactStagingDirectory)\ProductBinaries'
+ AnalyzeVerbose: true
+ AnalyzeHashes: true
+
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2
+ displayName: 'Publish Security Analysis Logs'
+ continueOnError: true
+
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-postanalysis.PostAnalysis@1
+ displayName: 'Post SDL Analysis'
+ inputs:
+ BinSkim: true
+ CredScan: true
+ PoliCheck: true
+ continueOnError: true
+
+ #Sign Wilson 6x task group
+ - template: template-sign-wilson-6x.yaml
+
+ - task: PowerShell@2
+ displayName: Pack
+ inputs:
+ targetType: filePath
+ filePath: ./pack.ps1
+ arguments: '-buildType $(BuildConfiguration)'
+
+ - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
+ displayName: 'Sign Nuget Packages'
+ inputs:
+ ConnectedServiceName: 'IDDP Code Signing'
+ FolderPath: artifacts
+ Pattern: '*.nupkg'
+ signConfigType: inlineSignParams
+ inlineOperation: |
+ [
+ {
+ "keyCode": "CP-401405",
+ "operationSetCode": "NuGetSign",
+ "parameters": [ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
+ },
+ {
+ "keyCode": "CP-401405",
+ "operationSetCode": "NuGetVerify",
+ "parameters": [ ],
+ "toolName": "sign",
+ "toolVersion": "1.0"
+ }
+ ]
+ SessionTimeout: 20
+
+ - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
+ displayName: 'Component Detection'
+ inputs:
+ scanType: 'Register'
+ verbosity: 'Verbose'
+ alertWarningLevel: 'High'
+
+ - task: PublishSymbols@2
+ displayName: 'Publish symbols on symweb (cross publish)'
+ inputs:
+ SearchPattern: '**\bin\**\*.IdentityModel.*'
+ SymbolServerType: TeamServices
+ TreatNotIndexedAsWarning: true
+
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-uploadtotsa.TSAUpload@1
+ displayName: 'TSA upload to Codebase: WILSON Stamp: Azure'
+ inputs:
+ tsaVersion: TsaV2
+ codeBaseName: WILSON
+ uploadAPIScan: false
+ uploadFortifySCA: false
+ uploadFxCop: false
+ uploadModernCop: false
+ uploadPREfast: false
+ uploadTSLint: false
+
+ - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
+ displayName: 'Manifest Generator '
+ inputs:
+ BuildDropPath: '$(Build.SourcesDirectory)\src'
+ ManifestDirPath: '$(Build.SourcesDirectory)\artifacts'
+
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish NuGet Package Artifact'
+ inputs:
+ PathtoPublish: '$(Build.SourcesDirectory)\artifacts'
+ ArtifactName: '$(Build.BuildNumber)-nuget-package'
+
+ - task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
+ displayName: 'Clean Agent Directories'
diff --git a/build/strongNameBypass.reg b/build/strongNameBypass.reg
index 242b5f53cb..970e9a7471 100644
Binary files a/build/strongNameBypass.reg and b/build/strongNameBypass.reg differ
diff --git a/build/strongNameBypass2.reg b/build/strongNameBypass2.reg
index ec084be794..930b518bda 100644
Binary files a/build/strongNameBypass2.reg and b/build/strongNameBypass2.reg differ
diff --git a/build/targets.props b/build/targets.props
index 3c93d991a6..e5ac9a6e94 100644
--- a/build/targets.props
+++ b/build/targets.props
@@ -1,6 +1,6 @@
- net45;net461;net472;netstandard2.0
+ net45;net461;net472;netstandard2.0;net6.0
netstandard2.0
diff --git a/build/targetsTest.props b/build/targetsTest.props
index 3bcbc92921..19306fa550 100644
--- a/build/targetsTest.props
+++ b/build/targetsTest.props
@@ -1,6 +1,6 @@
- net452;net461;net472;netcoreapp2.1
+ net452;net461;net472;netcoreapp2.1;net6.0
netcoreapp2.1
diff --git a/build/template-sign-binary.yml b/build/template-sign-binary.yml
new file mode 100644
index 0000000000..cf61a57fd6
--- /dev/null
+++ b/build/template-sign-binary.yml
@@ -0,0 +1,69 @@
+# template-sign-binary.yml
+# Signs a binary via ESRP
+
+parameters:
+ LibraryName: ''
+ BuildConfiguration: ''
+
+steps:
+- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
+ displayName: 'Sign ${{ parameters.LibraryName }}'
+ inputs:
+ ConnectedServiceName: 'IDDP Code Signing'
+ FolderPath: 'src\${{ parameters.LibraryName }}\bin\${{ parameters.BuildConfiguration }}'
+ Pattern: ${{ parameters.LibraryName }}.dll
+ signConfigType: inlineSignParams
+ inlineOperation: |
+ [
+ {
+ "keyCode": "MSSharedLibSnKey",
+ "operationSetCode": "StrongNameSign",
+ "parameters": null,
+ "toolName": "sn.exe",
+ "toolVersion": "V4.6.1586.0"
+ },
+ {
+ "keyCode": "MSSharedLibSnKey",
+ "operationSetCode": "StrongNameVerify",
+ "parameters": null,
+ "toolName": "sn.exe",
+ "toolVersion": "V4.6.1586.0"
+ },
+ {
+ "keyCode": "CP-230012",
+ "operationSetCode": "SigntoolSign",
+ "parameters": [
+ {
+ "parameterName": "OpusName",
+ "parameterValue": "TestSign"
+ },
+ {
+ "parameterName": "OpusInfo",
+ "parameterValue": "http://test"
+ },
+ {
+ "parameterName": "PageHash",
+ "parameterValue": "/NPH"
+ },
+ {
+ "parameterName": "FileDigest",
+ "parameterValue": "/fd sha256"
+ },
+ {
+ "parameterName": "TimeStamp",
+ "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
+ }
+ ],
+ "toolName": "signtool.exe",
+ "toolVersion": "6.2.9304.0"
+ },
+ {
+ "keyCode": "CP-230012",
+ "operationSetCode": "SigntoolVerify",
+ "parameters": [ ],
+ "toolName": "signtool.exe",
+ "toolVersion": "6.2.9304.0"
+ }
+ ]
+ SessionTimeout: 20
+ VerboseLogin: true
diff --git a/build/template-sign-wilson-6x.yaml b/build/template-sign-wilson-6x.yaml
new file mode 100644
index 0000000000..00a1be681d
--- /dev/null
+++ b/build/template-sign-wilson-6x.yaml
@@ -0,0 +1,91 @@
+#template sign-wilson-6x
+
+parameters:
+ BuildConfiguration: 'release'
+
+steps:
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'System.IdentityModel.Tokens.Jwt'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.JsonWebTokens'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Logging'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Protocols'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Protocols.WsFederation'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Tokens'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Tokens.Saml'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Xml'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Protocols.OpenIdConnect'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Protocols.SignedHttpRequest'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.KeyVaultExtensions'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.ManagedKeyVaultSecurityKey'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Validators'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.Abstractions'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.LoggingExtensions'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- template: template-sign-binary.yml
+ parameters:
+ LibraryName: 'Microsoft.IdentityModel.TestExtensions'
+ BuildConfiguration: ${{ parameters.BuildConfiguration }}
+
+- task: PowerShell@1
+ displayName: 'Verify Signing'
+ inputs:
+ scriptName: build/VerifySigning.ps1
+ arguments: '-buildType ${{ parameters.BuildConfiguration }}'
\ No newline at end of file
diff --git a/buildConfiguration.xml b/buildConfiguration.xml
index b5620f26ed..007ec93b93 100644
--- a/buildConfiguration.xml
+++ b/buildConfiguration.xml
@@ -2,7 +2,7 @@
x64
3.5.0-rc-1285
net45,net461,netstandard2.0
- 6.16.1
+ 6.20.1
preview
@@ -19,6 +19,9 @@
+
+
+
@@ -36,7 +39,7 @@
-
+
diff --git a/src/Microsoft.IdentityModel.Abstractions/EventLogLevel.cs b/src/Microsoft.IdentityModel.Abstractions/EventLogLevel.cs
new file mode 100644
index 0000000000..a23359df53
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/EventLogLevel.cs
@@ -0,0 +1,69 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// Defines Event Log Levels.
+ ///
+ public enum EventLogLevel
+ {
+ ///
+ /// No level filtering is done on this log level. Log messages of all levels will be logged.
+ ///
+ LogAlways = 0,
+
+ ///
+ /// Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires
+ /// immediate attention.
+ ///
+ Critical = 1,
+
+ ///
+ /// Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a
+ /// failure in the current activity, not an application-wide failure.
+ ///
+ Error = 2,
+
+ ///
+ /// Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the
+ /// application execution to stop.
+ ///
+ Warning = 3,
+
+ ///
+ /// Logs that track the general flow of the application. These logs should have long-term value.
+ ///
+ Informational = 4,
+
+ ///
+ /// Logs that are used for interactive investigation during development. These logs should primarily contain
+ /// information useful for debugging and have no long-term value.
+ ///
+ Verbose = 5
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Abstractions/IIdentityLogger.cs b/src/Microsoft.IdentityModel.Abstractions/IIdentityLogger.cs
new file mode 100644
index 0000000000..c915f788d5
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/IIdentityLogger.cs
@@ -0,0 +1,47 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// Interface that needs to be implemented by classes providing logging in Microsoft identity libraries.
+ ///
+ public interface IIdentityLogger
+ {
+ ///
+ /// Checks to see if logging is enabled at given .
+ ///
+ /// Log level of a message.
+ bool IsEnabled(EventLogLevel eventLogLevel);
+
+ ///
+ /// Writes a log entry.
+ ///
+ /// Defines a structured message to be logged at the provided .
+ void Log(LogEntry entry);
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Abstractions/ITelemetryClient.cs b/src/Microsoft.IdentityModel.Abstractions/ITelemetryClient.cs
new file mode 100644
index 0000000000..b6086bec89
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/ITelemetryClient.cs
@@ -0,0 +1,78 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// Interface for Telemetry tracking.
+ ///
+ public interface ITelemetryClient
+ {
+ ///
+ /// Gets or sets the application or client ID that telemetry is being sent for.
+ ///
+ string ClientId { get; set; }
+
+ ///
+ /// Perform any necessary bootstrapping for the telemetry client.
+ ///
+ ///
+ /// The expectation is that this should only be called once for the lifetime of the object however the
+ /// implementation should be idempotent.
+ ///
+ void Initialize();
+
+ ///
+ /// Checks to see if telemetry is enabled all up.
+ ///
+ ///
+ /// Returns if telemetry should be sent; otherwise.
+ ///
+ ///
+ /// This check should be used to gate any resource intensive operations to generate telemetry as well.
+ ///
+ bool IsEnabled();
+
+ ///
+ /// Checks to see if telemetry is enabled for the named event.
+ ///
+ /// Name of the event to check.
+ ///
+ /// Returns if telemetry should be sent for ;
+ /// otherwise.
+ ///
+ ///
+ /// This check should be used to gate any resource intensive operations to generate telemetry as well.
+ ///
+ bool IsEnabled(string eventName);
+
+ ///
+ /// Tracks an instance of a named event.
+ ///
+ /// Details of the event to track.
+ void TrackEvent(
+ TelemetryEventDetails eventDetails);
+
+ ///
+ /// Tracks an instance of a named event.
+ ///
+ /// Name of the event to track. Should be unique per scenario.
+ /// Key value pair of strings to long with the event.
+ /// Key value pair of longs to long with the event.
+ /// Key value pair of bools to long with the event.
+ /// Key value pair of DateTimes to long with the event.
+ /// Key value pair of doubles to long with the event.
+ /// Key value pair of Guids to long with the event.
+ void TrackEvent(
+ string eventName,
+ IDictionary stringProperties = null,
+ IDictionary longProperties = null,
+ IDictionary boolProperties = null,
+ IDictionary dateTimeProperties = null,
+ IDictionary doubleProperties = null,
+ IDictionary guidProperties = null);
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Abstractions/LogEntry.cs b/src/Microsoft.IdentityModel.Abstractions/LogEntry.cs
new file mode 100644
index 0000000000..f60726a286
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/LogEntry.cs
@@ -0,0 +1,53 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// Defines the structure of a log entry.
+ ///
+ public class LogEntry
+ {
+ ///
+ /// Defines the .
+ ///
+ public EventLogLevel EventLogLevel { get; set; }
+
+ ///
+ /// Message to be logged.
+ ///
+ public string Message { get; set; }
+
+ ///
+ /// A unique identifier for a request that can help with diagnostics across components.
+ ///
+ ///
+ /// Also referred to as ActivityId in Microsoft.IdentityModel.Tokens.CallContext.
+ ///
+ public string CorrelationId { get; set; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Abstractions/Microsoft.IdentityModel.Abstractions.csproj b/src/Microsoft.IdentityModel.Abstractions/Microsoft.IdentityModel.Abstractions.csproj
new file mode 100644
index 0000000000..e605b66732
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/Microsoft.IdentityModel.Abstractions.csproj
@@ -0,0 +1,25 @@
+
+
+
+
+
+ Microsoft.IdentityModel.Abstractions
+ A package containing thin abstractions for Microsoft.IdentityModel.
+ true
+ Microsoft.IdentityModel.Abstractions
+ .NET;Windows;Authentication;Identity;Abstractions
+
+
+
+ full
+ true
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/src/Microsoft.IdentityModel.Abstractions/NullIdentityModelLogger.cs b/src/Microsoft.IdentityModel.Abstractions/NullIdentityModelLogger.cs
new file mode 100644
index 0000000000..9710b8d8d5
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/NullIdentityModelLogger.cs
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// A minimalistic implementation that is disabled by default and doesn't log.
+ ///
+ public sealed class NullIdentityModelLogger : IIdentityLogger
+ {
+ ///
+ /// Default instance of .
+ ///
+ public static NullIdentityModelLogger Instance { get; } = new NullIdentityModelLogger();
+
+ private NullIdentityModelLogger() { }
+
+ ///
+ public bool IsEnabled(EventLogLevel eventLogLevel) => false;
+
+ ///
+ public void Log(LogEntry entry)
+ {
+ // no-op
+ }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Abstractions/NullTelemetryClient.cs b/src/Microsoft.IdentityModel.Abstractions/NullTelemetryClient.cs
new file mode 100644
index 0000000000..3350d6b56a
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/NullTelemetryClient.cs
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// The default implementation of the interface which swallows all telemetry signals.
+ ///
+ public class NullTelemetryClient : ITelemetryClient
+ {
+ ///
+ public string ClientId { get; set; }
+
+ ///
+ /// Singleton instance of .
+ ///
+ public static NullTelemetryClient Instance { get; } = new NullTelemetryClient();
+
+ ///
+ /// Initializes an instance of .
+ ///
+ ///
+ /// Private constructor to prevent the default constructor being exposed.
+ ///
+ private NullTelemetryClient() { }
+
+ ///
+ public bool IsEnabled() => false;
+
+ ///
+ public bool IsEnabled(string eventName) => false;
+
+ ///
+ public void Initialize()
+ {
+ // no-op
+ }
+
+ ///
+ public void TrackEvent(TelemetryEventDetails eventDetails)
+ {
+ // no-op
+ }
+
+ ///
+ public void TrackEvent(
+ string eventName,
+ IDictionary stringProperties = null,
+ IDictionary longProperties = null,
+ IDictionary boolProperties = null,
+ IDictionary dateTimeProperties = null,
+ IDictionary doubleProperties = null,
+ IDictionary guidProperties = null)
+ {
+ // no-op
+ }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Abstractions/ObservabilityConstants.cs b/src/Microsoft.IdentityModel.Abstractions/ObservabilityConstants.cs
new file mode 100644
index 0000000000..ef07cc7142
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/ObservabilityConstants.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// Common class containing observability constants to be used as well known metric keys.
+ ///
+ public static class ObservabilityConstants
+ {
+ ///
+ /// String used for the name of the property indicating if the call was successful.
+ ///
+ public const string Succeeded = "Succeeded";
+
+ ///
+ /// String used for the name of the property indicating the call in Duration (ms).
+ ///
+ public const string Duration = "Duration";
+
+ ///
+ /// String used for the name of the property indicating the call's Activity Id/Correlation Id.
+ ///
+ public const string ActivityId = "ActivityId";
+
+ ///
+ /// String used for the name of the property indicating the caller's ClientId.
+ ///
+ public const string ClientId = "ClientId";
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Abstractions/Properties/AssemblyInfo.cs b/src/Microsoft.IdentityModel.Abstractions/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..676a61750f
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/Properties/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyInformationalVersion("0.0.1")]
+[assembly: AssemblyFileVersion("0.0.1")]
+[assembly: AssemblyMetadata("Serviceable", "True")]
+[assembly: AssemblyVersion("0.0.1")]
+[assembly: CLSCompliant(true)]
+[assembly: ComVisible(false)]
diff --git a/src/Microsoft.IdentityModel.Abstractions/TelemetryEventDetails.cs b/src/Microsoft.IdentityModel.Abstractions/TelemetryEventDetails.cs
new file mode 100644
index 0000000000..86972aaa39
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Abstractions/TelemetryEventDetails.cs
@@ -0,0 +1,127 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.IdentityModel.Abstractions
+{
+ ///
+ /// Details of the telemetry event.
+ ///
+ ///
+ /// This implementation is not meant to be thread-safe. This implementation would either need to be overridden or
+ /// usage should not be concurrently operated on.
+ ///
+ public abstract class TelemetryEventDetails
+ {
+ ///
+ /// The underlying properties making up the .
+ ///
+ protected internal IDictionary PropertyValues { get; } = new Dictionary();
+
+ ///
+ /// Name of the telemetry event, should be unique between events.
+ ///
+ public virtual string Name { get; set; }
+
+ ///
+ /// Properties which describe the event.
+ ///
+ public virtual IReadOnlyDictionary Properties
+ {
+ get
+ {
+ return (IReadOnlyDictionary)PropertyValues;
+ }
+ }
+
+ ///
+ /// Sets a property on the event details.
+ ///
+ /// Property key.
+ /// Property value.
+ /// 'key' is null.
+ public virtual void SetProperty(
+ string key,
+ string value)
+ {
+ SetPropertyCore(key, value);
+ }
+
+ ///
+ /// Sets a property on the event details.
+ ///
+ /// Property key.
+ /// Property value.
+ /// 'key' is null.
+ public virtual void SetProperty(
+ string key,
+ long value)
+ {
+ SetPropertyCore(key, value);
+ }
+
+ ///
+ /// Sets a property on the event details.
+ ///
+ /// Property key.
+ /// Property value.
+ /// 'key' is null.
+ public virtual void SetProperty(
+ string key,
+ bool value)
+ {
+ SetPropertyCore(key, value);
+ }
+
+ ///
+ /// Sets a property on the event details.
+ ///
+ /// Property key.
+ /// Property value.
+ /// 'key' is null.
+ public virtual void SetProperty(
+ string key,
+ DateTime value)
+ {
+ SetPropertyCore(key, value);
+ }
+
+ ///
+ /// Sets a property on the event details.
+ ///
+ /// Property key.
+ /// Property value.
+ /// 'key' is null.
+ public virtual void SetProperty(
+ string key,
+ double value)
+ {
+ SetPropertyCore(key, value);
+ }
+
+ ///
+ /// Sets a property on the event details.
+ ///
+ /// Property key.
+ /// Property value.
+ /// 'key' is null.
+ public virtual void SetProperty(
+ string key,
+ Guid value)
+ {
+ SetPropertyCore(key, value);
+ }
+
+ private void SetPropertyCore(
+ string key,
+ object value)
+ {
+ if (key == null)
+ throw new ArgumentNullException(nameof(key));
+
+ PropertyValues[key] = value;
+ }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.JsonWebTokens/GlobalSuppressions.cs
index 2b09e611a9..4c9f5ebb89 100644
--- a/src/Microsoft.IdentityModel.JsonWebTokens/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/GlobalSuppressions.cs
@@ -24,7 +24,8 @@
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is written to a string", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateSignature(System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters,Microsoft.IdentityModel.Tokens.BaseConfiguration)~Microsoft.IdentityModel.JsonWebTokens.JsonWebToken")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is returned in the TokenValidationResult", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWE(Microsoft.IdentityModel.JsonWebTokens.JsonWebToken,System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters,Microsoft.IdentityModel.Tokens.BaseConfiguration)~Microsoft.IdentityModel.Tokens.TokenValidationResult")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is returned in the TokenValidationResult", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateJWS(System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters,Microsoft.IdentityModel.Tokens.BaseConfiguration)~Microsoft.IdentityModel.Tokens.TokenValidationResult")]
-[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is written to a string", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken(System.String,Microsoft.IdentityModel.JsonWebTokens.JsonWebToken,System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters)~Microsoft.IdentityModel.Tokens.TokenValidationResult")]
-[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is written to a string", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.GetConfigurationAndLogError(Microsoft.IdentityModel.Tokens.TokenValidationParameters)~Microsoft.IdentityModel.Tokens.BaseConfiguration")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is returned in the TokenValidationResult", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters)~System.Threading.Tasks.Task{Microsoft.IdentityModel.Tokens.TokenValidationResult}")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is written to a string", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateTokenAsync(System.String,Microsoft.IdentityModel.JsonWebTokens.JsonWebToken,System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters)~System.Threading.Tasks.Task{Microsoft.IdentityModel.Tokens.TokenValidationResult}")]
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Vendored component", Scope = "module")]
+[assembly: SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "It is used within a defined if condition", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.GetSecurityKey(Microsoft.IdentityModel.Tokens.EncryptingCredentials,Microsoft.IdentityModel.Tokens.CryptoProviderFactory,System.Collections.Generic.IDictionary{System.String,System.Object},System.Byte[]@)~Microsoft.IdentityModel.Tokens.SecurityKey")]
+[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is written to a string", Scope = "member", Target = "~M:Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.CreateTokenPrivate(System.String,Microsoft.IdentityModel.Tokens.SigningCredentials,Microsoft.IdentityModel.Tokens.EncryptingCredentials,System.String,System.Collections.Generic.IDictionary{System.String,System.Object},System.Collections.Generic.IDictionary{System.String,System.Object},System.String)~System.String")]
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cd b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cd
new file mode 100644
index 0000000000..e5a50696fe
--- /dev/null
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cd
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ hAcTICgAAAAMggAEAIQYCAUAAAIwBCCAwKAAYQAQAAA=
+ JsonWebToken.cs
+
+
+
+
\ No newline at end of file
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cs b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cs
index d162f82d94..68db639f91 100644
--- a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cs
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebToken.cs
@@ -331,7 +331,6 @@ public override SecurityKey SigningKey
/// the original token.
private void Decode(string[] tokenParts, string rawData)
{
- LogHelper.LogInformation(LogMessages.IDX14106, rawData);
try
{
Header = JObject.Parse(Base64UrlEncoder.Decode(tokenParts[0]));
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
index 3a2bea60a3..5680655f90 100644
--- a/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/JsonWebTokenHandler.cs
@@ -65,6 +65,19 @@ public Type TokenType
get { return typeof(JsonWebToken); }
}
+ internal static IDictionary AddCtyClaimDefaultValue(IDictionary additionalClaims, bool setDefaultCtyClaim)
+ {
+ if (!setDefaultCtyClaim)
+ return additionalClaims;
+
+ if (additionalClaims == null)
+ additionalClaims = new Dictionary { { JwtHeaderParameterNames.Cty, JwtConstants.HeaderType } };
+ else if (!additionalClaims.TryGetValue(JwtHeaderParameterNames.Cty, out _))
+ additionalClaims.Add(JwtHeaderParameterNames.Cty, JwtConstants.HeaderType);
+
+ return additionalClaims;
+ }
+
///
/// Determines if the string is a well formed Json Web Token (JWT).
/// See: https://datatracker.ietf.org/doc/html/rfc7519
@@ -177,7 +190,7 @@ public virtual string CreateToken(string payload)
if (string.IsNullOrEmpty(payload))
throw LogHelper.LogArgumentNullException(nameof(payload));
- return CreateTokenPrivate(JObject.Parse(payload), null, null, null, null, null);
+ return CreateTokenPrivate(payload, null, null, null, null, null, null);
}
///
@@ -196,7 +209,7 @@ public virtual string CreateToken(string payload, IDictionary ad
if (additionalHeaderClaims == null)
throw LogHelper.LogArgumentNullException(nameof(additionalHeaderClaims));
- return CreateTokenPrivate(JObject.Parse(payload), null, null, null, additionalHeaderClaims, null);
+ return CreateTokenPrivate(payload, null, null, null, additionalHeaderClaims, null, null);
}
///
@@ -215,7 +228,7 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
if (signingCredentials == null)
throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
- return CreateTokenPrivate(JObject.Parse(payload), signingCredentials, null, null, null, null);
+ return CreateTokenPrivate(payload, signingCredentials, null, null, null, null, null);
}
///
@@ -242,7 +255,7 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
if (additionalHeaderClaims == null)
throw LogHelper.LogArgumentNullException(nameof(additionalHeaderClaims));
- return CreateTokenPrivate(JObject.Parse(payload), signingCredentials, null, null, additionalHeaderClaims, null);
+ return CreateTokenPrivate(payload, signingCredentials, null, null, additionalHeaderClaims, null, null);
}
///
@@ -310,7 +323,14 @@ public virtual string CreateToken(SecurityTokenDescriptor tokenDescriptor)
payload[JwtRegisteredClaimNames.Nbf] = EpochTime.GetIntDate(tokenDescriptor.NotBefore.Value);
}
- return CreateTokenPrivate(payload, tokenDescriptor.SigningCredentials, tokenDescriptor.EncryptingCredentials, tokenDescriptor.CompressionAlgorithm, tokenDescriptor.AdditionalHeaderClaims, tokenDescriptor.TokenType);
+ return CreateTokenPrivate(
+ payload.ToString(Formatting.None),
+ tokenDescriptor.SigningCredentials,
+ tokenDescriptor.EncryptingCredentials,
+ tokenDescriptor.CompressionAlgorithm,
+ tokenDescriptor.AdditionalHeaderClaims,
+ tokenDescriptor.AdditionalInnerHeaderClaims,
+ tokenDescriptor.TokenType);
}
///
@@ -327,7 +347,34 @@ public virtual string CreateToken(string payload, EncryptingCredentials encrypti
if (encryptingCredentials == null)
throw LogHelper.LogArgumentNullException(nameof(encryptingCredentials));
- return CreateTokenPrivate(JObject.Parse(payload), null, encryptingCredentials, null, null, null);
+ return CreateTokenPrivate(payload, null, encryptingCredentials, null, null, null, null);
+ }
+
+ ///
+ /// Creates a JWE (Json Web Encryption).
+ ///
+ /// A string containing JSON which represents the JWT token payload.
+ /// Defines the security key and algorithm that will be used to encrypt the JWT.
+ /// Defines the dictionary containing any custom header claims that need to be added to the outer JWT token header.
+ /// if is null.
+ /// if is null.
+ /// if is null.
+ /// if ,
+ /// , , and/or
+ /// are present inside of .
+ /// A JWS in Compact Serialization Format.
+ public virtual string CreateToken(string payload, EncryptingCredentials encryptingCredentials, IDictionary additionalHeaderClaims)
+ {
+ if (string.IsNullOrEmpty(payload))
+ throw LogHelper.LogArgumentNullException(nameof(payload));
+
+ if (encryptingCredentials == null)
+ throw LogHelper.LogArgumentNullException(nameof(encryptingCredentials));
+
+ if (additionalHeaderClaims == null)
+ throw LogHelper.LogArgumentNullException(nameof(additionalHeaderClaims));
+
+ return CreateTokenPrivate(payload, null, encryptingCredentials, null, additionalHeaderClaims, null, null);
}
///
@@ -351,7 +398,7 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
if (encryptingCredentials == null)
throw LogHelper.LogArgumentNullException(nameof(encryptingCredentials));
- return CreateTokenPrivate(JObject.Parse(payload), signingCredentials, encryptingCredentials, null, null, null);
+ return CreateTokenPrivate(payload, signingCredentials, encryptingCredentials, null, null, null, null);
}
///
@@ -369,7 +416,11 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
/// , , and/or
/// are present inside of .
/// A JWE in compact serialization format.
- public virtual string CreateToken(string payload, SigningCredentials signingCredentials, EncryptingCredentials encryptingCredentials, IDictionary additionalHeaderClaims)
+ public virtual string CreateToken(
+ string payload,
+ SigningCredentials signingCredentials,
+ EncryptingCredentials encryptingCredentials,
+ IDictionary additionalHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
throw LogHelper.LogArgumentNullException(nameof(payload));
@@ -383,7 +434,7 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
if (additionalHeaderClaims == null)
throw LogHelper.LogArgumentNullException(nameof(additionalHeaderClaims));
- return CreateTokenPrivate(JObject.Parse(payload), signingCredentials, encryptingCredentials, null, additionalHeaderClaims, null);
+ return CreateTokenPrivate(payload, signingCredentials, encryptingCredentials, null, additionalHeaderClaims, null, null);
}
///
@@ -404,7 +455,7 @@ public virtual string CreateToken(string payload, EncryptingCredentials encrypti
if (string.IsNullOrEmpty(compressionAlgorithm))
throw LogHelper.LogArgumentNullException(nameof(compressionAlgorithm));
- return CreateTokenPrivate(JObject.Parse(payload), null, encryptingCredentials, compressionAlgorithm, null, null);
+ return CreateTokenPrivate(payload, null, encryptingCredentials, compressionAlgorithm, null, null, null);
}
///
@@ -433,7 +484,61 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
if (string.IsNullOrEmpty(compressionAlgorithm))
throw LogHelper.LogArgumentNullException(nameof(compressionAlgorithm));
- return CreateTokenPrivate(JObject.Parse(payload), signingCredentials, encryptingCredentials, compressionAlgorithm, null, null);
+ return CreateTokenPrivate(payload, signingCredentials, encryptingCredentials, compressionAlgorithm, null, null, null);
+ }
+
+ ///
+ /// Creates a JWE (Json Web Encryption).
+ ///
+ /// A string containing JSON which represents the JWT token payload.
+ /// Defines the security key and algorithm that will be used to sign the JWT.
+ /// Defines the security key and algorithm that will be used to encrypt the JWT.
+ /// Defines the compression algorithm that will be used to compress the JWT token payload.
+ /// Defines the dictionary containing any custom header claims that need to be added to the outer JWT token header.
+ /// Defines the dictionary containing any custom header claims that need to be added to the inner JWT token header.
+ /// if is null.
+ /// if is null.
+ /// if is null.
+ /// if is null.
+ /// if is null.
+ /// if ,
+ /// , , and/or
+ /// are present inside of .
+ /// A JWE in compact serialization format.
+ public virtual string CreateToken(
+ string payload,
+ SigningCredentials signingCredentials,
+ EncryptingCredentials encryptingCredentials,
+ string compressionAlgorithm,
+ IDictionary additionalHeaderClaims,
+ IDictionary additionalInnerHeaderClaims)
+ {
+ if (string.IsNullOrEmpty(payload))
+ throw LogHelper.LogArgumentNullException(nameof(payload));
+
+ if (signingCredentials == null)
+ throw LogHelper.LogArgumentNullException(nameof(signingCredentials));
+
+ if (encryptingCredentials == null)
+ throw LogHelper.LogArgumentNullException(nameof(encryptingCredentials));
+
+ if (string.IsNullOrEmpty(compressionAlgorithm))
+ throw LogHelper.LogArgumentNullException(nameof(compressionAlgorithm));
+
+ if (additionalHeaderClaims == null)
+ throw LogHelper.LogArgumentNullException(nameof(additionalHeaderClaims));
+
+ if (additionalInnerHeaderClaims == null)
+ throw LogHelper.LogArgumentNullException(nameof(additionalInnerHeaderClaims));
+
+ return CreateTokenPrivate(
+ payload,
+ signingCredentials,
+ encryptingCredentials,
+ compressionAlgorithm,
+ additionalHeaderClaims,
+ additionalInnerHeaderClaims,
+ null);
}
///
@@ -453,7 +558,12 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
/// , , and/or
/// are present inside of .
/// A JWE in compact serialization format.
- public virtual string CreateToken(string payload, SigningCredentials signingCredentials, EncryptingCredentials encryptingCredentials, string compressionAlgorithm, IDictionary additionalHeaderClaims)
+ public virtual string CreateToken(
+ string payload,
+ SigningCredentials signingCredentials,
+ EncryptingCredentials encryptingCredentials,
+ string compressionAlgorithm,
+ IDictionary additionalHeaderClaims)
{
if (string.IsNullOrEmpty(payload))
throw LogHelper.LogArgumentNullException(nameof(payload));
@@ -470,40 +580,69 @@ public virtual string CreateToken(string payload, SigningCredentials signingCred
if (additionalHeaderClaims == null)
throw LogHelper.LogArgumentNullException(nameof(additionalHeaderClaims));
- return CreateTokenPrivate(JObject.Parse(payload), signingCredentials, encryptingCredentials, compressionAlgorithm, additionalHeaderClaims, null);
+ return CreateTokenPrivate(payload, signingCredentials, encryptingCredentials, compressionAlgorithm, additionalHeaderClaims, null, null);
}
- private string CreateTokenPrivate(JObject payload, SigningCredentials signingCredentials, EncryptingCredentials encryptingCredentials, string compressionAlgorithm, IDictionary additionalHeaderClaims, string tokenType)
+ private string CreateTokenPrivate(
+ string payload,
+ SigningCredentials signingCredentials,
+ EncryptingCredentials encryptingCredentials,
+ string compressionAlgorithm,
+ IDictionary additionalHeaderClaims,
+ IDictionary additionalInnerHeaderClaims,
+ string tokenType)
{
if (additionalHeaderClaims?.Count > 0 && additionalHeaderClaims.Keys.Intersect(JwtTokenUtilities.DefaultHeaderParameters, StringComparer.OrdinalIgnoreCase).Any())
throw LogHelper.LogExceptionMessage(new SecurityTokenException(LogHelper.FormatInvariant(LogMessages.IDX14116, LogHelper.MarkAsNonPII(nameof(additionalHeaderClaims)), LogHelper.MarkAsNonPII(string.Join(", ", JwtTokenUtilities.DefaultHeaderParameters)))));
+ if (additionalInnerHeaderClaims?.Count > 0 && additionalInnerHeaderClaims.Keys.Intersect(JwtTokenUtilities.DefaultHeaderParameters, StringComparer.OrdinalIgnoreCase).Any())
+ throw LogHelper.LogExceptionMessage(new SecurityTokenException(LogHelper.FormatInvariant(LogMessages.IDX14116, nameof(additionalInnerHeaderClaims), string.Join(", ", JwtTokenUtilities.DefaultHeaderParameters))));
+
var header = CreateDefaultJWSHeader(signingCredentials, tokenType);
if (encryptingCredentials == null && additionalHeaderClaims != null && additionalHeaderClaims.Count > 0)
header.Merge(JObject.FromObject(additionalHeaderClaims));
- var rawHeader = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(header.ToString(Formatting.None)));
+ if (additionalInnerHeaderClaims != null && additionalInnerHeaderClaims.Count > 0)
+ header.Merge(JObject.FromObject(additionalInnerHeaderClaims));
- if (SetDefaultTimesOnTokenCreation)
+ var rawHeader = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(header.ToString(Formatting.None)));
+ JObject jsonPayload = null;
+ try
{
- var now = EpochTime.GetIntDate(DateTime.UtcNow);
- if (!payload.TryGetValue(JwtRegisteredClaimNames.Exp, out _))
- payload.Add(JwtRegisteredClaimNames.Exp, now + TokenLifetimeInMinutes * 60);
+ if (SetDefaultTimesOnTokenCreation)
+ {
+ jsonPayload = JObject.Parse(payload);
+ if (jsonPayload != null)
+ {
+ var now = EpochTime.GetIntDate(DateTime.UtcNow);
+ if (!jsonPayload.TryGetValue(JwtRegisteredClaimNames.Exp, out _))
+ jsonPayload.Add(JwtRegisteredClaimNames.Exp, now + TokenLifetimeInMinutes * 60);
- if (!payload.TryGetValue(JwtRegisteredClaimNames.Iat, out _))
- payload.Add(JwtRegisteredClaimNames.Iat, now);
+ if (!jsonPayload.TryGetValue(JwtRegisteredClaimNames.Iat, out _))
+ jsonPayload.Add(JwtRegisteredClaimNames.Iat, now);
- if (!payload.TryGetValue(JwtRegisteredClaimNames.Nbf, out _))
- payload.Add(JwtRegisteredClaimNames.Nbf, now);
+ if (!jsonPayload.TryGetValue(JwtRegisteredClaimNames.Nbf, out _))
+ jsonPayload.Add(JwtRegisteredClaimNames.Nbf, now);
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ LogHelper.LogExceptionMessage(new SecurityTokenException(LogHelper.FormatInvariant(LogMessages.IDX14307, ex, payload)));
}
- var rawPayload = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(payload.ToString(Formatting.None)));
+ payload = jsonPayload != null ? jsonPayload.ToString(Formatting.None) : payload;
+ var rawPayload = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(payload));
var message = rawHeader + "." + rawPayload;
var rawSignature = signingCredentials == null ? string.Empty : JwtTokenUtilities.CreateEncodedSignature(message, signingCredentials);
if (encryptingCredentials != null)
+ {
+ additionalHeaderClaims = AddCtyClaimDefaultValue(additionalHeaderClaims, encryptingCredentials.SetDefaultCtyClaim);
+
return EncryptTokenPrivate(message + "." + rawSignature, encryptingCredentials, compressionAlgorithm, additionalHeaderClaims, tokenType);
+ }
return message + "." + rawSignature;
}
@@ -533,6 +672,13 @@ private static byte[] CompressToken(string token, string compressionAlgorithm)
return compressionProvider.Compress(Encoding.UTF8.GetBytes(token)) ?? throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(TokenLogMessages.IDX10680, LogHelper.MarkAsNonPII(compressionAlgorithm))));
}
+ private static StringComparison GetStringComparisonRuleIf509(SecurityKey securityKey) => (securityKey is X509SecurityKey)
+ ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+
+ private static StringComparison GetStringComparisonRuleIf509OrECDsa(SecurityKey securityKey) => (securityKey is X509SecurityKey
+ || securityKey is ECDsaSecurityKey)
+ ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+
///
/// Creates a from a .
///
@@ -755,7 +901,7 @@ private static string EncryptTokenPrivate(string innerJwt, EncryptingCredentials
throw LogHelper.LogExceptionMessage(new ArgumentException(TokenLogMessages.IDX10620));
byte[] wrappedKey = null;
- SecurityKey securityKey = JwtTokenUtilities.GetSecurityKey(encryptingCredentials, cryptoProviderFactory, out wrappedKey);
+ SecurityKey securityKey = JwtTokenUtilities.GetSecurityKey(encryptingCredentials, cryptoProviderFactory, additionalHeaderClaims, out wrappedKey);
using (var encryptionProvider = cryptoProviderFactory.CreateAuthenticatedEncryptionProvider(securityKey, encryptingCredentials.Enc))
{
@@ -763,7 +909,6 @@ private static string EncryptTokenPrivate(string innerJwt, EncryptingCredentials
throw LogHelper.LogExceptionMessage(new SecurityTokenEncryptionFailedException(LogMessages.IDX14103));
var header = CreateDefaultJWEHeader(encryptingCredentials, compressionAlgorithm, tokenType);
-
if (additionalHeaderClaims != null)
header.Merge(JObject.FromObject(additionalHeaderClaims));
@@ -788,7 +933,7 @@ private static string EncryptTokenPrivate(string innerJwt, EncryptingCredentials
{
var rawHeader = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(header.ToString(Formatting.None)));
var encryptionResult = encryptionProvider.Encrypt(plainText, Encoding.ASCII.GetBytes(rawHeader));
- return JwtConstants.DirectKeyUseAlg.Equals(encryptingCredentials.Alg, StringComparison.Ordinal) ?
+ return JwtConstants.DirectKeyUseAlg.Equals(encryptingCredentials.Alg) ?
string.Join(".", rawHeader, string.Empty, Base64UrlEncoder.Encode(encryptionResult.IV), Base64UrlEncoder.Encode(encryptionResult.Ciphertext), Base64UrlEncoder.Encode(encryptionResult.AuthenticationTag)):
string.Join(".", rawHeader, Base64UrlEncoder.Encode(wrappedKey), Base64UrlEncoder.Encode(encryptionResult.IV), Base64UrlEncoder.Encode(encryptionResult.Ciphertext), Base64UrlEncoder.Encode(encryptionResult.AuthenticationTag));
}
@@ -812,6 +957,9 @@ internal IEnumerable GetContentEncryptionKeys(JsonWebToken jwtToken
keys = new List { key };
}
+ // on decryption for ECDH-ES, we get the public key from the EPK value see: https://datatracker.ietf.org/doc/html/rfc7518#appendix-C
+ // we need the ECDSASecurityKey for the receiver, use TokenValidationParameters.TokenDecryptionKey
+
// control gets here if:
// 1. User specified delegate: TokenDecryptionKeyResolver returned null
// 2. ResolveTokenDecryptionKey returned null
@@ -819,7 +967,8 @@ internal IEnumerable GetContentEncryptionKeys(JsonWebToken jwtToken
if (keys == null)
keys = JwtTokenUtilities.GetAllDecryptionKeys(validationParameters);
- if (jwtToken.Alg.Equals(JwtConstants.DirectKeyUseAlg, StringComparison.Ordinal))
+ if (jwtToken.Alg.Equals(JwtConstants.DirectKeyUseAlg, StringComparison.Ordinal)
+ || jwtToken.Alg.Equals(SecurityAlgorithms.EcdhEs, StringComparison.Ordinal))
return keys;
var unwrappedKeys = new List();
@@ -830,6 +979,24 @@ internal IEnumerable GetContentEncryptionKeys(JsonWebToken jwtToken
{
try
{
+#if NET472 || NET6_0
+ if (SupportedAlgorithms.EcdsaWrapAlgorithms.Contains(jwtToken.Alg))
+ {
+ //// on decryption we get the public key from the EPK value see: https://datatracker.ietf.org/doc/html/rfc7518#appendix-C
+ var ecdhKeyExchangeProvider = new EcdhKeyExchangeProvider(
+ key as ECDsaSecurityKey,
+ validationParameters.TokenDecryptionKey as ECDsaSecurityKey,
+ jwtToken.Alg,
+ jwtToken.Enc);
+ jwtToken.TryGetHeaderValue(JwtHeaderParameterNames.Apu, out string apu);
+ jwtToken.TryGetHeaderValue(JwtHeaderParameterNames.Apv, out string apv);
+ SecurityKey kdf = ecdhKeyExchangeProvider.GenerateKdf(apu, apv);
+ var kwp = key.CryptoProviderFactory.CreateKeyWrapProviderForUnwrap(kdf, ecdhKeyExchangeProvider.GetEncryptionAlgorithm());
+ var unwrappedKey = kwp.UnwrapKey(Base64UrlEncoder.DecodeBytes(jwtToken.EncryptedKey));
+ unwrappedKeys.Add(new SymmetricSecurityKey(unwrappedKey));
+ }
+ else
+#endif
if (key.CryptoProviderFactory.IsSupportedAlgorithm(jwtToken.Alg, key))
{
var kwp = key.CryptoProviderFactory.CreateKeyWrapProviderForUnwrap(key, jwtToken.Alg);
@@ -866,17 +1033,18 @@ protected virtual SecurityKey ResolveTokenDecryptionKey(string token, JsonWebTok
if (validationParameters == null)
throw LogHelper.LogArgumentNullException(nameof(validationParameters));
+ StringComparison stringComparison = GetStringComparisonRuleIf509OrECDsa(validationParameters.TokenDecryptionKey);
if (!string.IsNullOrEmpty(jwtToken.Kid))
{
if (validationParameters.TokenDecryptionKey != null
- && string.Equals(validationParameters.TokenDecryptionKey.KeyId, jwtToken.Kid, validationParameters.TokenDecryptionKey is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
+ && string.Equals(validationParameters.TokenDecryptionKey.KeyId, jwtToken.Kid, stringComparison))
return validationParameters.TokenDecryptionKey;
if (validationParameters.TokenDecryptionKeys != null)
{
foreach (var key in validationParameters.TokenDecryptionKeys)
{
- if (key != null && string.Equals(key.KeyId, jwtToken.Kid, key is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
+ if (key != null && string.Equals(key.KeyId, jwtToken.Kid, GetStringComparisonRuleIf509OrECDsa(key)))
return key;
}
}
@@ -886,7 +1054,7 @@ protected virtual SecurityKey ResolveTokenDecryptionKey(string token, JsonWebTok
{
if (validationParameters.TokenDecryptionKey != null)
{
- if (string.Equals(validationParameters.TokenDecryptionKey.KeyId, jwtToken.X5t, validationParameters.TokenDecryptionKey is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
+ if (string.Equals(validationParameters.TokenDecryptionKey.KeyId, jwtToken.X5t, stringComparison))
return validationParameters.TokenDecryptionKey;
var x509Key = validationParameters.TokenDecryptionKey as X509SecurityKey;
@@ -898,7 +1066,7 @@ protected virtual SecurityKey ResolveTokenDecryptionKey(string token, JsonWebTok
{
foreach (var key in validationParameters.TokenDecryptionKeys)
{
- if (key != null && string.Equals(key.KeyId, jwtToken.X5t, key is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
+ if (key != null && string.Equals(key.KeyId, jwtToken.X5t, GetStringComparisonRuleIf509(key)))
return key;
var x509Key = key as X509SecurityKey;
@@ -907,6 +1075,7 @@ protected virtual SecurityKey ResolveTokenDecryptionKey(string token, JsonWebTok
}
}
}
+
return null;
}
@@ -1058,7 +1227,7 @@ private async Task ValidateTokenAsync(string token, JsonW
// Only try to re-validate using the newly obtained config if it doesn't reference equal the previously used configuration.
if (lastConfig != currentConfiguration)
- return decryptedJwt != null ? ValidateJWE(outerToken, decryptedJwt, validationParameters, currentConfiguration) : ValidateJWS(token, validationParameters, currentConfiguration); ;
+ return decryptedJwt != null ? ValidateJWE(outerToken, decryptedJwt, validationParameters, currentConfiguration) : ValidateJWS(token, validationParameters, currentConfiguration);
}
}
}
@@ -1285,7 +1454,7 @@ private static JsonWebToken ValidateSignature(string token, TokenValidationParam
{
if (kidMatched)
{
- var isKidInTVP = keysInTokenValidationParameters.Any(x => x.KeyId.Equals(jwtToken.Kid, StringComparison.Ordinal));
+ var isKidInTVP = keysInTokenValidationParameters.Any(x => x.KeyId.Equals(jwtToken.Kid));
var keyLocation = isKidInTVP ? "TokenValidationParameters" : "Configuration";
throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(
LogHelper.FormatInvariant(TokenLogMessages.IDX10511,
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JwtHeaderParameterNames.cs b/src/Microsoft.IdentityModel.JsonWebTokens/JwtHeaderParameterNames.cs
index 01f58b747d..f23f335540 100644
--- a/src/Microsoft.IdentityModel.JsonWebTokens/JwtHeaderParameterNames.cs
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/JwtHeaderParameterNames.cs
@@ -93,5 +93,20 @@ public struct JwtHeaderParameterNames
/// See: https://datatracker.ietf.org/doc/html/rfc7516#section-4.1.3
///
public const string Zip = "zip";
+
+ ///
+ /// See: https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.1.1
+ ///
+ public const string Epk = "epk";
+
+ ///
+ /// See: https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.1.2
+ ///
+ public const string Apu = "apu";
+
+ ///
+ /// See: https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.1.3
+ ///
+ public const string Apv = "apv";
}
}
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs b/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs
index 7bb0d94b3f..4213b415a9 100644
--- a/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs
@@ -49,7 +49,7 @@ public class JwtTokenUtilities
/// Regex that is used to figure out if a token is in JWS format.
///
public static Regex RegexJws = new Regex(JwtConstants.JsonCompactSerializationRegex, RegexOptions.Compiled | RegexOptions.CultureInvariant, TimeSpan.FromMilliseconds(100));
-
+
///
/// Regex that is used to figure out if a token is in JWE format.
///
@@ -200,6 +200,10 @@ internal static string DecryptJwtToken(
{
Validators.ValidateAlgorithm(decryptionParameters.Enc, key, jwtToken, validationParameters);
decryptedTokenBytes = DecryptToken(cryptoProviderFactory, key, decryptionParameters);
+ X509SecurityKey x509Key = key as X509SecurityKey;
+ if (x509Key != null)
+ LogHelper.LogInformation(TokenLogMessages.IDX10903, x509Key.Certificate?.Thumbprint);
+
decryptionSucceeded = true;
break;
}
@@ -278,32 +282,68 @@ public static byte[] GenerateKeyBytes(int sizeInBits)
return key;
}
- internal static SecurityKey GetSecurityKey(EncryptingCredentials encryptingCredentials, CryptoProviderFactory cryptoProviderFactory, out byte[] wrappedKey)
+ internal static SecurityKey GetSecurityKey(
+ EncryptingCredentials encryptingCredentials,
+ CryptoProviderFactory cryptoProviderFactory,
+ IDictionary additionalHeaderClaims,
+ out byte[] wrappedKey)
{
SecurityKey securityKey = null;
KeyWrapProvider kwProvider = null;
wrappedKey = null;
// if direct algorithm, look for support
- if (JwtConstants.DirectKeyUseAlg.Equals(encryptingCredentials.Alg, StringComparison.Ordinal))
+ if (JwtConstants.DirectKeyUseAlg.Equals(encryptingCredentials.Alg))
{
if (!cryptoProviderFactory.IsSupportedAlgorithm(encryptingCredentials.Enc, encryptingCredentials.Key))
throw LogHelper.LogExceptionMessage(new SecurityTokenEncryptionFailedException(LogHelper.FormatInvariant(TokenLogMessages.IDX10615, LogHelper.MarkAsNonPII(encryptingCredentials.Enc), encryptingCredentials.Key)));
securityKey = encryptingCredentials.Key;
}
+#if NET472 || NET6_0
+ else if (SupportedAlgorithms.EcdsaWrapAlgorithms.Contains(encryptingCredentials.Alg))
+ {
+ // on decryption we get the public key from the EPK value see: https://datatracker.ietf.org/doc/html/rfc7518#appendix-C
+ string apu = null, apv = null;
+ if (additionalHeaderClaims != null && additionalHeaderClaims.Count > 0)
+ {
+ if (additionalHeaderClaims.TryGetValue(JwtHeaderParameterNames.Apu, out object objApu))
+ apu = objApu?.ToString();
+
+ if (additionalHeaderClaims.TryGetValue(JwtHeaderParameterNames.Apv, out object objApv))
+ apv = objApv?.ToString();
+ }
+
+ EcdhKeyExchangeProvider ecdhKeyExchangeProvider = new EcdhKeyExchangeProvider(encryptingCredentials.Key as ECDsaSecurityKey, encryptingCredentials.KeyExchangePublicKey, encryptingCredentials.Alg, encryptingCredentials.Enc);
+ SecurityKey kdf = ecdhKeyExchangeProvider.GenerateKdf(apu, apv);
+ kwProvider = cryptoProviderFactory.CreateKeyWrapProvider(kdf, ecdhKeyExchangeProvider.GetEncryptionAlgorithm());
+
+ // only 128, 384 and 512 AesKeyWrap for CEK algorithm
+ if (SecurityAlgorithms.Aes128KW.Equals(kwProvider.Algorithm, StringComparison.Ordinal))
+ securityKey = new SymmetricSecurityKey(GenerateKeyBytes(256));
+ else if (SecurityAlgorithms.Aes192KW.Equals(kwProvider.Algorithm, StringComparison.Ordinal))
+ securityKey = new SymmetricSecurityKey(GenerateKeyBytes(384));
+ else if (SecurityAlgorithms.Aes256KW.Equals(kwProvider.Algorithm, StringComparison.Ordinal))
+ securityKey = new SymmetricSecurityKey(GenerateKeyBytes(512));
+ else
+ throw LogHelper.LogExceptionMessage(
+ new SecurityTokenEncryptionFailedException(LogHelper.FormatInvariant(TokenLogMessages.IDX10617, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes128KW), LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes192KW), LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes256KW), LogHelper.MarkAsNonPII(kwProvider.Algorithm))));
+
+ wrappedKey = kwProvider.WrapKey(((SymmetricSecurityKey)securityKey).Key);
+ }
+#endif
else
{
if (!cryptoProviderFactory.IsSupportedAlgorithm(encryptingCredentials.Alg, encryptingCredentials.Key))
throw LogHelper.LogExceptionMessage(new SecurityTokenEncryptionFailedException(LogHelper.FormatInvariant(TokenLogMessages.IDX10615, LogHelper.MarkAsNonPII(encryptingCredentials.Alg), encryptingCredentials.Key)));
// only 128, 384 and 512 AesCbcHmac for CEK algorithm
- if (SecurityAlgorithms.Aes128CbcHmacSha256.Equals(encryptingCredentials.Enc, StringComparison.Ordinal))
- securityKey = new SymmetricSecurityKey(JwtTokenUtilities.GenerateKeyBytes(256));
- else if (SecurityAlgorithms.Aes192CbcHmacSha384.Equals(encryptingCredentials.Enc, StringComparison.Ordinal))
- securityKey = new SymmetricSecurityKey(JwtTokenUtilities.GenerateKeyBytes(384));
- else if (SecurityAlgorithms.Aes256CbcHmacSha512.Equals(encryptingCredentials.Enc, StringComparison.Ordinal))
- securityKey = new SymmetricSecurityKey(JwtTokenUtilities.GenerateKeyBytes(512));
+ if (SecurityAlgorithms.Aes128CbcHmacSha256.Equals(encryptingCredentials.Enc))
+ securityKey = new SymmetricSecurityKey(GenerateKeyBytes(256));
+ else if (SecurityAlgorithms.Aes192CbcHmacSha384.Equals(encryptingCredentials.Enc))
+ securityKey = new SymmetricSecurityKey(GenerateKeyBytes(384));
+ else if (SecurityAlgorithms.Aes256CbcHmacSha512.Equals(encryptingCredentials.Enc))
+ securityKey = new SymmetricSecurityKey(GenerateKeyBytes(512));
else
throw LogHelper.LogExceptionMessage(
new SecurityTokenEncryptionFailedException(LogHelper.FormatInvariant(TokenLogMessages.IDX10617, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes128CbcHmacSha256), LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes192CbcHmacSha384), LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes256CbcHmacSha512), LogHelper.MarkAsNonPII(encryptingCredentials.Enc))));
@@ -401,7 +441,7 @@ internal static SecurityKey ResolveTokenSigningKey(string kid, string x5t, Token
{
foreach (SecurityKey signingKey in configuration.SigningKeys)
{
- if (signingKey != null && string.Equals(signingKey.KeyId, x5t, StringComparison.Ordinal))
+ if (signingKey != null && string.Equals(signingKey.KeyId, x5t))
return signingKey;
}
}
@@ -420,7 +460,7 @@ internal static SecurityKey ResolveTokenSigningKey(string kid, string x5t, Token
internal static SecurityKey ResolveTokenSigningKey(string kid, string x5t, TokenValidationParameters validationParameters)
{
if (!string.IsNullOrEmpty(kid))
- {
+ {
if (validationParameters.IssuerSigningKey != null
&& string.Equals(validationParameters.IssuerSigningKey.KeyId, kid, validationParameters.IssuerSigningKey is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
return validationParameters.IssuerSigningKey;
@@ -453,7 +493,7 @@ internal static SecurityKey ResolveTokenSigningKey(string kid, string x5t, Token
{
foreach (SecurityKey signingKey in validationParameters.IssuerSigningKeys)
{
- if (signingKey != null && string.Equals(signingKey.KeyId, x5t, StringComparison.Ordinal))
+ if (signingKey != null && string.Equals(signingKey.KeyId, x5t))
{
return signingKey;
}
diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/LogMessages.cs b/src/Microsoft.IdentityModel.JsonWebTokens/LogMessages.cs
index 9862078d70..04293daf8e 100644
--- a/src/Microsoft.IdentityModel.JsonWebTokens/LogMessages.cs
+++ b/src/Microsoft.IdentityModel.JsonWebTokens/LogMessages.cs
@@ -46,7 +46,7 @@ internal static class LogMessages
internal const string IDX14102 = "IDX14102: Unable to decode the header '{0}' as Base64Url encoded string. jwtEncodedString: '{1}'.";
internal const string IDX14103 = "IDX14103: Failed to create the token encryption provider.";
internal const string IDX14105 = "IDX14105: Header.Cty != null, assuming JWS. Cty: '{0}'.";
- internal const string IDX14106 = "IDX14106: Decoding token: '{0}' into header, payload and signature.";
+ // internal const string IDX14106 = "IDX14106:";
internal const string IDX14107 = "IDX14107: Token string does not match the token formats: JWE (header.encryptedKey.iv.ciphertext.tag) or JWS (header.payload.signature)";
internal const string IDX14111 = "IDX14111: JWT: '{0}' must have three segments (JWS) or five segments (JWE).";
internal const string IDX14112 = "IDX14112: Only a single 'Actor' is supported. Found second claim of type: '{0}', value: '{1}'";
@@ -67,6 +67,7 @@ internal static class LogMessages
internal const string IDX14304 = "IDX14304: Claim with name '{0}' does not exist in the payload.";
internal const string IDX14305 = "IDX14305: Unable to convert the '{0}' claim to the following type: '{1}'. Claim type was: '{2}'.";
internal const string IDX14306 = "IDX14306: JWE Ciphertext cannot be an empty string.";
+ internal const string IDX14307 = "IDX14307: An exception has been caught while parsing the payload. Exception: {0}, Payload: {1}";
#pragma warning restore 1591
}
}
diff --git a/src/Microsoft.IdentityModel.KeyVaultExtensions/Microsoft.IdentityModel.KeyVaultExtensions.csproj b/src/Microsoft.IdentityModel.KeyVaultExtensions/Microsoft.IdentityModel.KeyVaultExtensions.csproj
index ffad76f767..79dfe9e428 100644
--- a/src/Microsoft.IdentityModel.KeyVaultExtensions/Microsoft.IdentityModel.KeyVaultExtensions.csproj
+++ b/src/Microsoft.IdentityModel.KeyVaultExtensions/Microsoft.IdentityModel.KeyVaultExtensions.csproj
@@ -8,8 +8,8 @@
true
latest
Microsoft.IdentityModel.KeyVaultExtensions
- net452;netstandard2.0
- netstandard2.0
+ net452;netstandard2.0;net6.0
+ netstandard2.0;net6.0
.NET;Windows;Authentication;Identity;Azure;Key;Vault;Extensions
@@ -24,6 +24,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs
index c544c4d70c..dbc50a6607 100644
--- a/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs
@@ -7,3 +7,4 @@
[assembly: SuppressMessage("Design", "CA1052:Static holder types should be Static or NotInheritable", Justification = "Previously released as non-static / inheritable", Scope = "type", Target = "~T:Microsoft.IdentityModel.Logging.LogHelper")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Execution should not be altered for exceptions on format", Scope = "member", Target = "~M:Microsoft.IdentityModel.Logging.IdentityModelEventSource.PrepareMessage(System.Diagnostics.Tracing.EventLevel,System.String,System.Object[])~System.String")]
+[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Logging.LoggerContext.PropertyBag")]
diff --git a/src/Microsoft.IdentityModel.Logging/IdentityModelTelemetryUtil.cs b/src/Microsoft.IdentityModel.Logging/IdentityModelTelemetryUtil.cs
index 04fca859cf..ac07417efc 100644
--- a/src/Microsoft.IdentityModel.Logging/IdentityModelTelemetryUtil.cs
+++ b/src/Microsoft.IdentityModel.Logging/IdentityModelTelemetryUtil.cs
@@ -59,6 +59,8 @@ public static class IdentityModelTelemetryUtil
"ID_NET472";
#elif NETSTANDARD2_0
"ID_NETSTANDARD2_0";
+#elif NET6_0
+ "ID_NET6_0";
#endif
///
diff --git a/src/Microsoft.IdentityModel.Logging/LogHelper.cs b/src/Microsoft.IdentityModel.Logging/LogHelper.cs
index 474e5a1434..ef0af25ba2 100644
--- a/src/Microsoft.IdentityModel.Logging/LogHelper.cs
+++ b/src/Microsoft.IdentityModel.Logging/LogHelper.cs
@@ -29,6 +29,7 @@
using System.Diagnostics.Tracing;
using System.Globalization;
using System.Linq;
+using Microsoft.IdentityModel.Abstractions;
namespace Microsoft.IdentityModel.Logging
{
@@ -37,6 +38,26 @@ namespace Microsoft.IdentityModel.Logging
///
public class LogHelper
{
+ ///
+ /// Gets or sets a logger to which logs will be written to.
+ ///
+ public static IIdentityLogger Logger { get; set; } = NullIdentityModelLogger.Instance;
+
+ ///
+ /// Indicates whether the log message header (contains library version, date/time, and PII debugging information) has been written.
+ ///
+ private static bool _isHeaderWritten = false;
+
+ ///
+ /// The log message that is shown when PII is off.
+ ///
+ private static string _piiOffLogMessage = "PII logging is OFF. See https://aka.ms/IdentityModel/PII for details. ";
+
+ ///
+ /// The log message that is shown when PII is on.
+ ///
+ private static string _piiOnLogMessage = "PII logging is ON, do not use in production. See https://aka.ms/IdentityModel/PII for details. ";
+
///
/// Logs an exception using the event source logger and returns new exception.
///
@@ -44,7 +65,7 @@ public class LogHelper
/// EventLevel is set to Error.
public static ArgumentNullException LogArgumentNullException(string argument)
{
- return LogArgumentException(EventLevel.Error, argument, "IDX10000: The parameter '{0}' cannot be a 'null' or an empty object.", argument);
+ return LogArgumentException(EventLevel.Error, argument, "IDX10000: The parameter '{0}' cannot be a 'null' or an empty object. ", argument);
}
///
@@ -254,6 +275,10 @@ public static Exception LogExceptionMessage(EventLevel eventLevel, Exception exc
if (IdentityModelEventSource.Logger.IsEnabled() && IdentityModelEventSource.Logger.LogLevel >= eventLevel)
IdentityModelEventSource.Logger.Write(eventLevel, exception.InnerException, exception.Message);
+ EventLogLevel eventLogLevel = Enum.IsDefined(typeof(EventLogLevel), (int)eventLevel) ? (EventLogLevel)eventLevel : EventLogLevel.Error;
+ if (Logger.IsEnabled(eventLogLevel))
+ Logger.Log(WriteEntry((EventLogLevel)eventLevel, exception.InnerException, exception.Message, null));
+
return exception;
}
@@ -264,8 +289,11 @@ public static Exception LogExceptionMessage(EventLevel eventLevel, Exception exc
/// An object array that contains zero or more objects to format.
public static void LogInformation(string message, params object[] args)
{
- if (IdentityModelEventSource.Logger.IsEnabled())
+ if (IdentityModelEventSource.Logger.IsEnabled() && IdentityModelEventSource.Logger.LogLevel >= EventLevel.Informational)
IdentityModelEventSource.Logger.WriteInformation(message, args);
+
+ if (Enum.IsDefined(typeof(EventLogLevel), (int)EventLevel.Informational) && Logger.IsEnabled((EventLogLevel)EventLevel.Informational))
+ Logger.Log(WriteEntry((EventLogLevel)EventLevel.Informational, null, message, args));
}
///
@@ -277,6 +305,9 @@ public static void LogVerbose(string message, params object[] args)
{
if (IdentityModelEventSource.Logger.IsEnabled())
IdentityModelEventSource.Logger.WriteVerbose(message, args);
+
+ if (Enum.IsDefined(typeof(EventLogLevel), (int)EventLevel.Verbose) && Logger.IsEnabled((EventLogLevel)EventLevel.Verbose))
+ Logger.Log(WriteEntry((EventLogLevel)EventLevel.Verbose, null, message, args));
}
///
@@ -288,6 +319,9 @@ public static void LogWarning(string message, params object[] args)
{
if (IdentityModelEventSource.Logger.IsEnabled())
IdentityModelEventSource.Logger.WriteWarning(message, args);
+
+ if (Enum.IsDefined(typeof(EventLogLevel), (int)EventLevel.Warning) && Logger.IsEnabled((EventLogLevel)EventLevel.Warning))
+ Logger.Log(WriteEntry((EventLogLevel)EventLevel.Warning, null, message, args));
}
///
@@ -310,6 +344,10 @@ private static T LogExceptionImpl(EventLevel eventLevel, string argumentName,
if (IdentityModelEventSource.Logger.IsEnabled() && IdentityModelEventSource.Logger.LogLevel >= eventLevel)
IdentityModelEventSource.Logger.Write(eventLevel, innerException, message);
+ EventLogLevel eventLogLevel = Enum.IsDefined(typeof(EventLogLevel), (int)eventLevel) ? (EventLogLevel)eventLevel : EventLogLevel.Error;
+ if (Logger.IsEnabled(eventLogLevel))
+ Logger.Log(WriteEntry((EventLogLevel)eventLevel, innerException, message, null));
+
if (innerException != null)
if (string.IsNullOrEmpty(argumentName))
return (T)Activator.CreateInstance(typeof(T), message, innerException);
@@ -371,5 +409,53 @@ public static object MarkAsNonPII(object arg)
{
return new NonPII(arg);
}
+
+ ///
+ /// Creates a by using the provided event level, exception argument, string argument and arguments list.
+ ///
+ ///
+ ///
+ /// The log message.
+ /// An object array that contains zero or more objects to format.
+ private static LogEntry WriteEntry(EventLogLevel eventLogLevel, Exception innerException, string message, params object[] args)
+ {
+ if (string.IsNullOrEmpty(message))
+ return null;
+
+ if (innerException != null)
+ {
+ // if PII is turned off and 'innerException' is a System exception only display the exception type
+ if (!IdentityModelEventSource.ShowPII && !LogHelper.IsCustomException(innerException))
+ message = string.Format(CultureInfo.InvariantCulture, "Message: {0}, InnerException: {1}. ", message, innerException.GetType());
+ else // otherwise it's safe to display the entire exception message
+ message = string.Format(CultureInfo.InvariantCulture, "Message: {0}, InnerException: {1}. ", message, innerException.Message);
+ }
+
+ message = args == null ? message : FormatInvariant(message, args);
+
+ // Logs basic information (library version, DateTime, whether PII is ON/OFF) once before any log messages are written.
+ if (!_isHeaderWritten)
+ {
+ string headerMessage = string.Format(
+ CultureInfo.InvariantCulture,
+ "Microsoft.IdentityModel Version: {0}. Date {1}. {2}",
+ typeof(IdentityModelEventSource).Assembly.GetName().Version.ToString(),
+ DateTime.UtcNow,
+ IdentityModelEventSource.ShowPII ? _piiOnLogMessage : _piiOffLogMessage);
+
+ LogEntry headerEntry = new LogEntry();
+ headerEntry.EventLogLevel = EventLogLevel.LogAlways;
+ headerEntry.Message = headerMessage;
+ Logger.Log(headerEntry);
+
+ _isHeaderWritten = true;
+ }
+
+ LogEntry entry = new LogEntry();
+ entry.EventLogLevel = eventLogLevel;
+ entry.Message = message;
+
+ return entry;
+ }
}
}
diff --git a/src/Microsoft.IdentityModel.Logging/LoggerContext.cs b/src/Microsoft.IdentityModel.Logging/LoggerContext.cs
new file mode 100644
index 0000000000..24d015e1a2
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Logging/LoggerContext.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Microsoft.IdentityModel.Logging
+{
+ ///
+ /// A context class that can be used to store work per request to aid with debugging.
+ ///
+ public class LoggerContext
+ {
+ ///
+ /// Instantiates a new with the default activityId.
+ ///
+ public LoggerContext()
+ {
+ }
+
+ ///
+ /// Instantiates a new with an activityId.
+ ///
+ ///
+ public LoggerContext(Guid activityId)
+ {
+ ActivityId = activityId;
+ }
+
+ ///
+ /// Gets or set a that will be used in the call to EventSource.SetCurrentThreadActivityId before logging.
+ ///
+ public Guid ActivityId { get; set; } = Guid.Empty;
+
+ ///
+ /// Gets or sets a boolean controlling if logs are written into the context.
+ /// Useful when debugging.
+ ///
+ public bool CaptureLogs { get; set; } = false;
+
+ ///
+ /// Gets or sets a string that helps with setting breakpoints when debugging.
+ ///
+ public virtual string DebugId { get; set; } = string.Empty;
+
+ ///
+ /// The collection of logs associated with a request. Use to control capture.
+ ///
+ public ICollection Logs { get; private set; } = new Collection();
+
+ ///
+ /// Gets or sets an that enables custom extensibility scenarios.
+ ///
+ public IDictionary PropertyBag { get; set; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Logging/Microsoft.IdentityModel.Logging.csproj b/src/Microsoft.IdentityModel.Logging/Microsoft.IdentityModel.Logging.csproj
index 5c9a54d36a..7d92669e5d 100644
--- a/src/Microsoft.IdentityModel.Logging/Microsoft.IdentityModel.Logging.csproj
+++ b/src/Microsoft.IdentityModel.Logging/Microsoft.IdentityModel.Logging.csproj
@@ -26,4 +26,8 @@
+
+
+
+
diff --git a/src/Microsoft.IdentityModel.LoggingExtensions/IdentityLoggerAdapter.cs b/src/Microsoft.IdentityModel.LoggingExtensions/IdentityLoggerAdapter.cs
new file mode 100644
index 0000000000..229d82ea09
--- /dev/null
+++ b/src/Microsoft.IdentityModel.LoggingExtensions/IdentityLoggerAdapter.cs
@@ -0,0 +1,116 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using Microsoft.Extensions.Logging;
+using Microsoft.IdentityModel.Abstractions;
+
+namespace Microsoft.IdentityModel.LoggingExtensions
+{
+ ///
+ /// The default implementation of that provides a wrapper around instance.
+ ///
+ public class IdentityLoggerAdapter : IIdentityLogger
+ {
+ private readonly ILogger _logger;
+
+ ///
+ /// Instantiates using .
+ ///
+ /// An instance to which identity log messages are written.
+
+#pragma warning disable CS3001 // Argument type is not CLS-compliant
+ public IdentityLoggerAdapter(ILogger logger)
+#pragma warning restore CS3001 // Argument type is not CLS-compliant
+ {
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ }
+
+ ///
+ public bool IsEnabled(EventLogLevel eventLogLevel)
+ {
+ return _logger.IsEnabled(ConvertToLogLevel(eventLogLevel));
+ }
+
+ ///
+ public void Log(LogEntry entry)
+ {
+ if (entry != null)
+ {
+ switch (entry.EventLogLevel)
+ {
+ case EventLogLevel.Critical:
+ case EventLogLevel.LogAlways:
+ _logger.LogCritical(entry.Message);
+ break;
+
+ case EventLogLevel.Error:
+ _logger.LogError(entry.Message);
+ break;
+
+ case EventLogLevel.Warning:
+ _logger.LogWarning(entry.Message);
+ break;
+
+ case EventLogLevel.Informational:
+ _logger.LogInformation(entry.Message);
+ break;
+
+ case EventLogLevel.Verbose:
+ _logger.LogDebug(entry.Message);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ private static LogLevel ConvertToLogLevel(EventLogLevel eventLogLevel)
+ {
+ switch (eventLogLevel)
+ {
+ case EventLogLevel.Critical:
+ case EventLogLevel.LogAlways:
+ return LogLevel.Critical;
+
+ case EventLogLevel.Error:
+ return LogLevel.Error;
+
+ case EventLogLevel.Warning:
+ return LogLevel.Warning;
+
+ case EventLogLevel.Informational:
+ return LogLevel.Information;
+
+ case EventLogLevel.Verbose:
+ default:
+ return LogLevel.Debug;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.LoggingExtensions/Microsoft.IdentityModel.LoggingExtensions.csproj b/src/Microsoft.IdentityModel.LoggingExtensions/Microsoft.IdentityModel.LoggingExtensions.csproj
new file mode 100644
index 0000000000..81381568c4
--- /dev/null
+++ b/src/Microsoft.IdentityModel.LoggingExtensions/Microsoft.IdentityModel.LoggingExtensions.csproj
@@ -0,0 +1,34 @@
+
+
+
+
+
+ Microsoft.IdentityModel.LoggingExtensions
+ A package containing logging extensions to support writing Identity logs to Microsoft.Extensions.Logging.ILogger.
+ true
+ Microsoft.IdentityModel.LoggingExtensions
+ .NET;Windows;Authentication;Identity;Extensions;Logging
+ netstandard2.0
+
+
+
+ full
+ true
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Microsoft.IdentityModel.LoggingExtensions/Properties/AssemblyInfo.cs b/src/Microsoft.IdentityModel.LoggingExtensions/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..2743e6bc85
--- /dev/null
+++ b/src/Microsoft.IdentityModel.LoggingExtensions/Properties/AssemblyInfo.cs
@@ -0,0 +1,37 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyInformationalVersion("0.0.1")]
+[assembly: AssemblyFileVersion("0.0.1")]
+[assembly: AssemblyMetadata("Serviceable", "True")]
+[assembly: AssemblyVersion("0.0.1")]
+[assembly: CLSCompliant(true)]
+[assembly: ComVisible(false)]
diff --git a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj b/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj
index 70dfa95498..8ae7733056 100644
--- a/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj
+++ b/src/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey/Microsoft.IdentityModel.ManagedKeyVaultSecurityKey.csproj
@@ -26,6 +26,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/GlobalSuppressions.cs
index 1a18c024a7..332d530766 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/GlobalSuppressions.cs
@@ -18,3 +18,4 @@
[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Previously released as non-static", Scope = "member", Target = "~M:Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration.ShouldSerializeSigningKeys~System.Boolean")]
[assembly: SuppressMessage("Design", "CA1033:Interface methods should be callable by child types", Justification = "Previously released as explicit implementation", Scope = "member", Target = "~M:Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.Microsoft#IdentityModel#Protocols#IConfigurationRetriever#GetConfigurationAsync(System.String,Microsoft.IdentityModel.Protocols.IDocumentRetriever,System.Threading.CancellationToken)~System.Threading.Tasks.Task{Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration}")]
[assembly: SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Normalized only for display", Scope = "member", Target = "~M:Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolValidator.ValidateIdToken(Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolValidationContext)")]
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Vendored component", Scope = "module")]
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/LogMessages.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/LogMessages.cs
index d0fa487ae9..bb5fc9974e 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/LogMessages.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/LogMessages.cs
@@ -49,7 +49,7 @@ internal static class LogMessages
internal const string IDX21305 = "IDX21305: OpenIdConnectProtocolValidationContext.ProtocolMessage.Code is null, there is no 'code' in the OpenIdConnect Response to validate.";
internal const string IDX21306 = "IDX21306: The 'c_hash' claim was not a string in the 'id_token', but a 'code' was in the OpenIdConnectMessage, 'id_token': '{0}'.";
internal const string IDX21307 = "IDX21307: The 'c_hash' claim was not found in the id_token, but a 'code' was in the OpenIdConnectMessage, id_token: '{0}'";
- internal const string IDX21308 = "IDX21308: 'Azp' claim exists in the 'id_token' but 'ciient_id' is null. Cannot validate the 'azp' claim.";
+ internal const string IDX21308 = "IDX21308: 'azp' claim exists in the 'id_token' but 'client_id' is null. Cannot validate the 'azp' claim.";
internal const string IDX21309 = "IDX21309: Validating 'at_hash' using id_token and access_token.";
internal const string IDX21310 = "IDX21310: OpenIdConnectProtocolValidationContext.ProtocolMessage.AccessToken is null, there is no 'token' in the OpenIdConnect Response to validate.";
internal const string IDX21311 = "IDX21311: The 'at_hash' claim was not a string in the 'id_token', but an 'access_token' was in the OpenIdConnectMessage, 'id_token': '{0}'.";
diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdConnectProtocolValidator.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdConnectProtocolValidator.cs
index ae4ef80c2d..c676bc417b 100644
--- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdConnectProtocolValidator.cs
+++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/OpenIdConnectProtocolValidator.cs
@@ -345,7 +345,7 @@ public virtual void ValidateUserInfoResponse(OpenIdConnectProtocolValidationCont
if (string.IsNullOrEmpty(validationContext.ValidatedIdToken.Payload.Sub))
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolException(LogMessages.IDX21346));
- if (!string.Equals(validationContext.ValidatedIdToken.Payload.Sub, sub, StringComparison.Ordinal))
+ if (!string.Equals(validationContext.ValidatedIdToken.Payload.Sub, sub))
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolException(LogHelper.FormatInvariant(LogMessages.IDX21338, validationContext.ValidatedIdToken.Payload.Sub, sub)));
}
@@ -421,7 +421,7 @@ protected virtual void ValidateIdToken(OpenIdConnectProtocolValidationContext va
{
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolException(LogMessages.IDX21308));
}
- else if (!string.Equals(idToken.Payload.Azp, validationContext.ClientId, StringComparison.Ordinal))
+ else if (!string.Equals(idToken.Payload.Azp, validationContext.ClientId))
{
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolException(LogHelper.FormatInvariant(LogMessages.IDX21340, idToken.Payload.Azp, validationContext.ClientId)));
}
@@ -498,7 +498,7 @@ private static void CheckHash(HashAlgorithm hashAlgorithm, string expectedValue,
{
var hashBytes = hashAlgorithm.ComputeHash(Encoding.ASCII.GetBytes(hashItem));
var hashString = Base64UrlEncoder.Encode(hashBytes, 0, hashBytes.Length / 2);
- if (!string.Equals(expectedValue, hashString, StringComparison.Ordinal))
+ if (!string.Equals(expectedValue, hashString))
{
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolException(LogHelper.FormatInvariant(LogMessages.IDX21300, expectedValue, hashItem, LogHelper.MarkAsNonPII(algorithm))));
}
@@ -544,11 +544,15 @@ protected virtual void ValidateCHash(OpenIdConnectProtocolValidationContext vali
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidCHashException(LogHelper.FormatInvariant(LogMessages.IDX21306, validationContext.ValidatedIdToken)));
}
+ var idToken = validationContext.ValidatedIdToken;
+
+ var alg = idToken.InnerToken != null ? idToken.InnerToken.Header.Alg : idToken.Header.Alg;
+
try
{
- ValidateHash(chash, validationContext.ProtocolMessage.Code, validationContext.ValidatedIdToken.Header.Alg);
+ ValidateHash(chash, validationContext.ProtocolMessage.Code, alg);
}
- catch(OpenIdConnectProtocolException ex)
+ catch (OpenIdConnectProtocolException ex)
{
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidCHashException(LogMessages.IDX21347, ex));
}
@@ -590,9 +594,13 @@ protected virtual void ValidateAtHash(OpenIdConnectProtocolValidationContext val
if (atHash == null)
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidAtHashException(LogHelper.FormatInvariant(LogMessages.IDX21311, validationContext.ValidatedIdToken)));
+ var idToken = validationContext.ValidatedIdToken;
+
+ var alg = idToken.InnerToken != null ? idToken.InnerToken.Header.Alg : idToken.Header.Alg;
+
try
{
- ValidateHash(atHash, validationContext.ProtocolMessage.AccessToken, validationContext.ValidatedIdToken.Header.Alg);
+ ValidateHash(atHash, validationContext.ProtocolMessage.AccessToken, alg);
}
catch (OpenIdConnectProtocolException ex)
{
@@ -638,7 +646,7 @@ protected virtual void ValidateNonce(OpenIdConnectProtocolValidationContext vali
else if (string.IsNullOrEmpty(nonceFoundInJwt))
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidNonceException(LogHelper.FormatInvariant(LogMessages.IDX21349, LogHelper.MarkAsNonPII(RequireNonce))));
- if (!string.Equals(nonceFoundInJwt, validationContext.Nonce, StringComparison.Ordinal))
+ if (!string.Equals(nonceFoundInJwt, validationContext.Nonce))
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidNonceException(LogHelper.FormatInvariant(LogMessages.IDX21321, validationContext.Nonce, nonceFoundInJwt, validationContext.ValidatedIdToken)));
if (RequireTimeStampInNonce)
@@ -666,7 +674,7 @@ protected virtual void ValidateNonce(OpenIdConnectProtocolValidationContext vali
{
nonceTime = DateTime.FromBinary(ticks);
}
- catch(Exception ex)
+ catch (Exception ex)
{
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidNonceException(LogHelper.FormatInvariant(LogMessages.IDX21327, LogHelper.MarkAsNonPII(timestamp), LogHelper.MarkAsNonPII(DateTime.MinValue.Ticks.ToString(CultureInfo.InvariantCulture)), LogHelper.MarkAsNonPII(DateTime.MaxValue.Ticks.ToString(CultureInfo.InvariantCulture))), ex));
}
@@ -715,7 +723,7 @@ protected virtual void ValidateState(OpenIdConnectProtocolValidationContext vali
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidStateException(LogHelper.FormatInvariant(LogMessages.IDX21330, LogHelper.MarkAsNonPII(RequireState))));
}
- if (!string.Equals(validationContext.State, validationContext.ProtocolMessage.State, StringComparison.Ordinal))
+ if (!string.Equals(validationContext.State, validationContext.ProtocolMessage.State))
{
throw LogHelper.LogExceptionMessage(new OpenIdConnectProtocolInvalidStateException(LogHelper.FormatInvariant(LogMessages.IDX21331, validationContext.State, validationContext.ProtocolMessage.State)));
}
diff --git a/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/GlobalSuppressions.cs
index a64586da17..c4a4856de7 100644
--- a/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/GlobalSuppressions.cs
@@ -10,5 +10,6 @@
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Previously released as read / write", Scope = "member", Target = "~P:Microsoft.IdentityModel.Protocols.SignedHttpRequest.SignedHttpRequestDescriptor.AdditionalPayloadClaims")]
[assembly: SuppressMessage("Performance", "CA1825: Avoid zero-length array allocations", Justification = "net45 target doesn't support Array.Empty")]
[assembly: SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Headers need to be lowercase to calcuate appropriate hash", Scope = "type", Target = "~T:Microsoft.IdentityModel.Protocols.SignedHttpRequest.SignedHttpRequestHandler")]
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Vendored component", Scope = "module")]
[assembly: SuppressMessage("Design", "CA1001:Types that own disposable fields should be disposable", Justification = "Breaking change", Scope = "type", Target = "~T:Microsoft.IdentityModel.Protocols.SignedHttpRequest.SignedHttpRequestHandler")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Previously released as read / write", Scope = "member", Target = "~P:Microsoft.IdentityModel.Protocols.SignedHttpRequest.SignedHttpRequestInvalidNonceClaimException.PropertyBag")]
diff --git a/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/Microsoft.IdentityModel.Protocols.SignedHttpRequest.csproj b/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/Microsoft.IdentityModel.Protocols.SignedHttpRequest.csproj
index f427c7885e..f96b956717 100644
--- a/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/Microsoft.IdentityModel.Protocols.SignedHttpRequest.csproj
+++ b/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/Microsoft.IdentityModel.Protocols.SignedHttpRequest.csproj
@@ -31,7 +31,7 @@
-
+
diff --git a/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/SignedHttpRequestHandler.cs b/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/SignedHttpRequestHandler.cs
index 4dbe56485f..f3e936f7fd 100644
--- a/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/SignedHttpRequestHandler.cs
+++ b/src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/SignedHttpRequestHandler.cs
@@ -103,7 +103,6 @@ public string CreateSignedHttpRequest(SignedHttpRequestDescriptor signedHttpRequ
return message + "." + JwtTokenUtilities.CreateEncodedSignature(message, signedHttpRequestDescriptor.SigningCredentials, false);
}
-
///
/// Creates a JSON representation of a HttpRequest payload.
///
@@ -209,7 +208,7 @@ internal virtual void AddMClaim(Dictionary payload, SignedHttpRe
if (string.IsNullOrEmpty(httpMethod))
throw LogHelper.LogArgumentNullException(nameof(signedHttpRequestDescriptor.HttpRequestData.Method));
- if (!httpMethod.ToUpperInvariant().Equals(httpMethod, StringComparison.Ordinal))
+ if (!httpMethod.ToUpperInvariant().Equals(httpMethod))
throw LogHelper.LogExceptionMessage(new SignedHttpRequestCreationException(LogHelper.FormatInvariant(LogMessages.IDX23002, LogHelper.MarkAsNonPII(httpMethod))));
payload.Add(SignedHttpRequestClaimTypes.M, httpMethod);
@@ -856,7 +855,7 @@ internal virtual void ValidateQClaim(JsonWebToken signedHttpRequest, SignedHttpR
if (!signedHttpRequestValidationContext.SignedHttpRequestValidationParameters.AcceptUnsignedQueryParameters && sanitizedQueryParams.Any())
throw LogHelper.LogExceptionMessage(new SignedHttpRequestInvalidQClaimException(LogHelper.FormatInvariant(LogMessages.IDX23029, LogHelper.MarkAsNonPII(string.Join(", ", sanitizedQueryParams.Select(x => x.Key))))));
- if (!string.Equals(expectedBase64UrlEncodedHash, qClaimBase64UrlEncodedHash, StringComparison.Ordinal))
+ if (!string.Equals(expectedBase64UrlEncodedHash, qClaimBase64UrlEncodedHash))
throw LogHelper.LogExceptionMessage(new SignedHttpRequestInvalidQClaimException(LogHelper.FormatInvariant(LogMessages.IDX23011, LogHelper.MarkAsNonPII(SignedHttpRequestClaimTypes.Q), expectedBase64UrlEncodedHash, qClaimBase64UrlEncodedHash)));
}
@@ -924,7 +923,7 @@ internal virtual void ValidateHClaim(JsonWebToken signedHttpRequest, SignedHttpR
if (!signedHttpRequestValidationContext.SignedHttpRequestValidationParameters.AcceptUnsignedHeaders && sanitizedHeaders.Any())
throw LogHelper.LogExceptionMessage(new SignedHttpRequestInvalidHClaimException(LogHelper.FormatInvariant(LogMessages.IDX23026, LogHelper.MarkAsNonPII(string.Join(", ", sanitizedHeaders.Select(x => x.Key))))));
- if (!string.Equals(expectedBase64UrlEncodedHash, hClaimBase64UrlEncodedHash, StringComparison.Ordinal))
+ if (!string.Equals(expectedBase64UrlEncodedHash, hClaimBase64UrlEncodedHash))
throw LogHelper.LogExceptionMessage(new SignedHttpRequestInvalidHClaimException(LogHelper.FormatInvariant(LogMessages.IDX23011, LogHelper.MarkAsNonPII(SignedHttpRequestClaimTypes.H), expectedBase64UrlEncodedHash, hClaimBase64UrlEncodedHash)));
}
@@ -958,7 +957,7 @@ internal virtual void ValidateBClaim(JsonWebToken signedHttpRequest, SignedHttpR
throw LogHelper.LogExceptionMessage(new SignedHttpRequestCreationException(LogHelper.FormatInvariant(LogMessages.IDX23008, LogHelper.MarkAsNonPII(SignedHttpRequestClaimTypes.B), e), e));
}
- if (!string.Equals(expectedBase64UrlEncodedHash, bClaim, StringComparison.Ordinal))
+ if (!string.Equals(expectedBase64UrlEncodedHash, bClaim))
throw LogHelper.LogExceptionMessage(new SignedHttpRequestInvalidBClaimException(LogHelper.FormatInvariant(LogMessages.IDX23011, LogHelper.MarkAsNonPII(SignedHttpRequestClaimTypes.B), expectedBase64UrlEncodedHash, bClaim)));
}
#endregion
@@ -1102,7 +1101,7 @@ internal virtual async Task ResolvePopKeyFromJkuAsync(string jkuSet
{
foreach (var key in popKeys)
{
- if (string.Equals(key.KeyId, kid.ToString(), StringComparison.Ordinal))
+ if (string.Equals(key.KeyId, kid.ToString()))
return key;
}
@@ -1189,7 +1188,7 @@ internal virtual async Task ResolvePopKeyFromCnfReferenceAsync(stri
jwkPopKeyThumprint = Base64UrlEncoder.Encode(popKey.ComputeJwkThumbprint());
// validate reference
- if (!string.Equals(cnfReferenceId, jwkPopKeyThumprint, StringComparison.Ordinal))
+ if (!string.Equals(cnfReferenceId, jwkPopKeyThumprint))
throw LogHelper.LogExceptionMessage(new SignedHttpRequestInvalidPopKeyException(LogHelper.FormatInvariant(LogMessages.IDX23033, cnfReferenceId, jwkPopKeyThumprint, confirmationClaim)));
return popKey;
diff --git a/src/Microsoft.IdentityModel.Protocols.WsFederation/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Protocols.WsFederation/GlobalSuppressions.cs
index dc2dbb01cc..6a35dd1f18 100644
--- a/src/Microsoft.IdentityModel.Protocols.WsFederation/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Protocols.WsFederation/GlobalSuppressions.cs
@@ -31,3 +31,7 @@
[assembly: SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "Doesn't own object", Scope = "member", Target = "~M:Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMetadataSerializer.ReadEntityDescriptor(System.Xml.XmlReader)~Microsoft.IdentityModel.Protocols.WsFederation.WsFederationConfiguration")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Protocols.WsFederation.SecurityTokenServiceTypeRoleDescriptor.KeyInfos")]
+#if NET6_0
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Adding StringComparison.Ordinal adds a performance penalty.", Scope = "member", Target = "~M:Microsoft.IdentityModel.Protocols.WsFederation.QueryHelper.ParseNullableQuery(System.String)~System.Collections.Generic.IDictionary{System.String,System.Collections.Generic.IList{System.String}}")]
+#endif
+
diff --git a/src/Microsoft.IdentityModel.Protocols.WsFederation/Microsoft.IdentityModel.Protocols.WsFederation.csproj b/src/Microsoft.IdentityModel.Protocols.WsFederation/Microsoft.IdentityModel.Protocols.WsFederation.csproj
index 248ae24373..90baa73364 100644
--- a/src/Microsoft.IdentityModel.Protocols.WsFederation/Microsoft.IdentityModel.Protocols.WsFederation.csproj
+++ b/src/Microsoft.IdentityModel.Protocols.WsFederation/Microsoft.IdentityModel.Protocols.WsFederation.csproj
@@ -28,7 +28,7 @@
-
+
diff --git a/src/Microsoft.IdentityModel.Protocols/Configuration/ConfigurationManager.cs b/src/Microsoft.IdentityModel.Protocols/Configuration/ConfigurationManager.cs
index dde466a6d1..3a1cc8aa90 100644
--- a/src/Microsoft.IdentityModel.Protocols/Configuration/ConfigurationManager.cs
+++ b/src/Microsoft.IdentityModel.Protocols/Configuration/ConfigurationManager.cs
@@ -57,7 +57,6 @@ public class ConfigurationManager : BaseConfigurationManager, IConfigurationM
///
static ConfigurationManager()
{
- LogHelper.LogVerbose("Assembly version info: " + LogHelper.MarkAsNonPII(typeof(ConfigurationManager).AssemblyQualifiedName));
}
///
@@ -163,7 +162,7 @@ public async Task GetConfigurationAsync(CancellationToken cancel)
if (_configValidator != null)
{
ConfigurationValidationResult result = _configValidator.Validate(configuration);
- if (!result.Succeeded)
+ if (!result.Succeeded)
LogHelper.LogWarning(LogMessages.IDX20810, result.ErrorMessage);
}
diff --git a/src/Microsoft.IdentityModel.Protocols/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Protocols/GlobalSuppressions.cs
index e79eb2c67c..7b5a935521 100644
--- a/src/Microsoft.IdentityModel.Protocols/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Protocols/GlobalSuppressions.cs
@@ -9,3 +9,6 @@
[assembly: SuppressMessage("Performance", "CA1819:Properties should not return arrays", Justification = "Previously released as returning an array", Scope = "member", Target = "~P:Microsoft.IdentityModel.Protocols.HttpRequestData.Body")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Previously released read/write", Scope = "member", Target = "~P:Microsoft.IdentityModel.Protocols.HttpRequestData.Headers")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Previously released read/write", Scope = "member", Target = "~P:Microsoft.IdentityModel.Protocols.HttpRequestData.PropertyBag")]
+#if NET6_0
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Adding StringComparison.Ordinal adds a performance penalty.", Scope = "member", Target = "~M:Microsoft.IdentityModel.Protocols.AuthenticationProtocolMessage.BuildRedirectUrl~System.String")]
+#endif
diff --git a/src/Microsoft.IdentityModel.TestExtensions/Microsoft.IdentityModel.TestExtensions.csproj b/src/Microsoft.IdentityModel.TestExtensions/Microsoft.IdentityModel.TestExtensions.csproj
index c5895d612d..8948aa7508 100644
--- a/src/Microsoft.IdentityModel.TestExtensions/Microsoft.IdentityModel.TestExtensions.csproj
+++ b/src/Microsoft.IdentityModel.TestExtensions/Microsoft.IdentityModel.TestExtensions.csproj
@@ -1,6 +1,6 @@
-
+
Microsoft.IdentityModel.TestExtensions
diff --git a/src/Microsoft.IdentityModel.TestExtensions/Properties/AssemblyInfo.cs b/src/Microsoft.IdentityModel.TestExtensions/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..2743e6bc85
--- /dev/null
+++ b/src/Microsoft.IdentityModel.TestExtensions/Properties/AssemblyInfo.cs
@@ -0,0 +1,37 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyInformationalVersion("0.0.1")]
+[assembly: AssemblyFileVersion("0.0.1")]
+[assembly: AssemblyMetadata("Serviceable", "True")]
+[assembly: AssemblyVersion("0.0.1")]
+[assembly: CLSCompliant(true)]
+[assembly: ComVisible(false)]
diff --git a/src/Microsoft.IdentityModel.Tokens.Saml/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Tokens.Saml/GlobalSuppressions.cs
index 07185abb0b..0dfb75d6f5 100644
--- a/src/Microsoft.IdentityModel.Tokens.Saml/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Tokens.Saml/GlobalSuppressions.cs
@@ -30,3 +30,4 @@
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.Saml2.Saml2Assertion.CanonicalString")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Catching all exceptions to match old model, in new models, we should try to avoid this behavior", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.Saml.SamlSecurityTokenHandler.ValidateTokenAsync(System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters)~System.Threading.Tasks.Task{Microsoft.IdentityModel.Tokens.TokenValidationResult}")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Catching all exceptions to match old model, in new models, we should try to avoid this behavior", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateTokenAsync(System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters)~System.Threading.Tasks.Task{Microsoft.IdentityModel.Tokens.TokenValidationResult}")]
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Vendored component", Scope = "module")]
diff --git a/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAttributeKeyComparer.cs b/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAttributeKeyComparer.cs
index 49df3a982a..203bcee0f4 100644
--- a/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAttributeKeyComparer.cs
+++ b/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAttributeKeyComparer.cs
@@ -96,12 +96,12 @@ int ComputeHashCode()
public bool Equals(AttributeKey other)
{
return other != null &&
- FriendlyName.Equals(other.FriendlyName, StringComparison.Ordinal) &&
- Name.Equals(other.Name, StringComparison.Ordinal) &&
- NameFormat.Equals(other.NameFormat, StringComparison.Ordinal) &&
- Namespace.Equals(other.Namespace, StringComparison.Ordinal) &&
- OriginalIssuer.Equals(other.OriginalIssuer, StringComparison.Ordinal) &&
- ValueType.Equals(other.ValueType, StringComparison.Ordinal);
+ FriendlyName.Equals(other.FriendlyName) &&
+ Name.Equals(other.Name) &&
+ NameFormat.Equals(other.NameFormat) &&
+ Namespace.Equals(other.Namespace) &&
+ OriginalIssuer.Equals(other.OriginalIssuer) &&
+ ValueType.Equals(other.ValueType);
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAuthorizationDecisionStatement.cs b/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAuthorizationDecisionStatement.cs
index 1a601ffee8..ca2c0b5b33 100644
--- a/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAuthorizationDecisionStatement.cs
+++ b/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlAuthorizationDecisionStatement.cs
@@ -97,9 +97,9 @@ public string Decision
if (string.IsNullOrEmpty(value))
throw LogArgumentNullException(nameof(value));
- if (SamlConstants.AccessDecision.Deny.Equals(value, StringComparison.Ordinal)
- || SamlConstants.AccessDecision.Permit.Equals(value, StringComparison.Ordinal)
- || SamlConstants.AccessDecision.Indeterminate.Equals(value, StringComparison.Ordinal))
+ if (SamlConstants.AccessDecision.Deny.Equals(value)
+ || SamlConstants.AccessDecision.Permit.Equals(value)
+ || SamlConstants.AccessDecision.Indeterminate.Equals(value))
_decision = value;
else
throw LogExceptionMessage(new SamlSecurityTokenException(LogMessages.IDX11508));
diff --git a/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlSerializer.cs b/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlSerializer.cs
index e8bcae5f3a..6a07d9b1a1 100644
--- a/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlSerializer.cs
+++ b/src/Microsoft.IdentityModel.Tokens.Saml/Saml/SamlSerializer.cs
@@ -234,7 +234,7 @@ public virtual SamlAssertion ReadAssertion(XmlReader reader)
if (string.IsNullOrEmpty(majorVersion))
throw LogReadException(LogMessages.IDX11115, SamlConstants.Elements.Assertion, SamlConstants.Attributes.MajorVersion);
- if (!majorVersion.Equals(SamlConstants.MajorVersionValue, StringComparison.Ordinal))
+ if (!majorVersion.Equals(SamlConstants.MajorVersionValue))
throw LogReadException(LogMessages.IDX11116, majorVersion);
// @MinorVersion - required - must be "1"
@@ -242,7 +242,7 @@ public virtual SamlAssertion ReadAssertion(XmlReader reader)
if (string.IsNullOrEmpty(minorVersion))
throw LogReadException(LogMessages.IDX11115, SamlConstants.Elements.Assertion, SamlConstants.Attributes.MinorVersion);
- if (!minorVersion.Equals(SamlConstants.MinorVersionValue, StringComparison.Ordinal))
+ if (!minorVersion.Equals(SamlConstants.MinorVersionValue))
throw LogReadException(LogMessages.IDX11117, minorVersion);
// @AssertionId - required
diff --git a/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AttributeKeyComparer.cs b/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AttributeKeyComparer.cs
index c612a3f89a..c29f7a31ba 100644
--- a/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AttributeKeyComparer.cs
+++ b/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AttributeKeyComparer.cs
@@ -92,11 +92,11 @@ int ComputeHashCode()
public bool Equals(AttributeKey other)
{
return other != null &&
- FriendlyName.Equals(other.FriendlyName, StringComparison.Ordinal) &&
- Name.Equals(other.Name, StringComparison.Ordinal) &&
- NameFormat.Equals(other.NameFormat, StringComparison.Ordinal) &&
- ValueType.Equals(other.ValueType, StringComparison.Ordinal) &&
- OriginalIssuer.Equals(other.OriginalIssuer, StringComparison.Ordinal);
+ FriendlyName.Equals(other.FriendlyName) &&
+ Name.Equals(other.Name) &&
+ NameFormat.Equals(other.NameFormat) &&
+ ValueType.Equals(other.ValueType) &&
+ OriginalIssuer.Equals(other.OriginalIssuer);
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AuthorizationDecisionStatement.cs b/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AuthorizationDecisionStatement.cs
index 947532186f..90000381de 100644
--- a/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AuthorizationDecisionStatement.cs
+++ b/src/Microsoft.IdentityModel.Tokens.Saml/Saml2/Saml2AuthorizationDecisionStatement.cs
@@ -94,9 +94,9 @@ public string Decision
if (string.IsNullOrEmpty(value))
throw LogArgumentNullException(nameof(value));
- if (Saml2Constants.AccessDecision.Deny.Equals(value, StringComparison.Ordinal)
- || Saml2Constants.AccessDecision.Permit.Equals(value, StringComparison.Ordinal)
- || Saml2Constants.AccessDecision.Indeterminate.Equals(value, StringComparison.Ordinal))
+ if (Saml2Constants.AccessDecision.Deny.Equals(value)
+ || Saml2Constants.AccessDecision.Permit.Equals(value)
+ || Saml2Constants.AccessDecision.Indeterminate.Equals(value))
_decision = value;
else
throw LogExceptionMessage(new Saml2SecurityTokenException(LogMessages.IDX13310));
diff --git a/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs b/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs
index 20b8911fd5..c0260b6087 100644
--- a/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/AsymmetricAdapter.cs
@@ -33,7 +33,7 @@
using System.Reflection;
#endif
-#if NET461 || NET472 || NETSTANDARD2_0
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
using System.Security.Cryptography.X509Certificates;
#endif
@@ -194,8 +194,8 @@ private void InitializeUsingRsa(RSA rsa, string algorithm)
#if DESKTOP
if (rsa is RSACryptoServiceProvider rsaCryptoServiceProvider)
{
- _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal)
- || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal);
+ _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP)
+ || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap);
RsaCryptoServiceProviderProxy = new RSACryptoServiceProviderProxy(rsaCryptoServiceProvider);
DecryptFunction = DecryptWithRsaCryptoServiceProviderProxy;
@@ -215,10 +215,10 @@ private void InitializeUsingRsa(RSA rsa, string algorithm)
// This requires 4.6+ to be installed. If a dependent library is targeting 4.5, 4.5.1, 4.5.2 or 4.6
// they will bind to our Net45 target, but the type is RSACng.
// The 'lightup' code will bind to the correct operators.
- else if (rsa.GetType().ToString().Equals(_rsaCngTypeName, StringComparison.Ordinal) && IsRsaCngSupported())
+ else if (rsa.GetType().ToString().Equals(_rsaCngTypeName) && IsRsaCngSupported())
{
- _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal)
- || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal);
+ _useRSAOeapPadding = algorithm.Equals(SecurityAlgorithms.RsaOAEP)
+ || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap);
_lightUpHashAlgorithmName = GetLightUpHashAlgorithmName();
DecryptFunction = DecryptNet45;
@@ -235,13 +235,13 @@ private void InitializeUsingRsa(RSA rsa, string algorithm)
}
#endif
-#if NET461 || NET472 || NETSTANDARD2_0
- if (algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256, StringComparison.Ordinal) ||
- algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256Signature, StringComparison.Ordinal) ||
- algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384, StringComparison.Ordinal) ||
- algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384Signature, StringComparison.Ordinal) ||
- algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512, StringComparison.Ordinal) ||
- algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512Signature, StringComparison.Ordinal))
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
+ if (algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256) ||
+ algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha256Signature) ||
+ algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384) ||
+ algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha384Signature) ||
+ algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512) ||
+ algorithm.Equals(SecurityAlgorithms.RsaSsaPssSha512Signature))
{
RSASignaturePadding = RSASignaturePadding.Pss;
}
@@ -251,7 +251,7 @@ private void InitializeUsingRsa(RSA rsa, string algorithm)
RSASignaturePadding = RSASignaturePadding.Pkcs1;
}
- RSAEncryptionPadding = (algorithm.Equals(SecurityAlgorithms.RsaOAEP, StringComparison.Ordinal) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap, StringComparison.Ordinal))
+ RSAEncryptionPadding = (algorithm.Equals(SecurityAlgorithms.RsaOAEP) || algorithm.Equals(SecurityAlgorithms.RsaOaepKeyWrap))
? RSAEncryptionPadding.OaepSHA1
: RSAEncryptionPadding.Pkcs1;
RSA = rsa;
@@ -270,7 +270,7 @@ private void InitializeUsingRsaSecurityKey(RsaSecurityKey rsaSecurityKey, string
}
else
{
-#if NET472
+#if NET472 || NET6_0
var rsa = RSA.Create(rsaSecurityKey.Parameters);
#else
var rsa = RSA.Create();
@@ -323,8 +323,8 @@ private bool VerifyWithECDsa(byte[] bytes, byte[] signature)
return ECDsa.VerifyHash(HashAlgorithm.ComputeHash(bytes), signature);
}
-#region NET61+ related code
-#if NET461 || NET472 || NETSTANDARD2_0
+ #region NET61+ related code
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
// HasAlgorithmName was introduced into Net46
internal AsymmetricAdapter(SecurityKey key, string algorithm, HashAlgorithm hashAlgorithm, HashAlgorithmName hashAlgorithmName, bool requirePrivateKey)
: this(key, algorithm, hashAlgorithm, requirePrivateKey)
diff --git a/src/Microsoft.IdentityModel.Tokens/AsymmetricSignatureProvider.cs b/src/Microsoft.IdentityModel.Tokens/AsymmetricSignatureProvider.cs
index dc1cd213d7..465c557634 100644
--- a/src/Microsoft.IdentityModel.Tokens/AsymmetricSignatureProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/AsymmetricSignatureProvider.cs
@@ -185,8 +185,8 @@ private static PrivateKeyStatus FoundPrivateKey(SecurityKey key)
return PrivateKeyStatus.Unknown;
}
-
-#if NET461 || NET472 || NETSTANDARD2_0
+
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
///
/// Creating a Signature requires the use of a .
/// This method returns the
diff --git a/src/Microsoft.IdentityModel.Tokens/CallContext.cs b/src/Microsoft.IdentityModel.Tokens/CallContext.cs
index 359d94d067..d800d7dd05 100644
--- a/src/Microsoft.IdentityModel.Tokens/CallContext.cs
+++ b/src/Microsoft.IdentityModel.Tokens/CallContext.cs
@@ -26,51 +26,27 @@
//------------------------------------------------------------------------------
using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics.Tracing;
+using Microsoft.IdentityModel.Logging;
namespace Microsoft.IdentityModel.Tokens
{
///
/// An opaque context used to store work when working with authentication artifacts.
///
- public class CallContext
+ public class CallContext : LoggerContext
{
///
/// Instantiates a new with a default activityId.
///
- public CallContext()
+ public CallContext() : base()
{
}
///
/// Instantiates a new with an activityId.
///
- public CallContext(Guid activityId)
+ public CallContext(Guid activityId) : base(activityId)
{
- ActivityId = activityId;
}
-
- ///
- /// Gets or set a that will be used in the call to EventSource.SetCurrentThreadActivityId before logging.
- ///
- public Guid ActivityId { get; set; } = Guid.Empty;
-
- ///
- /// Gets or sets a boolean controlling if logs are written into the context.
- /// Useful when debugging.
- ///
- public bool CaptureLogs { get; set; } = false;
-
- ///
- /// The collection of logs associated with a request. Use to control capture.
- ///
- public ICollection Logs { get; private set; } = new Collection();
-
- ///
- /// Gets or sets an that enables custom extensibility scenarios.
- ///
- public IDictionary PropertyBag { get; set; }
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens/CompressionProviderFactory.cs b/src/Microsoft.IdentityModel.Tokens/CompressionProviderFactory.cs
index 139bd0ea03..1042e36ac2 100644
--- a/src/Microsoft.IdentityModel.Tokens/CompressionProviderFactory.cs
+++ b/src/Microsoft.IdentityModel.Tokens/CompressionProviderFactory.cs
@@ -93,7 +93,7 @@ public virtual bool IsSupportedAlgorithm(string algorithm)
private static bool IsSupportedCompressionAlgorithm(string algorithm)
{
- return CompressionAlgorithms.Deflate.Equals(algorithm, StringComparison.Ordinal);
+ return CompressionAlgorithms.Deflate.Equals(algorithm);
}
///
@@ -109,7 +109,7 @@ public ICompressionProvider CreateCompressionProvider(string algorithm)
if (CustomCompressionProvider != null && CustomCompressionProvider.IsSupportedAlgorithm(algorithm))
return CustomCompressionProvider;
- if (algorithm.Equals(CompressionAlgorithms.Deflate, StringComparison.Ordinal))
+ if (algorithm.Equals(CompressionAlgorithms.Deflate))
return new DeflateCompressionProvider();
throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10652, LogHelper.MarkAsNonPII(algorithm))));
diff --git a/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs b/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs
index c206c468b5..66a0c75532 100644
--- a/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs
+++ b/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs
@@ -342,7 +342,7 @@ public virtual SignatureProvider CreateForVerifying(SecurityKey key, string algo
return CreateSignatureProvider(key, algorithm, false, cacheProvider);
}
-#if NET461 || NET472 || NETSTANDARD2_0
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
///
/// Creates a for a specific algorithm.
///
diff --git a/src/Microsoft.IdentityModel.Tokens/DeflateCompressionProvider.cs b/src/Microsoft.IdentityModel.Tokens/DeflateCompressionProvider.cs
index 9eac17f586..60b48beff6 100644
--- a/src/Microsoft.IdentityModel.Tokens/DeflateCompressionProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/DeflateCompressionProvider.cs
@@ -118,7 +118,7 @@ public byte[] Compress(byte[] value)
/// true if the compression algorithm is supported, false otherwise.
public bool IsSupportedAlgorithm(string algorithm)
{
- return Algorithm.Equals(algorithm, StringComparison.Ordinal);
+ return Algorithm.Equals(algorithm);
}
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens/ECDsaAdapter.cs b/src/Microsoft.IdentityModel.Tokens/ECDsaAdapter.cs
index c0264f7930..7a40a30f5f 100644
--- a/src/Microsoft.IdentityModel.Tokens/ECDsaAdapter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/ECDsaAdapter.cs
@@ -52,7 +52,7 @@ internal class ECDsaAdapter
///
internal ECDsaAdapter()
{
-#if NET472
+#if NET472 || NET6_0
CreateECDsaFunction = CreateECDsaUsingECParams;
#elif NETSTANDARD2_0
// Although NETSTANDARD2_0 specifies that ECParameters are supported, we still need to call SupportsECParameters()
@@ -269,7 +269,9 @@ private static bool SupportsCNGKey()
{
try
{
+#pragma warning disable CA1416 // Validate platform compatibility
_ = CngKeyBlobFormat.EccPrivateBlob;
+#pragma warning restore CA1416 // Validate platform compatibility
return true;
}
catch
@@ -278,7 +280,7 @@ private static bool SupportsCNGKey()
}
}
-#if NET472 || NETSTANDARD2_0
+#if NET472 || NETSTANDARD2_0 || NET6_0
///
/// Creates an ECDsa object using the and .
/// 'ECParameters' structure is available in .NET Framework 4.7+, .NET Standard 1.6+, and .NET Core 1.0+.
@@ -349,11 +351,11 @@ internal static string GetCrvParameterValue(ECCurve curve)
if (curve.Oid == null)
throw LogHelper.LogArgumentNullException(nameof(curve.Oid));
- if (string.Equals(curve.Oid.Value, ECCurve.NamedCurves.nistP256.Oid.Value, StringComparison.Ordinal) || string.Equals(curve.Oid.FriendlyName, ECCurve.NamedCurves.nistP256.Oid.FriendlyName, StringComparison.Ordinal))
+ if (string.Equals(curve.Oid.Value, ECCurve.NamedCurves.nistP256.Oid.Value) || string.Equals(curve.Oid.FriendlyName, ECCurve.NamedCurves.nistP256.Oid.FriendlyName))
return JsonWebKeyECTypes.P256;
- else if (string.Equals(curve.Oid.Value, ECCurve.NamedCurves.nistP384.Oid.Value, StringComparison.Ordinal) || string.Equals(curve.Oid.FriendlyName, ECCurve.NamedCurves.nistP384.Oid.FriendlyName, StringComparison.Ordinal))
+ else if (string.Equals(curve.Oid.Value, ECCurve.NamedCurves.nistP384.Oid.Value) || string.Equals(curve.Oid.FriendlyName, ECCurve.NamedCurves.nistP384.Oid.FriendlyName))
return JsonWebKeyECTypes.P384;
- else if (string.Equals(curve.Oid.Value, ECCurve.NamedCurves.nistP521.Oid.Value, StringComparison.Ordinal) || string.Equals(curve.Oid.FriendlyName, ECCurve.NamedCurves.nistP521.Oid.FriendlyName, StringComparison.Ordinal))
+ else if (string.Equals(curve.Oid.Value, ECCurve.NamedCurves.nistP521.Oid.Value) || string.Equals(curve.Oid.FriendlyName, ECCurve.NamedCurves.nistP521.Oid.FriendlyName))
return JsonWebKeyECTypes.P521;
else
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10645, (curve.Oid.Value ?? curve.Oid.FriendlyName) ?? "null")));
@@ -366,7 +368,7 @@ internal static string GetCrvParameterValue(ECCurve curve)
/// True if structure is supported, false otherwise.
internal static bool SupportsECParameters()
{
-#if NET472
+#if NET472 || NET6_0
return true;
#else
try
diff --git a/src/Microsoft.IdentityModel.Tokens/ECDsaSecurityKey.cs b/src/Microsoft.IdentityModel.Tokens/ECDsaSecurityKey.cs
index 11cb930038..5096aa35f0 100644
--- a/src/Microsoft.IdentityModel.Tokens/ECDsaSecurityKey.cs
+++ b/src/Microsoft.IdentityModel.Tokens/ECDsaSecurityKey.cs
@@ -116,7 +116,7 @@ public override int KeySize
/// https://datatracker.ietf.org/doc/html/rfc7638
public override bool CanComputeJwkThumbprint()
{
-#if NET472 || NETSTANDARD2_0
+#if NET472 || NETSTANDARD2_0 || NET6_0
if (ECDsaAdapter.SupportsECParameters())
return true;
#endif
@@ -130,7 +130,7 @@ public override bool CanComputeJwkThumbprint()
/// https://datatracker.ietf.org/doc/html/rfc7638
public override byte[] ComputeJwkThumbprint()
{
-#if NET472 || NETSTANDARD2_0
+#if NET472 || NETSTANDARD2_0 || NET6_0
if (ECDsaAdapter.SupportsECParameters())
{
ECParameters parameters = ECDsa.ExportParameters(false);
diff --git a/src/Microsoft.IdentityModel.Tokens/EncryptingCredentials.cs b/src/Microsoft.IdentityModel.Tokens/EncryptingCredentials.cs
index 5e0db2b8d5..03d29926a9 100644
--- a/src/Microsoft.IdentityModel.Tokens/EncryptingCredentials.cs
+++ b/src/Microsoft.IdentityModel.Tokens/EncryptingCredentials.cs
@@ -109,11 +109,24 @@ public string Enc
private set => _enc = string.IsNullOrEmpty(value) ? throw LogHelper.LogArgumentNullException("enc") : value;
}
+ ///
+ /// Public key used in Key Agreement Algorithms
+ ///
+ public SecurityKey KeyExchangePublicKey { get; set; }
+
///
/// Users can override the default with this property. This factory will be used for creating encryption providers.
///
public CryptoProviderFactory CryptoProviderFactory { get; set; }
+ ///
+ /// Gets or sets a bool that controls if the encrypted token creation will set default 'cty' if not specified.
+ ///
+ /// Applies to only JWT tokens.
+ ///
+ ///
+ public bool SetDefaultCtyClaim { get; set; } = true;
+
///
/// Gets the used for encryption.
///
diff --git a/src/Microsoft.IdentityModel.Tokens/Encryption/AuthenticatedEncryptionProvider.cs b/src/Microsoft.IdentityModel.Tokens/Encryption/AuthenticatedEncryptionProvider.cs
index 0644798645..896195c24a 100644
--- a/src/Microsoft.IdentityModel.Tokens/Encryption/AuthenticatedEncryptionProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Encryption/AuthenticatedEncryptionProvider.cs
@@ -83,7 +83,7 @@ public AuthenticatedEncryptionProvider(SecurityKey key, string algorithm)
{
if (SupportedAlgorithms.IsAesGcm(algorithm))
{
-#if NETSTANDARD2_0
+#if NETSTANDARD2_0 || NET6_0
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
throw LogHelper.LogExceptionMessage(new PlatformNotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10713, LogHelper.MarkAsNonPII(algorithm))));
#endif
@@ -377,11 +377,11 @@ protected virtual bool IsSupportedAlgorithm(SecurityKey key, string algorithm)
private AuthenticatedKeys GetAlgorithmParameters(SecurityKey key, string algorithm)
{
int keyLength = -1;
- if (algorithm.Equals(SecurityAlgorithms.Aes256CbcHmacSha512, StringComparison.Ordinal))
+ if (algorithm.Equals(SecurityAlgorithms.Aes256CbcHmacSha512))
keyLength = 32;
- else if (algorithm.Equals(SecurityAlgorithms.Aes192CbcHmacSha384, StringComparison.Ordinal))
+ else if (algorithm.Equals(SecurityAlgorithms.Aes192CbcHmacSha384))
keyLength = 24;
- else if (algorithm.Equals(SecurityAlgorithms.Aes128CbcHmacSha256, StringComparison.Ordinal))
+ else if (algorithm.Equals(SecurityAlgorithms.Aes128CbcHmacSha256))
keyLength = 16;
else
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10668, LogHelper.MarkAsNonPII(_className), LogHelper.MarkAsNonPII(algorithm), key)));
@@ -406,13 +406,13 @@ private AuthenticatedKeys GetAlgorithmParameters(SecurityKey key, string algorit
///
private static string GetHmacAlgorithm(string algorithm)
{
- if (SecurityAlgorithms.Aes128CbcHmacSha256.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes128CbcHmacSha256.Equals(algorithm))
return SecurityAlgorithms.HmacSha256;
- if (SecurityAlgorithms.Aes192CbcHmacSha384.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes192CbcHmacSha384.Equals(algorithm))
return SecurityAlgorithms.HmacSha384;
- if (SecurityAlgorithms.Aes256CbcHmacSha512.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes256CbcHmacSha512.Equals(algorithm))
return SecurityAlgorithms.HmacSha512;
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10652, LogHelper.MarkAsNonPII(algorithm)), nameof(algorithm)));
@@ -475,7 +475,7 @@ protected virtual void ValidateKeySize(SecurityKey key, string algorithm)
if (string.IsNullOrEmpty(algorithm))
throw LogHelper.LogArgumentNullException(nameof(algorithm));
- if (SecurityAlgorithms.Aes128CbcHmacSha256.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes128CbcHmacSha256.Equals(algorithm))
{
if (key.KeySize < 256)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10653, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes128CbcHmacSha256), LogHelper.MarkAsNonPII(256), key.KeyId, LogHelper.MarkAsNonPII(key.KeySize))));
@@ -483,7 +483,7 @@ protected virtual void ValidateKeySize(SecurityKey key, string algorithm)
return;
}
- if (SecurityAlgorithms.Aes192CbcHmacSha384.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes192CbcHmacSha384.Equals(algorithm))
{
if (key.KeySize < 384)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10653, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes192CbcHmacSha384), LogHelper.MarkAsNonPII(384), key.KeyId, LogHelper.MarkAsNonPII(key.KeySize))));
@@ -491,7 +491,7 @@ protected virtual void ValidateKeySize(SecurityKey key, string algorithm)
return;
}
- if (SecurityAlgorithms.Aes256CbcHmacSha512.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes256CbcHmacSha512.Equals(algorithm))
{
if (key.KeySize < 512)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10653, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes256CbcHmacSha512), LogHelper.MarkAsNonPII(512), key.KeyId, LogHelper.MarkAsNonPII(key.KeySize))));
@@ -499,7 +499,7 @@ protected virtual void ValidateKeySize(SecurityKey key, string algorithm)
return;
}
- if (SecurityAlgorithms.Aes128Gcm.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes128Gcm.Equals(algorithm))
{
if (key.KeySize < 128)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10653, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes128Gcm), LogHelper.MarkAsNonPII(128), key.KeyId, LogHelper.MarkAsNonPII(key.KeySize))));
@@ -507,7 +507,7 @@ protected virtual void ValidateKeySize(SecurityKey key, string algorithm)
return;
}
- if (SecurityAlgorithms.Aes192Gcm.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes192Gcm.Equals(algorithm))
{
if (key.KeySize < 192)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10653, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes192Gcm), LogHelper.MarkAsNonPII(192), key.KeyId, LogHelper.MarkAsNonPII(key.KeySize))));
@@ -515,7 +515,7 @@ protected virtual void ValidateKeySize(SecurityKey key, string algorithm)
return;
}
- if (SecurityAlgorithms.Aes256Gcm.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes256Gcm.Equals(algorithm))
{
if (key.KeySize < 256)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10653, LogHelper.MarkAsNonPII(SecurityAlgorithms.Aes256Gcm), LogHelper.MarkAsNonPII(256), key.KeyId, LogHelper.MarkAsNonPII(key.KeySize))));
diff --git a/src/Microsoft.IdentityModel.Tokens/Encryption/EcdhKeyExchangeProvider.cs b/src/Microsoft.IdentityModel.Tokens/Encryption/EcdhKeyExchangeProvider.cs
new file mode 100644
index 0000000000..114bb5da28
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/Encryption/EcdhKeyExchangeProvider.cs
@@ -0,0 +1,244 @@
+//------------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation.
+// All rights reserved.
+//
+// This code is licensed under the MIT License.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files(the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Text;
+using System.Security.Cryptography;
+using Microsoft.IdentityModel.Logging;
+
+namespace Microsoft.IdentityModel.Tokens
+{
+#if NET472 || NET6_0
+ ///
+ /// Provides a Security Key that can be used as Content Encryption Key (CEK) for use with a JWE
+ ///
+ public class EcdhKeyExchangeProvider
+ {
+ ///
+ /// Number of bits in the desired output key
+ ///
+ public int KeyDataLen { get; set; }
+
+ private ECDiffieHellman _ecdhPublic;
+ private ECDiffieHellman _ecdhPrivate;
+ private ECParameters _ecParamsPublic;
+ private ECParameters _ecParamsPrivate;
+ private string _algorithmId;
+
+ ///
+ /// Initializes a new instance of used for CEKs
+ /// The that will be used for cryptographic operations and represents the private key.
+ /// The that will be used for cryptographic operations and represents the public key.
+ /// alg header parameter value.
+ /// enc header parameter value.
+ ///
+ public EcdhKeyExchangeProvider(SecurityKey privateKey, SecurityKey publicKey, string alg, string enc)
+ {
+ if (privateKey == null)
+ throw LogHelper.LogArgumentNullException(nameof(privateKey));
+
+ if (publicKey is null)
+ throw LogHelper.LogArgumentNullException(nameof(publicKey));
+
+ ValidateAlgAndEnc(alg, enc);
+ SetKeyDataLenAndEncryptionAlgorithm(alg, enc);
+ _ecParamsPublic = GetECParametersFromKey(publicKey, false, nameof(publicKey));
+ _ecParamsPrivate = GetECParametersFromKey(privateKey, true, nameof(privateKey));
+ ValidateCurves(nameof(privateKey), nameof(publicKey));
+ _ecdhPublic = ECDiffieHellman.Create(_ecParamsPublic);
+ _ecdhPrivate = ECDiffieHellman.Create(_ecParamsPrivate);
+ }
+
+ ///
+ /// Generates the KDF
+ ///
+ /// Agreement PartyUInfo (optional). When used, the PartyVInfo value contains information about the producer,
+ /// represented as a base64url-encoded string.
+ /// Agreement PartyVInfo (optional). When used, the PartyUInfo value contains information about the recipient,
+ /// represented as a base64url-encoded string.
+ /// Returns that represents the key generated
+ public SecurityKey GenerateKdf(string apu = null, string apv = null)
+ {
+ //The "apu" and "apv" values MUST be distinct when used (per rfc7518 section 4.6.2) https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.2
+ if (!string.IsNullOrEmpty(apu) && !string.IsNullOrEmpty(apv) && apu.Equals(apv))
+ throw LogHelper.LogArgumentException(
+ nameof(apu),
+ LogHelper.FormatInvariant(
+ LogMessages.IDX11001,
+ LogHelper.MarkAsNonPII(nameof(apu)),
+ LogHelper.MarkAsNonPII(apu),
+ LogHelper.MarkAsNonPII(nameof(apv)),
+ LogHelper.MarkAsNonPII(apv))
+ );
+
+ int kdfLength = KeyDataLen / 8; // number of octets
+ // prepend bytes that represent n = ceiling of (keydatalen / hashlen), see section 5.8.1.1: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
+ // hashlen is always 256 for ecdh-es, see: https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.2
+ // for supported algorithms it is always '1', for saml might be different
+ byte[] prepend = new byte[4] { 0, 0, 0, 1 };
+ SetAppendBytes(apu, apv, out byte[] append);
+ byte[] kdf = new byte[kdfLength];
+
+ // JWA's spec https://datatracker.ietf.org/doc/html/rfc7518#section-4.6.2 specifies SHA256, saml might be different
+ byte[] derivedKey = _ecdhPrivate.DeriveKeyFromHash(_ecdhPublic.PublicKey, HashAlgorithmName.SHA256, prepend, append);
+ Array.Copy(derivedKey, kdf, kdfLength);
+
+ return new SymmetricSecurityKey(kdf);
+ }
+
+ private void SetAppendBytes(string apu, string apv, out byte[] append)
+ {
+ byte[] encBytes = Encoding.ASCII.GetBytes(_algorithmId);
+ byte[] apuBytes = Base64UrlEncoder.DecodeBytes(string.IsNullOrEmpty(apu) ? string.Empty : apu);
+ byte[] apvBytes = Base64UrlEncoder.DecodeBytes(string.IsNullOrEmpty(apv) ? string.Empty : apv);
+ byte[] numOctetsEnc = BitConverter.GetBytes(encBytes.Length);
+ byte[] numOctetsApu = BitConverter.GetBytes(apuBytes.Length);
+ byte[] numOctetsApv = BitConverter.GetBytes(apvBytes.Length);
+ byte[] keyDataLengthBytes = BitConverter.GetBytes(KeyDataLen);
+
+ if (BitConverter.IsLittleEndian)
+ {
+ // these representations need to be big-endian
+ Array.Reverse(numOctetsEnc);
+ Array.Reverse(numOctetsApu);
+ Array.Reverse(numOctetsApv);
+ Array.Reverse(keyDataLengthBytes);
+ }
+
+ append = Concat(numOctetsEnc, encBytes, numOctetsApu, apuBytes, numOctetsApv, apvBytes, keyDataLengthBytes);
+ }
+
+ private void SetKeyDataLenAndEncryptionAlgorithm(string alg, string enc = null)
+ {
+ if (SecurityAlgorithms.EcdhEs.Equals(alg, StringComparison.InvariantCulture))
+ {
+ _algorithmId = enc;
+ if (SecurityAlgorithms.Aes128Gcm.Equals(enc, StringComparison.InvariantCulture))
+ KeyDataLen = 128;
+ else if (SecurityAlgorithms.Aes192Gcm.Equals(enc, StringComparison.InvariantCulture))
+ KeyDataLen = 192;
+ else if (SecurityAlgorithms.Aes256Gcm.Equals(enc, StringComparison.InvariantCulture))
+ KeyDataLen = 256;
+ else if (SecurityAlgorithms.Aes128CbcHmacSha256.Equals(enc, StringComparison.InvariantCulture))
+ KeyDataLen = 128;
+ else if (SecurityAlgorithms.Aes192CbcHmacSha384.Equals(enc, StringComparison.InvariantCulture))
+ KeyDataLen = 192;
+ else if (SecurityAlgorithms.Aes256CbcHmacSha512.Equals(enc, StringComparison.InvariantCulture))
+ KeyDataLen = 256;
+ }
+ else
+ {
+ _algorithmId = alg;
+
+ if (SecurityAlgorithms.EcdhEsA128kw.Equals(alg, StringComparison.InvariantCulture))
+ KeyDataLen = 128;
+ else if (SecurityAlgorithms.EcdhEsA192kw.Equals(alg, StringComparison.InvariantCulture))
+ KeyDataLen = 192;
+ else if (SecurityAlgorithms.EcdhEsA256kw.Equals(alg, StringComparison.InvariantCulture))
+ KeyDataLen = 256;
+ }
+ }
+
+ private static void ValidateAlgAndEnc(string alg, string enc)
+ {
+ if (string.IsNullOrEmpty(alg))
+ throw LogHelper.LogArgumentNullException(alg);
+ if (string.IsNullOrEmpty(enc))
+ throw LogHelper.LogArgumentNullException(enc);
+
+ if (!SupportedAlgorithms.EcdsaWrapAlgorithms.Contains(alg) && !SecurityAlgorithms.EcdhEs.Equals(alg, StringComparison.InvariantCulture))
+ throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10652, LogHelper.MarkAsNonPII(alg))));
+
+ if (!SupportedAlgorithms.SymmetricEncryptionAlgorithms.Contains(enc))
+ throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10715, LogHelper.MarkAsNonPII(enc))));
+ }
+
+ private void ValidateCurves(string privateKeyArgName, string publicKeyArgName)
+ {
+ if (_ecParamsPrivate.Curve.Equals(_ecParamsPublic.Curve))
+ {
+ throw LogHelper.LogArgumentException(
+ privateKeyArgName,
+ LogHelper.FormatInvariant(
+ LogMessages.IDX11000,
+ LogHelper.MarkAsNonPII(privateKeyArgName),
+ LogHelper.MarkAsNonPII(_ecParamsPrivate.Curve.ToString()),
+ LogHelper.MarkAsNonPII(publicKeyArgName),
+ LogHelper.MarkAsNonPII(_ecParamsPublic.Curve.ToString()))
+ );
+ }
+ }
+
+ private static ECParameters GetECParametersFromKey(SecurityKey key, bool isPrivate, string nameOfKey)
+ {
+ if (key is ECDsaSecurityKey ecdsaKey)
+ {
+ return ecdsaKey.ECDsa.ExportParameters(isPrivate);
+ }
+ else if (key is JsonWebKey jwk
+ && JsonWebKeyConverter.TryConvertToECDsaSecurityKey(jwk, out SecurityKey securityKey))
+ {
+ return ((ECDsaSecurityKey)securityKey).ECDsa.ExportParameters(isPrivate);
+ }
+ else
+ {
+ throw LogHelper.LogArgumentException(
+ nameOfKey,
+ LogHelper.FormatInvariant(LogMessages.IDX11002, LogHelper.MarkAsNonPII(nameOfKey)));
+ }
+ }
+
+ private static byte[] Concat(params byte[][] arrays)
+ {
+ int outputLength = 0;
+ foreach (byte[] arr in arrays)
+ outputLength += arr.Length;
+
+ byte[] output = new byte[outputLength];
+ int x = 0;
+ foreach (byte[] arr in arrays)
+ {
+ Array.Copy(arr, 0, output, x, arr.Length);
+ x += arr.Length;
+ }
+
+ return output;
+ }
+
+ internal string GetEncryptionAlgorithm()
+ {
+ if (_algorithmId.Equals(SecurityAlgorithms.EcdhEsA128kw, StringComparison.Ordinal))
+ return SecurityAlgorithms.Aes128KW;
+ if (_algorithmId.Equals(SecurityAlgorithms.EcdhEsA192kw, StringComparison.Ordinal))
+ return SecurityAlgorithms.Aes192KW;
+ if (_algorithmId.Equals(SecurityAlgorithms.EcdhEsA256kw, StringComparison.Ordinal))
+ return SecurityAlgorithms.Aes256KW;
+ return _algorithmId;
+ }
+ }
+#endif
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/Encryption/SymmetricKeyWrapProvider.cs b/src/Microsoft.IdentityModel.Tokens/Encryption/SymmetricKeyWrapProvider.cs
index a1ccc3f996..ff79d0c9b6 100644
--- a/src/Microsoft.IdentityModel.Tokens/Encryption/SymmetricKeyWrapProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Encryption/SymmetricKeyWrapProvider.cs
@@ -337,7 +337,7 @@ Return an error
private void ValidateKeySize(byte[] key, string algorithm)
{
- if (SecurityAlgorithms.Aes128KW.Equals(algorithm, StringComparison.Ordinal) || SecurityAlgorithms.Aes128KeyWrap.Equals(algorithm, StringComparison.Ordinal))
+ if (SecurityAlgorithms.Aes128KW.Equals(algorithm) || SecurityAlgorithms.Aes128KeyWrap.Equals(algorithm))
{
if (key.Length != 16)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10662, LogHelper.MarkAsNonPII(algorithm), LogHelper.MarkAsNonPII(128), Key.KeyId, LogHelper.MarkAsNonPII(key.Length << 3))));
@@ -345,7 +345,15 @@ private void ValidateKeySize(byte[] key, string algorithm)
return;
}
- if (SecurityAlgorithms.Aes256KW.Equals(algorithm, StringComparison.Ordinal) || (SecurityAlgorithms.Aes256KeyWrap.Equals(algorithm, StringComparison.Ordinal)))
+ if (SecurityAlgorithms.Aes192KW.Equals(algorithm) || SecurityAlgorithms.Aes192KeyWrap.Equals(algorithm))
+ {
+ if (key.Length != 24)
+ throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10662, LogHelper.MarkAsNonPII(algorithm), LogHelper.MarkAsNonPII(128), Key.KeyId, LogHelper.MarkAsNonPII(key.Length << 3))));
+
+ return;
+ }
+
+ if (SecurityAlgorithms.Aes256KW.Equals(algorithm) || (SecurityAlgorithms.Aes256KeyWrap.Equals(algorithm)))
{
if (key.Length != 32)
throw LogHelper.LogExceptionMessage(new ArgumentOutOfRangeException(nameof(key), LogHelper.FormatInvariant(LogMessages.IDX10662, LogHelper.MarkAsNonPII(algorithm), LogHelper.MarkAsNonPII(256), Key.KeyId, LogHelper.MarkAsNonPII(key.Length << 3))));
diff --git a/src/Microsoft.IdentityModel.Tokens/EventBasedLRUCache.cs b/src/Microsoft.IdentityModel.Tokens/EventBasedLRUCache.cs
index 24a6e8b336..3ed42cec80 100644
--- a/src/Microsoft.IdentityModel.Tokens/EventBasedLRUCache.cs
+++ b/src/Microsoft.IdentityModel.Tokens/EventBasedLRUCache.cs
@@ -95,6 +95,10 @@ internal class EventBasedLRUCache
private const int EventQueueTaskDoNotStop = 2; // force the task to continue even it has past the _eventQueueTaskStopTime, see StartEventQueueTaskIfNotRunning() for more details.
private int _eventQueueTaskState = EventQueueTaskStopped;
+ private const int CompactionNotQueued = 0; // compaction action not in the event queue
+ private const int CompactionQueuedOrRunning = 1; // compaction action in the event queue or currently in progress
+ private int _compactionState = CompactionNotQueued;
+
// set to true when the AppDomain is to be unloaded or the default AppDomain process is ready to exit
private bool _shouldStopImmediately = false;
@@ -330,6 +334,9 @@ private void CompactLRU()
_doubleLinkedList.RemoveLast();
}
+
+ // reset _compactionState so the compaction action can be queued again when needed
+ _compactionState = CompactionNotQueued;
}
///
@@ -350,6 +357,9 @@ private void Compact()
OnItemRemoved?.Invoke(cacheItem.Value);
}
}
+
+ // reset _compactionState so the compaction action can be queued again when needed
+ _compactionState = CompactionNotQueued;
}
///
@@ -415,10 +425,13 @@ public bool SetValue(TKey key, TValue value, DateTime expirationTime)
// if cache is at _maxCapacityPercentage, trim it by _compactionPercentage
if ((double)_map.Count / _capacity >= _maxCapacityPercentage)
{
- if (_maintainLRU)
- _eventQueue.Enqueue(CompactLRU);
- else
- _eventQueue.Enqueue(Compact);
+ if (Interlocked.CompareExchange(ref _compactionState, CompactionQueuedOrRunning, CompactionNotQueued) == CompactionNotQueued)
+ {
+ if (_maintainLRU)
+ AddActionToEventQueue(CompactLRU);
+ else
+ AddActionToEventQueue(Compact);
+ }
}
var newCacheItem = new LRUCacheItem(key, value, expirationTime);
@@ -569,11 +582,6 @@ public bool TryRemove(TKey key, out TValue value)
///
internal void WaitForProcessing()
{
- // The _eventQueue can be non-empty only if _maintainLRU = true.
- // If _maintainLRU = false, neither the _doubleLinkedList nor _eventQueue will be used.
- if (!_maintainLRU)
- return;
-
while (!_eventQueue.IsEmpty);
}
diff --git a/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs b/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs
index 2f19b51bc4..a886ba64eb 100644
--- a/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Exceptions/SecurityTokenException.cs
@@ -76,7 +76,7 @@ protected SecurityTokenException(SerializationInfo info, StreamingContext contex
{
}
-#if NET472 || NETSTANDARD2_0
+#if NET472 || NETSTANDARD2_0 || NET6_0
///
/// When overridden in a derived class, sets the System.Runtime.Serialization.SerializationInfo
/// with information about the exception.
diff --git a/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs
index f765eb3379..86381917d7 100644
--- a/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs
+++ b/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs
@@ -17,14 +17,13 @@
[assembly: SuppressMessage("Usage", "CA2207:Initialize value type static fields inline", Justification = "Vendored component", Scope = "namespaceanddescendants", Target = "Microsoft.IdentityModel.Json")]
[assembly: SuppressMessage("Performance", "CA1810:Initialize reference type static fields inline", Justification = "Vendored component", Scope = "namespaceanddescendants", Target = "Microsoft.IdentityModel.Json")]
[assembly: SuppressMessage("Performance", "CA1825:Avoid zero-length array allocations.", Justification = "vendored", Scope = "namespaceanddescendants", Target = "Microsoft.IdentityModel.Json")]
-[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Vendored component", Scope = "namespaceanddescendants", Target = "Microsoft.IdentityModel.Json")]
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Vendored component", Scope = "module")]
[assembly: SuppressMessage("Performance", "CA1820:Test for empty strings using string length", Justification = "Vendored component", Scope = "namespaceanddescendants", Target = "Microsoft.IdentityModel.Json")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Vendored component", Scope = "namespaceanddescendants", Target = "Microsoft.IdentityModel.Json")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor.AdditionalHeaderClaims")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor.Claims")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.JsonWebKey.Oth")]
-[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.CallContext.PropertyBag")]
[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking chnage", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.TokenValidationParameters.PropertyBag")]
[assembly: SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Current design", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.TokenValidationParameters.#ctor(Microsoft.IdentityModel.Tokens.TokenValidationParameters)")]
[assembly: SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Disposed through ReleaseSignatureProvider", Scope = "member", Target = "~F:Microsoft.IdentityModel.Tokens.AuthenticatedEncryptionProvider._symmetricSignatureProvider")]
@@ -54,9 +53,12 @@
[assembly: SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "Not using Globalization", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.Interop.Kernel32.GetMessage(System.Int32,System.IntPtr)~System.String")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Exception is written to a string", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.EventBasedLRUCache`2.EventQueueTaskAction")]
[assembly: SuppressMessage("Design", "CA1001:Types That own disposable fields should be disposable", Justification = "Exceptions can occurr if disposed of", Scope = "type", Target = "~T:Microsoft.IdentityModel.Tokens.EventBasedLRUCache`2")]
+[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Consistency", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor.AdditionalInnerHeaderClaims")]
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used as validation", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.InternalValidators.ValidateLifetimeAndIssuerAfterSignatureNotValidatedJwt(Microsoft.IdentityModel.Tokens.SecurityToken,System.Nullable{System.DateTime},System.Nullable{System.DateTime},System.String,Microsoft.IdentityModel.Tokens.TokenValidationParameters,Microsoft.IdentityModel.Tokens.BaseConfiguration,System.Text.StringBuilder,System.Int32,System.Int32)")]
-#if NET472 || NETSTANDARD2_0
+#if NET472 || NETSTANDARD2_0 || NET6_0
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used to determine appropriate code path to take.", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.JsonWebKeyConverter.ConvertFromECDsaSecurityKey(Microsoft.IdentityModel.Tokens.ECDsaSecurityKey)~Microsoft.IdentityModel.Tokens.JsonWebKey")]
+[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used to determine appropriate code path to take.", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.EcdhSecurityKey.PrivateKeyStatus")]
+[assembly: SuppressMessage("Globalization", "CA1307:Specify StringComparison", Justification = "Adding StringComparison.Ordinal adds a performance penalty.", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.EcdhKeyExchangeProvider.GenerateKdf(System.String,System.String)~Microsoft.IdentityModel.Tokens.SecurityKey")]
#endif
#if !NET472
[assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Used as validation", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.ECDsaAdapter.SupportsECParameters~System.Boolean")]
diff --git a/src/Microsoft.IdentityModel.Tokens/JsonWebKey.cs b/src/Microsoft.IdentityModel.Tokens/JsonWebKey.cs
index be9a76307c..52a1628bba 100644
--- a/src/Microsoft.IdentityModel.Tokens/JsonWebKey.cs
+++ b/src/Microsoft.IdentityModel.Tokens/JsonWebKey.cs
@@ -349,11 +349,11 @@ public override bool CanComputeJwkThumbprint()
if (string.IsNullOrEmpty(Kty))
return false;
- if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.EllipticCurve, StringComparison.Ordinal))
+ if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.EllipticCurve))
return CanComputeECThumbprint();
- else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.RSA, StringComparison.Ordinal))
+ else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.RSA))
return CanComputeRsaThumbprint();
- else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.Octet, StringComparison.Ordinal))
+ else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.Octet))
return CanComputeOctThumbprint();
else
return false;
@@ -369,11 +369,11 @@ public override byte[] ComputeJwkThumbprint()
if (string.IsNullOrEmpty(Kty))
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10705, LogHelper.MarkAsNonPII(nameof(Kty)))));
- if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.EllipticCurve, StringComparison.Ordinal))
+ if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.EllipticCurve))
return ComputeECThumbprint();
- else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.RSA, StringComparison.Ordinal))
+ else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.RSA))
return ComputeRsaThumbprint();
- else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.Octet, StringComparison.Ordinal))
+ else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.Octet))
return ComputeOctThumbprint();
else
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10706, LogHelper.MarkAsNonPII(nameof(Kty)), LogHelper.MarkAsNonPII(string.Join(", ", JsonWebAlgorithmsKeyTypes.EllipticCurve, JsonWebAlgorithmsKeyTypes.RSA, JsonWebAlgorithmsKeyTypes.Octet)), LogHelper.MarkAsNonPII(nameof(Kty)))));
@@ -442,9 +442,9 @@ internal string RepresentAsAsymmetricPublicJwk()
if (!string.IsNullOrEmpty(Kid))
jwk.Add(JsonWebKeyParameterNames.Kid, Kid);
- if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.EllipticCurve, StringComparison.Ordinal))
+ if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.EllipticCurve))
PopulateWithPublicEcParams(jwk);
- else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.RSA, StringComparison.Ordinal))
+ else if (string.Equals(Kty, JsonWebAlgorithmsKeyTypes.RSA))
PopulateWithPublicRsaParams(jwk);
else
throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10707, LogHelper.MarkAsNonPII(nameof(Kty)), LogHelper.MarkAsNonPII(string.Join(", ", JsonWebAlgorithmsKeyTypes.EllipticCurve, JsonWebAlgorithmsKeyTypes.RSA)), LogHelper.MarkAsNonPII(nameof(Kty)))));
diff --git a/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs b/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
index 3f67041835..bea9c6769e 100644
--- a/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/JsonWebKeyConverter.cs
@@ -57,7 +57,7 @@ public static JsonWebKey ConvertFromSecurityKey(SecurityKey key)
return ConvertFromSymmetricSecurityKey(symmetricKey);
else if (key is X509SecurityKey x509Key)
return ConvertFromX509SecurityKey(x509Key);
-#if NET472 || NETSTANDARD2_0
+#if NET472 || NETSTANDARD2_0 || NET6_0
else if (key is ECDsaSecurityKey ecdsaSecurityKey)
return ConvertFromECDsaSecurityKey(ecdsaSecurityKey);
#endif
@@ -181,7 +181,7 @@ public static JsonWebKey ConvertFromSymmetricSecurityKey(SymmetricSecurityKey ke
};
}
-#if NET472 || NETSTANDARD2_0
+#if NET472 || NETSTANDARD2_0 || NET6_0
///
/// Converts a into a
///
@@ -233,7 +233,7 @@ internal static bool TryConvertToSecurityKey(JsonWebKey webKey, out SecurityKey
key = null;
try
{
- if (JsonWebAlgorithmsKeyTypes.RSA.Equals(webKey.Kty, StringComparison.Ordinal))
+ if (JsonWebAlgorithmsKeyTypes.RSA.Equals(webKey.Kty))
{
if (TryConvertToX509SecurityKey(webKey, out key))
return true;
@@ -241,11 +241,11 @@ internal static bool TryConvertToSecurityKey(JsonWebKey webKey, out SecurityKey
if (TryCreateToRsaSecurityKey(webKey, out key))
return true;
}
- else if (JsonWebAlgorithmsKeyTypes.EllipticCurve.Equals(webKey.Kty, StringComparison.Ordinal))
+ else if (JsonWebAlgorithmsKeyTypes.EllipticCurve.Equals(webKey.Kty))
{
return TryConvertToECDsaSecurityKey(webKey, out key);
}
- else if (JsonWebAlgorithmsKeyTypes.Octet.Equals(webKey.Kty, StringComparison.Ordinal))
+ else if (JsonWebAlgorithmsKeyTypes.Octet.Equals(webKey.Kty))
{
return TryConvertToSymmetricSecurityKey(webKey, out key);
}
diff --git a/src/Microsoft.IdentityModel.Tokens/JsonWebKeySet.cs b/src/Microsoft.IdentityModel.Tokens/JsonWebKeySet.cs
index 21047bbaf1..b021382260 100644
--- a/src/Microsoft.IdentityModel.Tokens/JsonWebKeySet.cs
+++ b/src/Microsoft.IdentityModel.Tokens/JsonWebKeySet.cs
@@ -123,7 +123,7 @@ public IList GetSigningKeys()
{
// skip if "use" (Public Key Use) parameter is not empty or "sig".
// https://datatracker.ietf.org/doc/html/rfc7517#section-4.2
- if (!string.IsNullOrEmpty(webKey.Use) && !webKey.Use.Equals(JsonWebKeyUseNames.Sig, StringComparison.Ordinal))
+ if (!string.IsNullOrEmpty(webKey.Use) && !webKey.Use.Equals(JsonWebKeyUseNames.Sig))
{
string convertKeyInfo = LogHelper.FormatInvariant(LogMessages.IDX10808, webKey, webKey.Use);
webKey.ConvertKeyInfo = convertKeyInfo;
@@ -134,7 +134,7 @@ public IList GetSigningKeys()
continue;
}
- if (JsonWebAlgorithmsKeyTypes.RSA.Equals(webKey.Kty, StringComparison.Ordinal))
+ if (JsonWebAlgorithmsKeyTypes.RSA.Equals(webKey.Kty))
{
var rsaKeyResolved = true;
@@ -167,7 +167,7 @@ public IList GetSigningKeys()
if (!rsaKeyResolved && !SkipUnresolvedJsonWebKeys)
signingKeys.Add(webKey);
}
- else if (JsonWebAlgorithmsKeyTypes.EllipticCurve.Equals(webKey.Kty, StringComparison.Ordinal))
+ else if (JsonWebAlgorithmsKeyTypes.EllipticCurve.Equals(webKey.Kty))
{
if (JsonWebKeyConverter.TryConvertToECDsaSecurityKey(webKey, out SecurityKey securityKey))
signingKeys.Add(securityKey);
diff --git a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs
index 96ae25e1e8..02cdc229e4 100644
--- a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs
+++ b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs
@@ -143,6 +143,7 @@ internal static class LogMessages
public const string IDX10618 = "IDX10618: Key unwrap failed using decryption Keys: '{0}'.\nExceptions caught:\n '{1}'.\ntoken: '{2}'.";
public const string IDX10619 = "IDX10619: Decryption failed. Algorithm: '{0}'. Either the Encryption Algorithm: '{1}' or none of the Security Keys are supported by the CryptoProviderFactory.";
public const string IDX10620 = "IDX10620: Unable to obtain a CryptoProviderFactory, both EncryptingCredentials.CryptoProviderFactory and EncryptingCredentials.Key.CrypoProviderFactory are null.";
+ public const string IDX10903 = "IDX10903: Token decryption succeeded. With thumbprint: '{0}'.";
// Formating
public const string IDX10400 = "IDX10400: Unable to decode: '{0}' as Base64url encoded string.";
@@ -260,6 +261,11 @@ internal static class LogMessages
public const string IDX10900 = "IDX10900: EventBasedLRUCache._eventQueue encountered an error while processing a cache operation. Exception '{0}'.";
public const string IDX10901 = "IDX10901: CryptoProviderCacheOptions.SizeLimit must be greater than 10. Value: '{0}'";
public const string IDX10902 = "IDX10902: Object disposed exception in '{0}': '{1}'";
+
+ // Crypto Errors
+ public const string IDX11000 = "IDX11000: Cannot create EcdhKeyExchangeProvider. '{0}'\'s Curve '{1}' does not match with '{2}'\'s curve '{3}'.";
+ public const string IDX11001 = "IDX11001: Cannot generate KDF. '{0}':'{1}' and '{2}':'{3}' must be different.";
+ public const string IDX11002 = "IDX11002: Cannot create the EcdhKeyExchangeProvider. Unable to obtain ECParameters from {0}. Verify the SecurityKey is an ECDsaSecurityKey or JsonWebKey and that properties Crv, X, Y, and D (if used for a private key) are contained in the provided SecurityKey.";
#pragma warning restore 1591
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens/Microsoft.IdentityModel.Tokens.csproj b/src/Microsoft.IdentityModel.Tokens/Microsoft.IdentityModel.Tokens.csproj
index d54ff4ea3c..b3fabb4d3a 100644
--- a/src/Microsoft.IdentityModel.Tokens/Microsoft.IdentityModel.Tokens.csproj
+++ b/src/Microsoft.IdentityModel.Tokens/Microsoft.IdentityModel.Tokens.csproj
@@ -13,11 +13,15 @@
- $(DefineConstants);TRACE;DESKTOP;HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_ASYNC;HAVE_BIG_INTEGER;HAVE_BINARY_FORMATTER;HAVE_BINARY_SERIALIZATION;HAVE_BINARY_EXCEPTION_SERIALIZATION;HAVE_CAS;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FAST_REVERSE;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_REFLECTION_EMIT;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT;HAVE_XML_DOCUMENT_TYPE;HAVE_CONCURRENT_DICTIONARY;
+ $(DefineConstants);TRACE;DESKTOP;HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_ASYNC;HAVE_BIG_INTEGER;HAVE_BINARY_FORMATTER;HAVE_BINARY_SERIALIZATION;HAVE_BINARY_EXCEPTION_SERIALIZATION;HAVE_CAS;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FAST_REVERSE;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_REFLECTION_EMIT;HAVE_REGEX_TIMEOUTS;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT;HAVE_XML_DOCUMENT_TYPE;HAVE_CONCURRENT_DICTIONARY;$(AdditionalConstants)
- $(DefineConstants);TRACE;HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_ASYNC;HAVE_BIG_INTEGER;HAVE_BINARY_FORMATTER;HAVE_BINARY_SERIALIZATION;HAVE_BINARY_EXCEPTION_SERIALIZATION;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FAST_REVERSE;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT;HAVE_XML_DOCUMENT_TYPE;HAVE_CONCURRENT_DICTIONARY;$(AdditionalConstants)
+ $(DefineConstants);TRACE;HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_ASYNC;HAVE_BIG_INTEGER;HAVE_BINARY_FORMATTER;HAVE_BINARY_SERIALIZATION;HAVE_BINARY_EXCEPTION_SERIALIZATION;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FAST_REVERSE;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT;HAVE_XML_DOCUMENT_TYPE;HAVE_CONCURRENT_DICTIONARY;HAVE_REGEX_TIMEOUTS;$(AdditionalConstants)
+
+
+
+ $(DefineConstants);HAVE_ADO_NET;HAVE_APP_DOMAIN;HAVE_ASYNC;HAVE_ASYNC_DISPOSABLE;HAVE_BIG_INTEGER;HAVE_BINARY_FORMATTER;HAVE_BINARY_SERIALIZATION;HAVE_BINARY_EXCEPTION_SERIALIZATION;HAVE_CHAR_TO_LOWER_WITH_CULTURE;HAVE_CHAR_TO_STRING_WITH_CULTURE;HAVE_COM_ATTRIBUTES;HAVE_COMPONENT_MODEL;HAVE_CONCURRENT_COLLECTIONS;HAVE_COVARIANT_GENERICS;HAVE_DATA_CONTRACTS;HAVE_DATE_TIME_OFFSET;HAVE_DB_NULL_TYPE_CODE;HAVE_DYNAMIC;HAVE_EMPTY_TYPES;HAVE_ENTITY_FRAMEWORK;HAVE_EXPRESSIONS;HAVE_FAST_REVERSE;HAVE_FSHARP_TYPES;HAVE_FULL_REFLECTION;HAVE_GUID_TRY_PARSE;HAVE_HASH_SET;HAVE_ICLONEABLE;HAVE_ICONVERTIBLE;HAVE_IGNORE_DATA_MEMBER_ATTRIBUTE;HAVE_INOTIFY_COLLECTION_CHANGED;HAVE_INOTIFY_PROPERTY_CHANGING;HAVE_ISET;HAVE_LINQ;HAVE_MEMORY_BARRIER;HAVE_METHOD_IMPL_ATTRIBUTE;HAVE_NON_SERIALIZED_ATTRIBUTE;HAVE_READ_ONLY_COLLECTIONS;HAVE_REFLECTION_EMIT;HAVE_REGEX_TIMEOUTS;HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE;HAVE_SERIALIZATION_BINDER_BIND_TO_NAME;HAVE_STREAM_READER_WRITER_CLOSE;HAVE_STRING_JOIN_WITH_ENUMERABLE;HAVE_TIME_SPAN_PARSE_WITH_CULTURE;HAVE_TIME_SPAN_TO_STRING_WITH_CULTURE;HAVE_TIME_ZONE_INFO;HAVE_TRACE_WRITER;HAVE_TYPE_DESCRIPTOR;HAVE_UNICODE_SURROGATE_DETECTION;HAVE_VARIANT_TYPE_PARAMETERS;HAVE_VERSION_TRY_PARSE;HAVE_XLINQ;HAVE_XML_DOCUMENT;HAVE_XML_DOCUMENT_TYPE;HAVE_CONCURRENT_DICTIONARY;HAVE_INDEXOF_STRING_COMPARISON;HAVE_REPLACE_STRING_COMPARISON;HAVE_REPLACE_STRING_COMPARISON;HAVE_GETHASHCODE_STRING_COMPARISON;HAVE_NULLABLE_ATTRIBUTES;HAVE_DYNAMIC_CODE_COMPILED;HAS_ARRAY_EMPTY;HAVE_DATE_ONLY;$(AdditionalConstants)
@@ -30,7 +34,7 @@
-
+
diff --git a/src/Microsoft.IdentityModel.Tokens/RsaSecurityKey.cs b/src/Microsoft.IdentityModel.Tokens/RsaSecurityKey.cs
index eacd408112..5a27d78107 100644
--- a/src/Microsoft.IdentityModel.Tokens/RsaSecurityKey.cs
+++ b/src/Microsoft.IdentityModel.Tokens/RsaSecurityKey.cs
@@ -100,7 +100,7 @@ public override bool HasPrivateKey
{
// imitate signing
byte[] hash = new byte[20];
-#if NET461 || NET472 || NETSTANDARD2_0
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
Rsa.SignData(hash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
#else
if (Rsa is RSACryptoServiceProvider rsaCryptoServiceProvider)
diff --git a/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs b/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs
index bdbafc8e04..25947ca389 100644
--- a/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs
+++ b/src/Microsoft.IdentityModel.Tokens/SecurityAlgorithms.cs
@@ -51,6 +51,7 @@ public static class SecurityAlgorithms
// See: https://datatracker.ietf.org/doc/html/rfc7518#section-4.1
public const string Aes128KW = "A128KW";
+ public const string Aes192KW = "A192KW";
public const string Aes256KW = "A256KW";
public const string RsaPKCS1 = "RSA1_5";
public const string RsaOAEP = "RSA-OAEP";
@@ -119,6 +120,13 @@ public static class SecurityAlgorithms
internal const string DefaultAsymmetricKeyWrapAlgorithm = RsaOaepKeyWrap;
internal const string DefaultSymmetricEncryptionAlgorithm = Aes128CbcHmacSha256;
+ // See: https://datatracker.ietf.org/doc/html/rfc7518#section-4.6
+ public const string EcdhEsA128kw = "ECDH-ES+A128KW";
+ public const string EcdhEsA192kw = "ECDH-ES+A192KW";
+ public const string EcdhEsA256kw = "ECDH-ES+A256KW";
+
+ // See: https://datatracker.ietf.org/doc/html/rfc7518#section-4.6
+ public const string EcdhEs = "ECDH-ES";
#pragma warning restore 1591
}
}
diff --git a/src/Microsoft.IdentityModel.Tokens/SecurityTokenDescriptor.cs b/src/Microsoft.IdentityModel.Tokens/SecurityTokenDescriptor.cs
index 483c7151fa..21fe63733a 100644
--- a/src/Microsoft.IdentityModel.Tokens/SecurityTokenDescriptor.cs
+++ b/src/Microsoft.IdentityModel.Tokens/SecurityTokenDescriptor.cs
@@ -96,6 +96,17 @@ public class SecurityTokenDescriptor
///
public IDictionary AdditionalHeaderClaims { get; set; }
+ ///
+ /// Gets or sets the which contains any custom header claims that need to be added to the inner JWT token header.
+ /// The 'alg', 'kid', 'x5t', 'enc', and 'zip' claims are added by default based on the ,
+ /// , and/or provided and SHOULD NOT be included in this dictionary as this
+ /// will result in an exception being thrown.
+ ///
+ /// For JsonWebTokenHandler, these claims are merged with while adding to the inner JWT header.
+ ///
+ ///
+ public IDictionary AdditionalInnerHeaderClaims { get; set; }
+
///
/// Gets or sets the used to create a security token.
///
diff --git a/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs b/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs
index 61d6b1d54e..88c9c6d9b5 100644
--- a/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs
+++ b/src/Microsoft.IdentityModel.Tokens/SupportedAlgorithms.cs
@@ -38,6 +38,8 @@ namespace Microsoft.IdentityModel.Tokens
///
internal static class SupportedAlgorithms
{
+ private const int RsaMinKeySize = 2048;
+
internal static readonly ICollection EcdsaSigningAlgorithms = new Collection
{
SecurityAlgorithms.EcdsaSha256,
@@ -100,8 +102,13 @@ internal static class SupportedAlgorithms
{
SecurityAlgorithms.Aes128KW,
SecurityAlgorithms.Aes128KeyWrap,
+ SecurityAlgorithms.Aes192KW,
+ SecurityAlgorithms.Aes192KeyWrap,
SecurityAlgorithms.Aes256KW,
- SecurityAlgorithms.Aes256KeyWrap
+ SecurityAlgorithms.Aes256KeyWrap,
+ SecurityAlgorithms.EcdhEsA128kw,
+ SecurityAlgorithms.EcdhEsA192kw,
+ SecurityAlgorithms.EcdhEsA256kw
};
internal static readonly ICollection SymmetricSigningAlgorithms = new Collection
@@ -114,7 +121,14 @@ internal static class SupportedAlgorithms
SecurityAlgorithms.HmacSha512Signature
};
-#if NET461 || NET472 || NETSTANDARD2_0
+ internal static readonly ICollection EcdsaWrapAlgorithms = new Collection
+ {
+ SecurityAlgorithms.EcdhEsA128kw,
+ SecurityAlgorithms.EcdhEsA192kw,
+ SecurityAlgorithms.EcdhEsA256kw
+ };
+
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
///
/// Creating a Signature requires the use of a .
/// This method returns the
@@ -236,11 +250,11 @@ public static bool IsSupportedAlgorithm(string algorithm, SecurityKey key)
if (key is JsonWebKey jsonWebKey)
{
- if (JsonWebAlgorithmsKeyTypes.RSA.Equals(jsonWebKey.Kty, StringComparison.Ordinal))
+ if (JsonWebAlgorithmsKeyTypes.RSA.Equals(jsonWebKey.Kty))
return IsSupportedRsaAlgorithm(algorithm, key);
- else if (JsonWebAlgorithmsKeyTypes.EllipticCurve.Equals(jsonWebKey.Kty, StringComparison.Ordinal))
+ else if (JsonWebAlgorithmsKeyTypes.EllipticCurve.Equals(jsonWebKey.Kty))
return IsSupportedEcdsaAlgorithm(algorithm);
- else if (JsonWebAlgorithmsKeyTypes.Octet.Equals(jsonWebKey.Kty, StringComparison.Ordinal))
+ else if (JsonWebAlgorithmsKeyTypes.Octet.Equals(jsonWebKey.Kty))
return IsSupportedSymmetricAlgorithm(algorithm);
return false;
@@ -280,9 +294,9 @@ internal static bool IsAesGcm(string algorithm)
if (string.IsNullOrEmpty(algorithm))
return false;
- return algorithm.Equals(SecurityAlgorithms.Aes128Gcm, StringComparison.Ordinal)
- || algorithm.Equals(SecurityAlgorithms.Aes192Gcm, StringComparison.Ordinal)
- || algorithm.Equals(SecurityAlgorithms.Aes256Gcm, StringComparison.Ordinal);
+ return algorithm.Equals(SecurityAlgorithms.Aes128Gcm)
+ || algorithm.Equals(SecurityAlgorithms.Aes192Gcm)
+ || algorithm.Equals(SecurityAlgorithms.Aes256Gcm);
}
internal static bool IsAesCbc(string algorithm)
@@ -290,9 +304,9 @@ internal static bool IsAesCbc(string algorithm)
if (string.IsNullOrEmpty(algorithm))
return false;
- return algorithm.Equals(SecurityAlgorithms.Aes128CbcHmacSha256, StringComparison.Ordinal)
- || algorithm.Equals(SecurityAlgorithms.Aes192CbcHmacSha384, StringComparison.Ordinal)
- || algorithm.Equals(SecurityAlgorithms.Aes256CbcHmacSha512, StringComparison.Ordinal);
+ return algorithm.Equals(SecurityAlgorithms.Aes128CbcHmacSha256)
+ || algorithm.Equals(SecurityAlgorithms.Aes192CbcHmacSha384)
+ || algorithm.Equals(SecurityAlgorithms.Aes256CbcHmacSha512);
}
private static bool IsSupportedEcdsaAlgorithm(string algorithm)
@@ -317,7 +331,7 @@ internal static bool IsSupportedRsaKeyWrap(string algorithm, SecurityKey key)
return false;
if (key is RsaSecurityKey || key is X509SecurityKey || (key is JsonWebKey rsaJsonWebKey && rsaJsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA))
- return key.KeySize >= 2048;
+ return key.KeySize >= RsaMinKeySize;
return false;
}
@@ -349,7 +363,7 @@ private static bool IsSupportedRsaPss(SecurityKey key)
// RSA-PSS is not available on .NET 4.5
LogHelper.LogInformation(LogMessages.IDX10692);
return false;
-#elif NET461 || NET472 || NETSTANDARD2_0
+#elif NET461 || NET472 || NETSTANDARD2_0 || NET6_0
// RSACryptoServiceProvider doesn't support RSA-PSS
if (key is RsaSecurityKey rsa && rsa.Rsa is RSACryptoServiceProvider)
{
diff --git a/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs b/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs
index a4a8224df0..a5b54e3142 100644
--- a/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs
+++ b/src/Microsoft.IdentityModel.Tokens/TokenUtilities.cs
@@ -78,7 +78,7 @@ internal static IDictionary CreateDictionaryFromClaims(IEnumerab
continue;
string jsonClaimType = claim.Type;
- object jsonClaimValue = claim.ValueType.Equals(ClaimValueTypes.String, StringComparison.Ordinal) ? claim.Value : GetClaimValueUsingValueType(claim);
+ object jsonClaimValue = claim.ValueType.Equals(ClaimValueTypes.String) ? claim.Value : GetClaimValueUsingValueType(claim);
object existingValue;
// If there is an existing value, append to it.
@@ -244,7 +244,7 @@ internal static bool IsRecoverableConfiguration(TokenValidationParameters valida
LogHelper.LogInformation(TokenLogMessages.IDX10263);
return false;
}
- else
+ else
currentConfiguration = validationParameters.ConfigurationManager.LastKnownGoodConfiguration;
}
diff --git a/src/Microsoft.IdentityModel.Tokens/Validators.cs b/src/Microsoft.IdentityModel.Tokens/Validators.cs
index 2ed42e92a5..608da0bfbf 100644
--- a/src/Microsoft.IdentityModel.Tokens/Validators.cs
+++ b/src/Microsoft.IdentityModel.Tokens/Validators.cs
@@ -161,7 +161,7 @@ private static bool AudiencesMatch(TokenValidationParameters validationParameter
{
if (validAudience.Length == tokenAudience.Length)
{
- if (string.Equals(validAudience, tokenAudience, StringComparison.Ordinal))
+ if (string.Equals(validAudience, tokenAudience))
return true;
}
else if (validationParameters.IgnoreTrailingSlashWhenValidatingAudience && AudiencesMatchIgnoringTrailingSlash(tokenAudience, validAudience))
@@ -236,7 +236,7 @@ internal static string ValidateIssuer(string issuer, SecurityToken securityToken
if (!validationParameters.ValidateIssuer)
{
- LogHelper.LogInformation(LogMessages.IDX10235);
+ LogHelper.LogWarning(LogMessages.IDX10235);
return issuer;
}
@@ -251,7 +251,7 @@ internal static string ValidateIssuer(string issuer, SecurityToken securityToken
if (configuration != null)
{
- if (string.Equals(configuration.Issuer, issuer, StringComparison.Ordinal))
+ if (string.Equals(configuration.Issuer, issuer))
{
LogHelper.LogInformation(LogMessages.IDX10236, issuer);
return issuer;
@@ -262,7 +262,7 @@ internal static string ValidateIssuer(string issuer, SecurityToken securityToken
{ InvalidIssuer = issuer });
}
- if (string.Equals(validationParameters.ValidIssuer, issuer, StringComparison.Ordinal))
+ if (string.Equals(validationParameters.ValidIssuer, issuer))
{
LogHelper.LogInformation(LogMessages.IDX10236, issuer);
return issuer;
@@ -278,7 +278,7 @@ internal static string ValidateIssuer(string issuer, SecurityToken securityToken
continue;
}
- if (string.Equals(str, issuer, StringComparison.Ordinal))
+ if (string.Equals(str, issuer))
{
LogHelper.LogInformation(LogMessages.IDX10236, issuer);
return issuer;
@@ -338,7 +338,7 @@ internal static void ValidateIssuerSecurityKey(SecurityKey securityKey, Security
if (!validationParameters.ValidateIssuerSigningKey)
{
- LogHelper.LogInformation(LogMessages.IDX10237);
+ LogHelper.LogVerbose(LogMessages.IDX10237);
return;
}
@@ -455,7 +455,7 @@ public static void ValidateTokenReplay(DateTime? expirationTime, string security
if (!validationParameters.ValidateTokenReplay)
{
- LogHelper.LogInformation(LogMessages.IDX10246);
+ LogHelper.LogVerbose(LogMessages.IDX10246);
return;
}
@@ -514,7 +514,7 @@ public static string ValidateTokenType(string type, SecurityToken securityToken,
if (validationParameters.TypeValidator == null && (validationParameters.ValidTypes == null || !validationParameters.ValidTypes.Any()))
{
- LogHelper.LogInformation(LogMessages.IDX10255);
+ LogHelper.LogVerbose(LogMessages.IDX10255);
return type;
}
diff --git a/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs b/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
index c5eca70c76..5ff26c44d3 100644
--- a/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
+++ b/src/Microsoft.IdentityModel.Tokens/X509SecurityKey.cs
@@ -102,7 +102,7 @@ public AsymmetricAlgorithm PrivateKey
{
if (!_privateKeyAvailabilityDetermined)
{
-#if NET461 || NET472 || NETSTANDARD2_0
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
_privateKey = RSACertificateExtensions.GetRSAPrivateKey(Certificate);
#else
_privateKey = Certificate.PrivateKey;
@@ -129,7 +129,7 @@ public AsymmetricAlgorithm PublicKey
{
if (_publicKey == null)
{
-#if NET461 || NET472 || NETSTANDARD2_0
+#if NET461 || NET472 || NETSTANDARD2_0 || NET6_0
_publicKey = RSACertificateExtensions.GetRSAPublicKey(Certificate);
#else
_publicKey = Certificate.PublicKey.Key;
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryType.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryType.cs
index 4d26ac3303..4339a46b40 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryType.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryType.cs
@@ -25,6 +25,8 @@
using System;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Bson
{
internal enum BsonBinaryType : byte
@@ -41,4 +43,4 @@ internal enum BsonBinaryType : byte
Md5 = 0x05,
UserDefined = 0x80
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryWriter.cs
index 459d43517b..db528596c7 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonBinaryWriter.cs
@@ -29,6 +29,8 @@
using System.Text;
using Microsoft.IdentityModel.Json.Utilities;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Bson
{
internal class BsonBinaryWriter
@@ -325,4 +327,4 @@ private int CalculateSize(BsonToken t)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonObjectId.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonObjectId.cs
index 64f8bb8fcb..6ba12b3bca 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonObjectId.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonObjectId.cs
@@ -26,6 +26,8 @@
using System;
using Microsoft.IdentityModel.Json.Utilities;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Bson
{
///
@@ -55,4 +57,4 @@ public BsonObjectId(byte[] value)
Value = value;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonReader.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonReader.cs
index 3c1b2860bf..a69af510ea 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonReader.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonReader.cs
@@ -32,6 +32,8 @@
using Microsoft.IdentityModel.Json.Utilities;
using Microsoft.IdentityModel.Json.Linq;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Bson
{
///
@@ -831,4 +833,4 @@ private byte[] ReadBytes(int count)
return _reader.ReadBytes(count);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonToken.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonToken.cs
index a3ea597844..46baeed080 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonToken.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonToken.cs
@@ -26,6 +26,8 @@
using System.Collections;
using System.Collections.Generic;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Bson
{
internal abstract class BsonToken
@@ -163,4 +165,4 @@ internal class BsonProperty
public BsonString Name { get; set; }
public BsonToken Value { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonType.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonType.cs
index b204f90a11..9861a871cf 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonType.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonType.cs
@@ -23,6 +23,8 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Bson
{
internal enum BsonType : sbyte
@@ -48,4 +50,4 @@ internal enum BsonType : sbyte
MinKey = -1,
MaxKey = 127
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonWriter.cs
index 9f72ee7c41..279007125a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Bson/BsonWriter.cs
@@ -35,6 +35,8 @@
using Microsoft.IdentityModel.Json.Linq;
using System.Globalization;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Bson
{
///
@@ -390,9 +392,7 @@ public override void WriteValue(char value)
#if HAVE_CHAR_TO_STRING_WITH_CULTURE
s = value.ToString(CultureInfo.InvariantCulture);
#else
-#pragma warning disable CA1305 // Specify IFormatProvider
s = value.ToString();
-#pragma warning restore CA1305 // Specify IFormatProvider
#endif
AddToken(new BsonString(s, true));
}
@@ -536,4 +536,4 @@ public void WriteRegex(string pattern, string options)
AddToken(new BsonRegex(pattern, options));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/ConstructorHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/ConstructorHandling.cs
index 914691bff6..ab6635a09b 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/ConstructorHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/ConstructorHandling.cs
@@ -40,4 +40,4 @@ internal enum ConstructorHandling
///
AllowNonPublicDefaultConstructor = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BinaryConverter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BinaryConverter.cs
index ec24a6171b..2c4dba4054 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BinaryConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BinaryConverter.cs
@@ -28,14 +28,14 @@
using System.Globalization;
using Microsoft.IdentityModel.Json.Utilities;
using System.Collections.Generic;
-using System.Reflection;
-
+using System.Diagnostics;
#if HAVE_ADO_NET
using System.Data.SqlTypes;
#endif
namespace Microsoft.IdentityModel.Json.Converters
{
+#nullable enable
///
/// Converts a binary value to and from a base 64 string value.
///
@@ -44,7 +44,7 @@ internal class BinaryConverter : JsonConverter
#if HAVE_LINQ
private const string BinaryTypeName = "System.Data.Linq.Binary";
private const string BinaryToArrayName = "ToArray";
- private static ReflectionObject _reflectionObject;
+ private static ReflectionObject? _reflectionObject;
#endif
///
@@ -53,7 +53,7 @@ internal class BinaryConverter : JsonConverter
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
@@ -72,7 +72,9 @@ private byte[] GetByteArray(object value)
if (value.GetType().FullName == BinaryTypeName)
{
EnsureReflectionObject(value.GetType());
- return (byte[])_reflectionObject.GetValue(value, BinaryToArrayName);
+ MiscellaneousUtils.Assert(_reflectionObject != null);
+
+ return (byte[])_reflectionObject.GetValue(value, BinaryToArrayName)!;
}
#endif
#if HAVE_ADO_NET
@@ -103,7 +105,7 @@ private static void EnsureReflectionObject(Type t)
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -125,7 +127,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
{
// current token is already at base64 string
// unable to call ReadAsBytes so do it the old fashion way
- string encodedData = reader.Value.ToString();
+ string encodedData = reader.Value!.ToString()!;
data = Convert.FromBase64String(encodedData);
}
else
@@ -134,15 +136,16 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
}
Type t = (ReflectionUtils.IsNullableType(objectType))
- ? Nullable.GetUnderlyingType(objectType)
+ ? Nullable.GetUnderlyingType(objectType)!
: objectType;
#if HAVE_LINQ
if (t.FullName == BinaryTypeName)
{
EnsureReflectionObject(t);
+ MiscellaneousUtils.Assert(_reflectionObject != null);
- return _reflectionObject.Creator(data);
+ return _reflectionObject.Creator!(data);
}
#endif
@@ -205,6 +208,7 @@ public override bool CanConvert(Type objectType)
return false;
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BsonObjectIdConverter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BsonObjectIdConverter.cs
index 6680627462..304fd28254 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BsonObjectIdConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/BsonObjectIdConverter.cs
@@ -88,4 +88,4 @@ public override bool CanConvert(Type objectType)
return (objectType == typeof(BsonObjectId));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/CustomCreationConverter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/CustomCreationConverter.cs
index 3b40a4f96d..0fadd80d9f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/CustomCreationConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/CustomCreationConverter.cs
@@ -29,6 +29,7 @@
namespace Microsoft.IdentityModel.Json.Converters
{
+#nullable enable
///
/// Creates a custom object.
///
@@ -41,7 +42,7 @@ internal abstract class CustomCreationConverter : JsonConverter
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
}
@@ -54,7 +55,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -98,4 +99,5 @@ public override bool CanConvert(Type objectType)
///
public override bool CanWrite => false;
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataSetConverter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataSetConverter.cs
index a94c4beae4..08c57e8f80 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataSetConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataSetConverter.cs
@@ -30,6 +30,7 @@
namespace Microsoft.IdentityModel.Json.Converters
{
+#nullable enable
///
/// Converts a to and from JSON.
///
@@ -41,7 +42,7 @@ internal class DataSetConverter : JsonConverter
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
@@ -50,7 +51,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
}
DataSet dataSet = (DataSet)value;
- DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
+ DefaultContractResolver? resolver = serializer.ContractResolver as DefaultContractResolver;
DataTableConverter converter = new DataTableConverter();
@@ -74,7 +75,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -84,7 +85,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
// handle typed datasets
DataSet ds = (objectType == typeof(DataSet))
? new DataSet()
- : (DataSet)Activator.CreateInstance(objectType);
+ : (DataSet)Activator.CreateInstance(objectType)!;
DataTableConverter converter = new DataTableConverter();
@@ -92,10 +93,10 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
while (reader.TokenType == JsonToken.PropertyName)
{
- DataTable dt = ds.Tables[(string)reader.Value];
+ DataTable? dt = ds.Tables[(string)reader.Value!];
bool exists = (dt != null);
- dt = (DataTable)converter.ReadJson(reader, typeof(DataTable), dt, serializer);
+ dt = (DataTable)converter.ReadJson(reader, typeof(DataTable), dt, serializer)!;
if (!exists)
{
@@ -120,6 +121,7 @@ public override bool CanConvert(Type valueType)
return typeof(DataSet).IsAssignableFrom(valueType);
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataTableConverter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataTableConverter.cs
index 247994e293..47f0eda861 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataTableConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Converters/DataTableConverter.cs
@@ -34,6 +34,7 @@
namespace Microsoft.IdentityModel.Json.Converters
{
+#nullable enable
///
/// Converts a to and from JSON.
///
@@ -45,7 +46,7 @@ internal class DataTableConverter : JsonConverter
/// The to write to.
/// The value.
/// The calling serializer.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
@@ -54,7 +55,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
}
DataTable table = (DataTable)value;
- DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver;
+ DefaultContractResolver? resolver = serializer.ContractResolver as DefaultContractResolver;
writer.WriteStartArray();
@@ -87,7 +88,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
@@ -99,14 +100,14 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
// handle typed datasets
dt = (objectType == typeof(DataTable))
? new DataTable()
- : (DataTable)Activator.CreateInstance(objectType);
+ : (DataTable)Activator.CreateInstance(objectType)!;
}
// DataTable is inside a DataSet
// populate the name from the property name
if (reader.TokenType == JsonToken.PropertyName)
{
- dt.TableName = (string)reader.Value;
+ dt.TableName = (string)reader.Value!;
reader.ReadAndAssert();
@@ -140,11 +141,11 @@ private static void CreateRow(JsonReader reader, DataTable dt, JsonSerializer se
while (reader.TokenType == JsonToken.PropertyName)
{
- string columnName = (string)reader.Value;
+ string columnName = (string)reader.Value!;
reader.ReadAndAssert();
- DataColumn column = dt.Columns[columnName];
+ DataColumn? column = dt.Columns[columnName];
if (column == null)
{
Type columnType = GetColumnDataType(reader);
@@ -177,7 +178,7 @@ private static void CreateRow(JsonReader reader, DataTable dt, JsonSerializer se
reader.ReadAndAssert();
}
- List
DefaultValue = 2
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/FloatParseHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/FloatParseHandling.cs
index 751d778c35..4cf55a85da 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/FloatParseHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/FloatParseHandling.cs
@@ -40,4 +40,4 @@ internal enum FloatParseHandling
///
Decimal = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/FormatterAssemblyStyle.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/FormatterAssemblyStyle.cs
index b3ba268508..4504af98ba 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/FormatterAssemblyStyle.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/FormatterAssemblyStyle.cs
@@ -21,4 +21,4 @@ internal enum FormatterAssemblyStyle
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Formatting.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Formatting.cs
index b637fcd1b9..5d86facdfe 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Formatting.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Formatting.cs
@@ -40,4 +40,4 @@ internal enum Formatting
///
Indented = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/IArrayPool.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/IArrayPool.cs
index c27b800b21..acaf2eec5b 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/IArrayPool.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/IArrayPool.cs
@@ -1,5 +1,6 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Provides an interface for using pooled arrays.
///
@@ -17,6 +18,7 @@ internal interface IArrayPool
/// Return an array to the pool.
///
/// The array that is being returned.
- void Return(T[] array);
+ void Return(T[]? array);
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/IJsonLineInfo.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/IJsonLineInfo.cs
index e75650bd91..158c82c5ae 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/IJsonLineInfo.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/IJsonLineInfo.cs
@@ -50,4 +50,4 @@ internal interface IJsonLineInfo
/// The current line position or 0 if no line information is available (for example, when returns false).
int LinePosition { get; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonArrayAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonArrayAttribute.cs
index 1a9b5ba33d..4278754b46 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonArrayAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonArrayAttribute.cs
@@ -70,4 +70,4 @@ public JsonArrayAttribute(string id)
{
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConstructorAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConstructorAttribute.cs
index 68a61733e8..1e9c91d1c8 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConstructorAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConstructorAttribute.cs
@@ -34,4 +34,4 @@ namespace Microsoft.IdentityModel.Json
internal sealed class JsonConstructorAttribute : Attribute
{
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonContainerAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonContainerAttribute.cs
index a3d3a67eff..06b23e7500 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonContainerAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonContainerAttribute.cs
@@ -28,6 +28,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Instructs the how to serialize the object.
///
@@ -38,25 +39,25 @@ internal abstract class JsonContainerAttribute : Attribute
/// Gets or sets the id.
///
/// The id.
- public string Id { get; set; }
+ public string? Id { get; set; }
///
/// Gets or sets the title.
///
/// The title.
- public string Title { get; set; }
+ public string? Title { get; set; }
///
/// Gets or sets the description.
///
/// The description.
- public string Description { get; set; }
+ public string? Description { get; set; }
///
/// Gets or sets the collection's items converter.
///
/// The collection's items converter.
- public Type ItemConverterType { get; set; }
+ public Type? ItemConverterType { get; set; }
///
/// The parameter list to use when constructing the described by .
@@ -69,13 +70,13 @@ internal abstract class JsonContainerAttribute : Attribute
/// [JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
///
///
- public object[] ItemConverterParameters { get; set; }
+ public object[]? ItemConverterParameters { get; set; }
///
/// Gets or sets the of the .
///
/// The of the .
- public Type NamingStrategyType
+ public Type? NamingStrategyType
{
get => _namingStrategyType;
set
@@ -96,7 +97,7 @@ public Type NamingStrategyType
/// [JsonContainer(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
///
///
- public object[] NamingStrategyParameters
+ public object[]? NamingStrategyParameters
{
get => _namingStrategyParameters;
set
@@ -106,7 +107,7 @@ public object[] NamingStrategyParameters
}
}
- internal NamingStrategy NamingStrategyInstance { get; set; }
+ internal NamingStrategy? NamingStrategyInstance { get; set; }
// yuck. can't set nullable properties on an attribute in C#
// have to use this approach to get an unset default state
@@ -114,8 +115,8 @@ public object[] NamingStrategyParameters
internal bool? _itemIsReference;
internal ReferenceLoopHandling? _itemReferenceLoopHandling;
internal TypeNameHandling? _itemTypeNameHandling;
- private Type _namingStrategyType;
- private object[] _namingStrategyParameters;
+ private Type? _namingStrategyType;
+ private object[]? _namingStrategyParameters;
///
/// Gets or sets a value that indicates whether to preserve object references.
@@ -177,4 +178,5 @@ protected JsonContainerAttribute(string id)
Id = id;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConvert.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConvert.cs
index da2582d9fa..97ef41fda9 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConvert.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConvert.cs
@@ -36,13 +36,16 @@
using Microsoft.IdentityModel.Json.Serialization;
using System.Text;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if HAVE_XLINQ
using System.Xml.Linq;
-
#endif
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
///
/// Provides methods for converting between .NET types and JSON types.
///
@@ -58,7 +61,7 @@ internal static class JsonConvert
/// To serialize without using any default settings create a with
/// .
///
- public static Func DefaultSettings { get; set; }
+ public static Func? DefaultSettings { get; set; }
///
/// Represents JavaScript's boolean value true as a string. This field is read-only.
@@ -209,7 +212,7 @@ public static string ToString(short value)
///
/// The value to convert.
/// A JSON string representation of the .
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static string ToString(ushort value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
@@ -220,7 +223,7 @@ public static string ToString(ushort value)
///
/// The value to convert.
/// A JSON string representation of the .
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static string ToString(uint value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
@@ -248,7 +251,7 @@ private static string ToStringInternal(BigInteger value)
///
/// The value to convert.
/// A JSON string representation of the .
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static string ToString(ulong value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
@@ -301,7 +304,7 @@ internal static string ToString(double value, FloatFormatHandling floatFormatHan
private static string EnsureDecimalPlace(double value, string text)
{
- if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1)
+ if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1)
{
return text;
}
@@ -311,7 +314,7 @@ private static string EnsureDecimalPlace(double value, string text)
private static string EnsureDecimalPlace(string text)
{
- if (text.IndexOf('.') != -1)
+ if (StringUtils.IndexOf(text, '.') != -1)
{
return text;
}
@@ -334,7 +337,7 @@ public static string ToString(byte value)
///
/// The value to convert.
/// A JSON string representation of the .
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static string ToString(sbyte value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
@@ -344,7 +347,7 @@ public static string ToString(sbyte value)
/// Converts the to its JSON string representation.
///
/// The value to convert.
- /// A JSON string representation of the .
+ /// A JSON string representation of the .
public static string ToString(decimal value)
{
return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
@@ -368,10 +371,8 @@ internal static string ToString(Guid value, char quoteChar)
text = value.ToString("D", CultureInfo.InvariantCulture);
qc = quoteChar.ToString(CultureInfo.InvariantCulture);
#else
-#pragma warning disable CA1305 // Specify IFormatProvider
text = value.ToString("D");
qc = quoteChar.ToString();
-#pragma warning restore CA1305 // Specify IFormatProvider
#endif
return qc + text + qc;
@@ -397,7 +398,7 @@ internal static string ToString(TimeSpan value, char quoteChar)
///
/// The value to convert.
/// A JSON string representation of the .
- public static string ToString(Uri value)
+ public static string ToString(Uri? value)
{
if (value == null)
{
@@ -417,7 +418,7 @@ internal static string ToString(Uri value, char quoteChar)
///
/// The value to convert.
/// A JSON string representation of the .
- public static string ToString(string value)
+ public static string ToString(string? value)
{
return ToString(value, '"');
}
@@ -428,7 +429,7 @@ public static string ToString(string value)
/// The value to convert.
/// The string delimiter character.
/// A JSON string representation of the .
- public static string ToString(string value, char delimiter)
+ public static string ToString(string? value, char delimiter)
{
return ToString(value, delimiter, StringEscapeHandling.Default);
}
@@ -440,7 +441,7 @@ public static string ToString(string value, char delimiter)
/// The string delimiter character.
/// The string escape handling.
/// A JSON string representation of the .
- public static string ToString(string value, char delimiter, StringEscapeHandling stringEscapeHandling)
+ public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
{
if (delimiter != '"' && delimiter != '\'')
{
@@ -455,7 +456,7 @@ public static string ToString(string value, char delimiter, StringEscapeHandling
///
/// The value to convert.
/// A JSON string representation of the .
- public static string ToString(object value)
+ public static string ToString(object? value)
{
if (value == null)
{
@@ -526,9 +527,9 @@ public static string ToString(object value)
/// The object to serialize.
/// A JSON string representation of the object.
[DebuggerStepThrough]
- public static string SerializeObject(object value)
+ public static string SerializeObject(object? value)
{
- return SerializeObject(value, null, (JsonSerializerSettings)null);
+ return SerializeObject(value, null, (JsonSerializerSettings?)null);
}
///
@@ -540,9 +541,9 @@ public static string SerializeObject(object value)
/// A JSON string representation of the object.
///
[DebuggerStepThrough]
- public static string SerializeObject(object value, Formatting formatting)
+ public static string SerializeObject(object? value, Formatting formatting)
{
- return SerializeObject(value, formatting, (JsonSerializerSettings)null);
+ return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
}
///
@@ -552,9 +553,9 @@ public static string SerializeObject(object value, Formatting formatting)
/// A collection of converters used while serializing.
/// A JSON string representation of the object.
[DebuggerStepThrough]
- public static string SerializeObject(object value, params JsonConverter[] converters)
+ public static string SerializeObject(object? value, params JsonConverter[] converters)
{
- JsonSerializerSettings settings = (converters != null && converters.Length > 0)
+ JsonSerializerSettings? settings = (converters != null && converters.Length > 0)
? new JsonSerializerSettings { Converters = converters }
: null;
@@ -569,9 +570,9 @@ public static string SerializeObject(object value, params JsonConverter[] conver
/// A collection of converters used while serializing.
/// A JSON string representation of the object.
[DebuggerStepThrough]
- public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters)
+ public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
{
- JsonSerializerSettings settings = (converters != null && converters.Length > 0)
+ JsonSerializerSettings? settings = (converters != null && converters.Length > 0)
? new JsonSerializerSettings { Converters = converters }
: null;
@@ -588,7 +589,7 @@ public static string SerializeObject(object value, Formatting formatting, params
/// A JSON string representation of the object.
///
[DebuggerStepThrough]
- public static string SerializeObject(object value, JsonSerializerSettings settings)
+ public static string SerializeObject(object? value, JsonSerializerSettings? settings)
{
return SerializeObject(value, null, settings);
}
@@ -608,7 +609,7 @@ public static string SerializeObject(object value, JsonSerializerSettings settin
/// A JSON string representation of the object.
///
[DebuggerStepThrough]
- public static string SerializeObject(object value, Type type, JsonSerializerSettings settings)
+ public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
@@ -626,7 +627,7 @@ public static string SerializeObject(object value, Type type, JsonSerializerSett
/// A JSON string representation of the object.
///
[DebuggerStepThrough]
- public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings)
+ public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
{
return SerializeObject(value, null, formatting, settings);
}
@@ -647,7 +648,7 @@ public static string SerializeObject(object value, Formatting formatting, JsonSe
/// A JSON string representation of the object.
///
[DebuggerStepThrough]
- public static string SerializeObject(object value, Type type, Formatting formatting, JsonSerializerSettings settings)
+ public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
jsonSerializer.Formatting = formatting;
@@ -655,7 +656,7 @@ public static string SerializeObject(object value, Type type, Formatting formatt
return SerializeObjectInternal(value, type, jsonSerializer);
}
- private static string SerializeObjectInternal(object value, Type type, JsonSerializer jsonSerializer)
+ private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
{
StringBuilder sb = new StringBuilder(256);
StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
@@ -677,9 +678,9 @@ private static string SerializeObjectInternal(object value, Type type, JsonSeria
/// The JSON to deserialize.
/// The deserialized object from the JSON string.
[DebuggerStepThrough]
- public static object DeserializeObject(string value)
+ public static object? DeserializeObject(string value)
{
- return DeserializeObject(value, null, (JsonSerializerSettings)null);
+ return DeserializeObject(value, null, (JsonSerializerSettings?)null);
}
///
@@ -692,7 +693,7 @@ public static object DeserializeObject(string value)
///
/// The deserialized object from the JSON string.
[DebuggerStepThrough]
- public static object DeserializeObject(string value, JsonSerializerSettings settings)
+ public static object? DeserializeObject(string value, JsonSerializerSettings settings)
{
return DeserializeObject(value, null, settings);
}
@@ -704,9 +705,9 @@ public static object DeserializeObject(string value, JsonSerializerSettings sett
/// The of object being deserialized.
/// The deserialized object from the JSON string.
[DebuggerStepThrough]
- public static object DeserializeObject(string value, Type type)
+ public static object? DeserializeObject(string value, Type type)
{
- return DeserializeObject(value, type, (JsonSerializerSettings)null);
+ return DeserializeObject(value, type, (JsonSerializerSettings?)null);
}
///
@@ -716,9 +717,9 @@ public static object DeserializeObject(string value, Type type)
/// The JSON to deserialize.
/// The deserialized object from the JSON string.
[DebuggerStepThrough]
- public static T DeserializeObject(string value)
+ public static T? DeserializeObject(string value)
{
- return DeserializeObject(value, (JsonSerializerSettings)null);
+ return DeserializeObject(value, (JsonSerializerSettings?)null);
}
///
@@ -733,7 +734,7 @@ public static T DeserializeObject(string value)
/// The anonymous type object.
/// The deserialized anonymous type from the JSON string.
[DebuggerStepThrough]
- public static T DeserializeAnonymousType(string value, T anonymousTypeObject)
+ public static T? DeserializeAnonymousType(string value, T anonymousTypeObject)
{
return DeserializeObject(value);
}
@@ -754,7 +755,7 @@ public static T DeserializeAnonymousType(string value, T anonymousTypeObject)
///
/// The deserialized anonymous type from the JSON string.
[DebuggerStepThrough]
- public static T DeserializeAnonymousType(string value, T anonymousTypeObject, JsonSerializerSettings settings)
+ public static T? DeserializeAnonymousType(string value, T anonymousTypeObject, JsonSerializerSettings settings)
{
return DeserializeObject(value, settings);
}
@@ -767,9 +768,9 @@ public static T DeserializeAnonymousType(string value, T anonymousTypeObject,
/// Converters to use while deserializing.
/// The deserialized object from the JSON string.
[DebuggerStepThrough]
- public static T DeserializeObject(string value, params JsonConverter[] converters)
+ public static T? DeserializeObject(string value, params JsonConverter[] converters)
{
- return (T)DeserializeObject(value, typeof(T), converters);
+ return (T?)DeserializeObject(value, typeof(T), converters);
}
///
@@ -783,9 +784,9 @@ public static T DeserializeObject(string value, params JsonConverter[] conver
///
/// The deserialized object from the JSON string.
[DebuggerStepThrough]
- public static T DeserializeObject(string value, JsonSerializerSettings settings)
+ public static T? DeserializeObject(string value, JsonSerializerSettings? settings)
{
- return (T)DeserializeObject(value, typeof(T), settings);
+ return (T?)DeserializeObject(value, typeof(T), settings);
}
///
@@ -796,9 +797,9 @@ public static T DeserializeObject(string value, JsonSerializerSettings settin
/// Converters to use while deserializing.
/// The deserialized object from the JSON string.
[DebuggerStepThrough]
- public static object DeserializeObject(string value, Type type, params JsonConverter[] converters)
+ public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
{
- JsonSerializerSettings settings = (converters != null && converters.Length > 0)
+ JsonSerializerSettings? settings = (converters != null && converters.Length > 0)
? new JsonSerializerSettings { Converters = converters }
: null;
@@ -815,7 +816,7 @@ public static object DeserializeObject(string value, Type type, params JsonConve
/// If this is null, default serialization settings will be used.
///
/// The deserialized object from the JSON string.
- public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings)
+ public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
@@ -855,7 +856,7 @@ public static void PopulateObject(string value, object target)
/// The used to deserialize the object.
/// If this is null, default serialization settings will be used.
///
- public static void PopulateObject(string value, object target, JsonSerializerSettings settings)
+ public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
@@ -884,7 +885,7 @@ public static void PopulateObject(string value, object target, JsonSerializerSet
///
/// The node to serialize.
/// A JSON string of the .
- public static string SerializeXmlNode(XmlNode node)
+ public static string SerializeXmlNode(XmlNode? node)
{
return SerializeXmlNode(node, Formatting.None);
}
@@ -895,7 +896,7 @@ public static string SerializeXmlNode(XmlNode node)
/// The node to serialize.
/// Indicates how the output should be formatted.
/// A JSON string of the .
- public static string SerializeXmlNode(XmlNode node, Formatting formatting)
+ public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
{
XmlNodeConverter converter = new XmlNodeConverter();
@@ -909,7 +910,7 @@ public static string SerializeXmlNode(XmlNode node, Formatting formatting)
/// Indicates how the output should be formatted.
/// Omits writing the root object.
/// A JSON string of the .
- public static string SerializeXmlNode(XmlNode node, Formatting formatting, bool omitRootObject)
+ public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
{
XmlNodeConverter converter = new XmlNodeConverter { OmitRootObject = omitRootObject };
@@ -921,7 +922,7 @@ public static string SerializeXmlNode(XmlNode node, Formatting formatting, bool
///
/// The JSON string.
/// The deserialized .
- public static XmlDocument DeserializeXmlNode(string value)
+ public static XmlDocument? DeserializeXmlNode(string value)
{
return DeserializeXmlNode(value, null);
}
@@ -932,7 +933,7 @@ public static XmlDocument DeserializeXmlNode(string value)
/// The JSON string.
/// The name of the root element to append when deserializing.
/// The deserialized .
- public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName)
+ public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
{
return DeserializeXmlNode(value, deserializeRootElementName, false);
}
@@ -948,7 +949,7 @@ public static XmlDocument DeserializeXmlNode(string value, string deserializeRoo
/// This attribute helps preserve arrays when converting the written XML back to JSON.
///
/// The deserialized .
- public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
+ public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
{
return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, false);
}
@@ -970,14 +971,14 @@ public static XmlDocument DeserializeXmlNode(string value, string deserializeRoo
/// as part of the XML element name.
///
/// The deserialized .
- public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
+ public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
{
XmlNodeConverter converter = new XmlNodeConverter();
converter.DeserializeRootElementName = deserializeRootElementName;
converter.WriteArrayAttribute = writeArrayAttribute;
converter.EncodeSpecialCharacters = encodeSpecialCharacters;
- return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), converter);
+ return (XmlDocument?)DeserializeObject(value, typeof(XmlDocument), converter);
}
#endif
@@ -987,7 +988,7 @@ public static XmlDocument DeserializeXmlNode(string value, string deserializeRoo
///
/// The node to convert to JSON.
/// A JSON string of the .
- public static string SerializeXNode(XObject node)
+ public static string SerializeXNode(XObject? node)
{
return SerializeXNode(node, Formatting.None);
}
@@ -998,7 +999,7 @@ public static string SerializeXNode(XObject node)
/// The node to convert to JSON.
/// Indicates how the output should be formatted.
/// A JSON string of the .
- public static string SerializeXNode(XObject node, Formatting formatting)
+ public static string SerializeXNode(XObject? node, Formatting formatting)
{
return SerializeXNode(node, formatting, false);
}
@@ -1010,7 +1011,7 @@ public static string SerializeXNode(XObject node, Formatting formatting)
/// Indicates how the output should be formatted.
/// Omits writing the root object.
/// A JSON string of the .
- public static string SerializeXNode(XObject node, Formatting formatting, bool omitRootObject)
+ public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
{
XmlNodeConverter converter = new XmlNodeConverter { OmitRootObject = omitRootObject };
@@ -1022,7 +1023,7 @@ public static string SerializeXNode(XObject node, Formatting formatting, bool om
///
/// The JSON string.
/// The deserialized .
- public static XDocument DeserializeXNode(string value)
+ public static XDocument? DeserializeXNode(string value)
{
return DeserializeXNode(value, null);
}
@@ -1033,7 +1034,7 @@ public static XDocument DeserializeXNode(string value)
/// The JSON string.
/// The name of the root element to append when deserializing.
/// The deserialized .
- public static XDocument DeserializeXNode(string value, string deserializeRootElementName)
+ public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
{
return DeserializeXNode(value, deserializeRootElementName, false);
}
@@ -1049,7 +1050,7 @@ public static XDocument DeserializeXNode(string value, string deserializeRootEle
/// This attribute helps preserve arrays when converting the written XML back to JSON.
///
/// The deserialized .
- public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
+ public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
{
return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, false);
}
@@ -1071,16 +1072,18 @@ public static XDocument DeserializeXNode(string value, string deserializeRootEle
/// as part of the XML element name.
///
/// The deserialized .
- public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
+ public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
{
XmlNodeConverter converter = new XmlNodeConverter();
converter.DeserializeRootElementName = deserializeRootElementName;
converter.WriteArrayAttribute = writeArrayAttribute;
converter.EncodeSpecialCharacters = encodeSpecialCharacters;
- return (XDocument)DeserializeObject(value, typeof(XDocument), converter);
+ return (XDocument?)DeserializeObject(value, typeof(XDocument), converter);
}
#endif
#endregion
}
-}
\ No newline at end of file
+#nullable disable
+#pragma warning restore CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverter.cs
index 3258f419d5..e4498b65d3 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverter.cs
@@ -26,10 +26,12 @@
using System;
using Microsoft.IdentityModel.Json.Utilities;
using System.Globalization;
-using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Converts an object to and from JSON.
///
@@ -41,7 +43,7 @@ internal abstract class JsonConverter
/// The to write to.
/// The value.
/// The calling serializer.
- public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);
+ public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);
///
/// Reads the JSON representation of the object.
@@ -51,7 +53,7 @@ internal abstract class JsonConverter
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);
+ public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);
///
/// Determines whether this instance can convert the specified object type.
@@ -87,13 +89,13 @@ internal abstract class JsonConverter : JsonConverter
/// The to write to.
/// The value.
/// The calling serializer.
- public sealed override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (!(value != null ? value is T : ReflectionUtils.IsNullable(typeof(T))))
{
throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
}
- WriteJson(writer, (T)value, serializer);
+ WriteJson(writer, (T?)value, serializer);
}
///
@@ -102,7 +104,7 @@ public sealed override void WriteJson(JsonWriter writer, object value, JsonSeria
/// The to write to.
/// The value.
/// The calling serializer.
- public abstract void WriteJson(JsonWriter writer, T value, JsonSerializer serializer);
+ public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);
///
/// Reads the JSON representation of the object.
@@ -112,14 +114,14 @@ public sealed override void WriteJson(JsonWriter writer, object value, JsonSeria
/// The existing value of object being read.
/// The calling serializer.
/// The object value.
- public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
bool existingIsNull = existingValue == null;
if (!(existingIsNull || existingValue is T))
{
throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
}
- return ReadJson(reader, objectType, existingIsNull ? default : (T)existingValue, !existingIsNull, serializer);
+ return ReadJson(reader, objectType, existingIsNull ? default : (T?)existingValue, !existingIsNull, serializer);
}
///
@@ -131,7 +133,7 @@ public sealed override object ReadJson(JsonReader reader, Type objectType, objec
/// The existing value has a value.
/// The calling serializer.
/// The object value.
- public abstract T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer);
+ public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);
///
/// Determines whether this instance can convert the specified object type.
@@ -145,4 +147,5 @@ public sealed override bool CanConvert(Type objectType)
return typeof(T).IsAssignableFrom(objectType);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterAttribute.cs
index 8e705cc284..9530ffa741 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterAttribute.cs
@@ -29,6 +29,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Instructs the to use the specified when serializing the member or class.
///
@@ -47,7 +48,7 @@ internal sealed class JsonConverterAttribute : Attribute
/// The parameter list to use when constructing the described by .
/// If null, the default constructor is used.
///
- public object[] ConverterParameters { get; }
+ public object[]? ConverterParameters { get; }
///
/// Initializes a new instance of the class.
@@ -74,4 +75,5 @@ public JsonConverterAttribute(Type converterType, params object[] converterParam
ConverterParameters = converterParameters;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterCollection.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterCollection.cs
index d18bb835e5..7815db6279 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterCollection.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonConverterCollection.cs
@@ -36,4 +36,4 @@ namespace Microsoft.IdentityModel.Json
internal class JsonConverterCollection : Collection
{
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonDictionaryAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonDictionaryAttribute.cs
index 0506804545..482815ae7a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonDictionaryAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonDictionaryAttribute.cs
@@ -49,4 +49,4 @@ public JsonDictionaryAttribute(string id)
{
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonException.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonException.cs
index 99aea061e9..20f23dc9e7 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonException.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonException.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// The exception thrown when an error occurs during JSON serialization or deserialization.
///
@@ -63,7 +64,7 @@ public JsonException(string message)
///
/// The error message that explains the reason for the exception.
/// The exception that is the cause of the current exception, or null if no inner exception is specified.
- public JsonException(string message, Exception innerException)
+ public JsonException(string message, Exception? innerException)
: base(message, innerException)
{
}
@@ -89,4 +90,5 @@ internal static JsonException Create(IJsonLineInfo lineInfo, string path, string
return new JsonException(message);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonExtensionDataAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonExtensionDataAttribute.cs
index a5cf6431ec..6b9fe37b20 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonExtensionDataAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonExtensionDataAttribute.cs
@@ -34,4 +34,4 @@ public JsonExtensionDataAttribute()
ReadData = true;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonIgnoreAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonIgnoreAttribute.cs
index 69b8258e53..f64b35c209 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonIgnoreAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonIgnoreAttribute.cs
@@ -36,4 +36,4 @@ namespace Microsoft.IdentityModel.Json
internal sealed class JsonIgnoreAttribute : Attribute
{
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonNameTable.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonNameTable.cs
index d291237aaf..083e0b5083 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonNameTable.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonNameTable.cs
@@ -1,16 +1,19 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Base class for a table of atomized string objects.
///
internal abstract class JsonNameTable
{
///
- /// Gets the string containing the same characters as the specified range of characters in the given array.
+ /// Gets a string containing the same characters as the specified range of characters in the given array.
///
/// The character array containing the name to find.
/// The zero-based index into the array specifying the first character of the name.
/// The number of characters in the name.
- public abstract string Get(char[] key, int start, int length);
+ /// A string containing the same characters as the specified range of characters in the given array.
+ public abstract string? Get(char[] key, int start, int length);
}
+#nullable disable
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonObjectAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonObjectAttribute.cs
index 09b2c6b42a..b0911e28f1 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonObjectAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonObjectAttribute.cs
@@ -34,6 +34,7 @@ namespace Microsoft.IdentityModel.Json
internal sealed class JsonObjectAttribute : JsonContainerAttribute
{
private MemberSerialization _memberSerialization = MemberSerialization.OptOut;
+ internal MissingMemberHandling? _missingMemberHandling;
// yuck. can't set nullable properties on an attribute in C#
// have to use this approach to get an unset default state
@@ -50,6 +51,16 @@ public MemberSerialization MemberSerialization
set => _memberSerialization = value;
}
+ ///
+ /// Gets or sets the missing member handling used when deserializing this object.
+ ///
+ /// The missing member handling.
+ public MissingMemberHandling MissingMemberHandling
+ {
+ get => _missingMemberHandling ?? default;
+ set => _missingMemberHandling = value;
+ }
+
///
/// Gets or sets how the object's properties with null values are handled during serialization and deserialization.
///
@@ -97,4 +108,4 @@ public JsonObjectAttribute(string id)
{
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPosition.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPosition.cs
index efa9e2bd44..69454760f5 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPosition.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPosition.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
internal enum JsonContainerType
{
None = 0,
@@ -46,7 +47,7 @@ internal struct JsonPosition
internal JsonContainerType Type;
internal int Position;
- internal string PropertyName;
+ internal string? PropertyName;
internal bool HasIndex;
public JsonPosition(JsonContainerType type)
@@ -62,7 +63,7 @@ internal int CalculateLength()
switch (Type)
{
case JsonContainerType.Object:
- return PropertyName.Length + 5;
+ return PropertyName!.Length + 5;
case JsonContainerType.Array:
case JsonContainerType.Constructor:
return MathUtils.IntLength((ulong)Position) + 2;
@@ -71,12 +72,12 @@ internal int CalculateLength()
}
}
- internal void WriteTo(StringBuilder sb, ref StringWriter writer, ref char[] buffer)
+ internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
{
switch (Type)
{
case JsonContainerType.Object:
- string propertyName = PropertyName;
+ string propertyName = PropertyName!;
if (propertyName.IndexOfAny(SpecialCharacters) != -1)
{
sb.Append(@"['");
@@ -130,8 +131,8 @@ internal static string BuildPath(List positions, JsonPosition? cur
}
StringBuilder sb = new StringBuilder(capacity);
- StringWriter writer = null;
- char[] buffer = null;
+ StringWriter? writer = null;
+ char[]? buffer = null;
if (positions != null)
{
foreach (JsonPosition state in positions)
@@ -147,7 +148,7 @@ internal static string BuildPath(List positions, JsonPosition? cur
return sb.ToString();
}
- internal static string FormatMessage(IJsonLineInfo lineInfo, string path, string message)
+ internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
{
// don't add a fullstop and space when message ends with a new line
if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
@@ -174,4 +175,5 @@ internal static string FormatMessage(IJsonLineInfo lineInfo, string path, string
return message;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPropertyAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPropertyAttribute.cs
index 6771badb22..837a5c0d1d 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPropertyAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonPropertyAttribute.cs
@@ -28,6 +28,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Instructs the to always serialize the member with the specified name.
///
@@ -52,7 +53,7 @@ internal sealed class JsonPropertyAttribute : Attribute
/// Gets or sets the type used when serializing the property's collection items.
///
/// The collection's items type.
- public Type ItemConverterType { get; set; }
+ public Type? ItemConverterType { get; set; }
///
/// The parameter list to use when constructing the described by .
@@ -65,13 +66,13 @@ internal sealed class JsonPropertyAttribute : Attribute
/// [JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })]
///
///
- public object[] ItemConverterParameters { get; set; }
+ public object[]? ItemConverterParameters { get; set; }
///
/// Gets or sets the of the .
///
/// The of the .
- public Type NamingStrategyType { get; set; }
+ public Type? NamingStrategyType { get; set; }
///
/// The parameter list to use when constructing the described by .
@@ -84,7 +85,7 @@ internal sealed class JsonPropertyAttribute : Attribute
/// [JsonProperty(NamingStrategyType = typeof(MyNamingStrategy), NamingStrategyParameters = new object[] { 123, "Four" })]
///
///
- public object[] NamingStrategyParameters { get; set; }
+ public object[]? NamingStrategyParameters { get; set; }
///
/// Gets or sets the null value handling used when serializing this property.
@@ -172,7 +173,7 @@ public Required Required
/// Gets or sets the name of the property.
///
/// The name of the property.
- public string PropertyName { get; set; }
+ public string? PropertyName { get; set; }
///
/// Gets or sets the reference loop handling used when serializing the property's collection items.
@@ -220,4 +221,5 @@ public JsonPropertyAttribute(string propertyName)
PropertyName = propertyName;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.Async.cs
index c6c29c42ab..8e7780e379 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.Async.cs
@@ -33,8 +33,27 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
internal abstract partial class JsonReader
+#if HAVE_ASYNC_DISPOABLE
+ : IAsyncDisposable
+#endif
{
+#if HAVE_ASYNC_DISPOABLE
+ ValueTask IAsyncDisposable.DisposeAsync()
+ {
+ try
+ {
+ Dispose(true);
+ return default;
+ }
+ catch (Exception exc)
+ {
+ return ValueTask.FromException(exc);
+ }
+ }
+#endif
+
///
/// Asynchronously reads the next JSON token from the source.
///
@@ -101,12 +120,12 @@ internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken
/// property returns the []. This result will be null at the end of an array.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task ReadAsBytesAsync(CancellationToken cancellationToken = default)
+ public virtual Task ReadAsBytesAsync(CancellationToken cancellationToken = default)
{
- return cancellationToken.CancelIfRequestedAsync() ?? Task.FromResult(ReadAsBytes());
+ return cancellationToken.CancelIfRequestedAsync() ?? Task.FromResult(ReadAsBytes());
}
- internal async Task ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
+ internal async Task ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
{
List buffer = new List();
@@ -199,9 +218,9 @@ internal async Task ReadArrayIntoByteArrayAsync(CancellationToken cancel
/// property returns the . This result will be null at the end of an array.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task ReadAsStringAsync(CancellationToken cancellationToken = default)
+ public virtual Task ReadAsStringAsync(CancellationToken cancellationToken = default)
{
- return cancellationToken.CancelIfRequestedAsync() ?? Task.FromResult(ReadAsString());
+ return cancellationToken.CancelIfRequestedAsync() ?? Task.FromResult(ReadAsString());
}
internal async Task ReadAndMoveToContentAsync(CancellationToken cancellationToken)
@@ -241,6 +260,7 @@ private async Task MoveToContentFromNonContentAsync(CancellationToken canc
}
}
}
+#nullable disable
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.cs
index 68a31cbd9a..7ea341c3cb 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReader.cs
@@ -35,6 +35,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data.
///
@@ -113,18 +114,18 @@ protected internal enum State
// current Token data
private JsonToken _tokenType;
- private object _value;
+ private object? _value;
internal char _quoteChar;
internal State _currentState;
private JsonPosition _currentPosition;
- private CultureInfo _culture;
+ private CultureInfo? _culture;
private DateTimeZoneHandling _dateTimeZoneHandling;
private int? _maxDepth;
private bool _hasExceededMaxDepth;
internal DateParseHandling _dateParseHandling;
internal FloatParseHandling _floatParseHandling;
- private string _dateFormatString;
- private List _stack;
+ private string? _dateFormatString;
+ private List? _stack;
///
/// Gets the current reader state.
@@ -219,7 +220,7 @@ public FloatParseHandling FloatParseHandling
///
/// Gets or sets how custom date formatted strings are parsed when reading JSON.
///
- public string DateFormatString
+ public string? DateFormatString
{
get => _dateFormatString;
set => _dateFormatString = value;
@@ -227,6 +228,8 @@ public string DateFormatString
///
/// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a .
+ /// A null value means there is no maximum.
+ /// The default value is 64.
///
public int? MaxDepth
{
@@ -243,19 +246,19 @@ public int? MaxDepth
}
///
- /// Gets the type of the current JSON token.
+ /// Gets the type of the current JSON token.
///
public virtual JsonToken TokenType => _tokenType;
///
/// Gets the text value of the current JSON token.
///
- public virtual object Value => _value;
+ public virtual object? Value => _value;
///
/// Gets the .NET type for the current JSON token.
///
- public virtual Type ValueType => _value?.GetType();
+ public virtual Type? ValueType => _value?.GetType();
///
/// Gets the depth of the current token in the JSON document.
@@ -278,7 +281,7 @@ public virtual int Depth
}
///
- /// Gets the path of the current JSON token.
+ /// Gets the path of the current JSON token.
///
public virtual string Path
{
@@ -295,7 +298,7 @@ public virtual string Path
JsonPosition? current = insideContainer ? (JsonPosition?)_currentPosition : null;
- return JsonPosition.BuildPath(_stack, current);
+ return JsonPosition.BuildPath(_stack!, current);
}
}
@@ -327,6 +330,7 @@ protected JsonReader()
_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
_dateParseHandling = DateParseHandling.DateTime;
_floatParseHandling = FloatParseHandling.Double;
+ _maxDepth = 64;
CloseInput = true;
}
@@ -408,7 +412,7 @@ private JsonContainerType Peek()
return null;
case JsonToken.Integer:
case JsonToken.Float:
- object v = Value;
+ object v = Value!;
if (v is int i)
{
return i;
@@ -436,16 +440,16 @@ private JsonContainerType Peek()
SetToken(JsonToken.Integer, i, false);
return i;
case JsonToken.String:
- string s = (string)Value;
+ string? s = (string?)Value;
return ReadInt32String(s);
}
throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
}
- internal int? ReadInt32String(string s)
+ internal int? ReadInt32String(string? s)
{
- if (string.IsNullOrEmpty(s))
+ if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, false);
return null;
@@ -467,7 +471,7 @@ private JsonContainerType Peek()
/// Reads the next JSON token from the source as a .
///
/// A . This method will return null at the end of an array.
- public virtual string ReadAsString()
+ public virtual string? ReadAsString()
{
JsonToken t = GetContentToken();
@@ -478,12 +482,12 @@ public virtual string ReadAsString()
case JsonToken.EndArray:
return null;
case JsonToken.String:
- return (string)Value;
+ return (string?)Value;
}
if (JsonTokenUtils.IsPrimitiveToken(t))
{
- object v = Value;
+ object? v = Value;
if (v != null)
{
string s;
@@ -493,7 +497,7 @@ public virtual string ReadAsString()
}
else
{
- s = v is Uri uri ? uri.OriginalString : v.ToString();
+ s = v is Uri uri ? uri.OriginalString : v.ToString()!;
}
SetToken(JsonToken.String, s, false);
@@ -508,7 +512,7 @@ public virtual string ReadAsString()
/// Reads the next JSON token from the source as a [].
///
/// A [] or null if the next JSON token is null. This method will return null at the end of an array.
- public virtual byte[] ReadAsBytes()
+ public virtual byte[]? ReadAsBytes()
{
JsonToken t = GetContentToken();
@@ -518,7 +522,7 @@ public virtual byte[] ReadAsBytes()
{
ReadIntoWrappedTypeObject();
- byte[] data = ReadAsBytes();
+ byte[]? data = ReadAsBytes();
ReaderReadAndAssert();
if (TokenType != JsonToken.EndObject)
@@ -533,7 +537,7 @@ public virtual byte[] ReadAsBytes()
{
// attempt to convert possible base 64 or GUID string to bytes
// GUID has to have format 00000000-0000-0000-0000-000000000000
- string s = (string)Value;
+ string s = (string)Value!;
byte[] data;
@@ -565,7 +569,7 @@ public virtual byte[] ReadAsBytes()
return data;
}
- return (byte[])Value;
+ return (byte[]?)Value;
case JsonToken.StartArray:
return ReadArrayIntoByteArray();
}
@@ -627,7 +631,7 @@ private bool ReadArrayElementIntoByteArrayReportDone(List buffer)
return null;
case JsonToken.Integer:
case JsonToken.Float:
- object v = Value;
+ object v = Value!;
if (v is double d)
{
return d;
@@ -648,15 +652,15 @@ private bool ReadArrayElementIntoByteArrayReportDone(List buffer)
return (double)d;
case JsonToken.String:
- return ReadDoubleString((string)Value);
+ return ReadDoubleString((string?)Value);
}
throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
}
- internal double? ReadDoubleString(string s)
+ internal double? ReadDoubleString(string? s)
{
- if (string.IsNullOrEmpty(s))
+ if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, false);
return null;
@@ -705,17 +709,17 @@ private bool ReadArrayElementIntoByteArrayReportDone(List buffer)
SetToken(JsonToken.Boolean, b, false);
return b;
case JsonToken.String:
- return ReadBooleanString((string)Value);
+ return ReadBooleanString((string?)Value);
case JsonToken.Boolean:
- return (bool)Value;
+ return (bool)Value!;
}
throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
}
- internal bool? ReadBooleanString(string s)
+ internal bool? ReadBooleanString(string? s)
{
- if (string.IsNullOrEmpty(s))
+ if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, false);
return null;
@@ -749,8 +753,8 @@ private bool ReadArrayElementIntoByteArrayReportDone(List buffer)
return null;
case JsonToken.Integer:
case JsonToken.Float:
- object v = Value;
-
+ object v = Value!;
+
if (v is decimal d)
{
return d;
@@ -778,15 +782,15 @@ private bool ReadArrayElementIntoByteArrayReportDone(List buffer)
SetToken(JsonToken.Float, d, false);
return d;
case JsonToken.String:
- return ReadDecimalString((string)Value);
+ return ReadDecimalString((string?)Value);
}
throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
}
- internal decimal? ReadDecimalString(string s)
+ internal decimal? ReadDecimalString(string? s)
{
- if (string.IsNullOrEmpty(s))
+ if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, false);
return null;
@@ -830,18 +834,17 @@ private bool ReadArrayElementIntoByteArrayReportDone(List buffer)
}
#endif
- return (DateTime)Value;
+ return (DateTime)Value!;
case JsonToken.String:
- string s = (string)Value;
- return ReadDateTimeString(s);
+ return ReadDateTimeString((string?)Value);
}
throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
- internal DateTime? ReadDateTimeString(string s)
+ internal DateTime? ReadDateTimeString(string? s)
{
- if (string.IsNullOrEmpty(s))
+ if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, false);
return null;
@@ -885,18 +888,18 @@ private bool ReadArrayElementIntoByteArrayReportDone(List buffer)
SetToken(JsonToken.Date, new DateTimeOffset(time), false);
}
- return (DateTimeOffset)Value;
+ return (DateTimeOffset)Value!;
case JsonToken.String:
- string s = (string)Value;
+ string? s = (string?)Value;
return ReadDateTimeOffsetString(s);
default:
throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t));
}
}
- internal DateTimeOffset? ReadDateTimeOffsetString(string s)
+ internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
{
- if (string.IsNullOrEmpty(s))
+ if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, false);
return null;
@@ -938,7 +941,7 @@ internal void ReadIntoWrappedTypeObject()
if (Value != null && Value.ToString() == JsonTypeReflector.TypePropertyName)
{
ReaderReadAndAssert();
- if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
+ if (Value != null && Value.ToString()!.StartsWith("System.Byte[]", StringComparison.Ordinal))
{
ReaderReadAndAssert();
if (Value.ToString() == JsonTypeReflector.ValuePropertyName)
@@ -985,7 +988,7 @@ protected void SetToken(JsonToken newToken)
///
/// The new token.
/// The value.
- protected void SetToken(JsonToken newToken, object value)
+ protected void SetToken(JsonToken newToken, object? value)
{
SetToken(newToken, value, true);
}
@@ -996,7 +999,7 @@ protected void SetToken(JsonToken newToken, object value)
/// The new token.
/// The value.
/// A flag indicating whether the position index inside an array should be updated.
- protected void SetToken(JsonToken newToken, object value, bool updateIndex)
+ protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
{
_tokenType = newToken;
_value = value;
@@ -1027,7 +1030,7 @@ protected void SetToken(JsonToken newToken, object value, bool updateIndex)
case JsonToken.PropertyName:
_currentState = State.Property;
- _currentPosition.PropertyName = (string)value;
+ _currentPosition.PropertyName = (string)value!;
break;
case JsonToken.Undefined:
case JsonToken.Integer:
@@ -1133,7 +1136,9 @@ private JsonContainerType GetTypeForCloseToken(JsonToken token)
}
}
+#pragma warning disable CA1063 // Implement IDisposable Correctly
void IDisposable.Dispose()
+#pragma warning restore CA1063 // Implement IDisposable Correctly
{
Dispose(true);
GC.SuppressFinalize(this);
@@ -1170,7 +1175,7 @@ internal void ReadAndAssert()
}
}
- internal void ReadForTypeAndAssert(JsonContract contract, bool hasConverter)
+ internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
{
if (!ReadForType(contract, hasConverter))
{
@@ -1178,7 +1183,7 @@ internal void ReadForTypeAndAssert(JsonContract contract, bool hasConverter)
}
}
- internal bool ReadForType(JsonContract contract, bool hasConverter)
+ internal bool ReadForType(JsonContract? contract, bool hasConverter)
{
// don't read properties with converters as a specific value
// the value might be a string which will then get converted which will error if read as date for example
@@ -1273,4 +1278,5 @@ private JsonToken GetContentToken()
return t;
}
}
+#nullable disable
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReaderException.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReaderException.cs
index 7cc8b9785e..a48fbf1ed8 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReaderException.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonReaderException.cs
@@ -30,6 +30,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// The exception thrown when an error occurs while reading JSON text.
///
@@ -54,7 +55,7 @@ internal class JsonReaderException : JsonException
/// Gets the path to the JSON where the error occurred.
///
/// The path to the JSON where the error occurred.
- public string Path { get; }
+ public string? Path { get; }
///
/// Initializes a new instance of the class.
@@ -107,7 +108,7 @@ public JsonReaderException(SerializationInfo info, StreamingContext context)
/// The line number indicating where the error occurred.
/// The line position indicating where the error occurred.
/// The exception that is the cause of the current exception, or null if no inner exception is specified.
- public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception innerException)
+ public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
: base(message, innerException)
{
Path = path;
@@ -120,12 +121,12 @@ internal static JsonReaderException Create(JsonReader reader, string message)
return Create(reader, message, null);
}
- internal static JsonReaderException Create(JsonReader reader, string message, Exception ex)
+ internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
{
return Create(reader as IJsonLineInfo, reader.Path, message, ex);
}
- internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
+ internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
{
message = JsonPosition.FormatMessage(lineInfo, path, message);
@@ -145,4 +146,5 @@ internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path,
return new JsonReaderException(message, path, lineNumber, linePosition, ex);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonRequiredAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonRequiredAttribute.cs
index 07d97acb11..e78a57e372 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonRequiredAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonRequiredAttribute.cs
@@ -36,4 +36,4 @@ namespace Microsoft.IdentityModel.Json
internal sealed class JsonRequiredAttribute : Attribute
{
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializationException.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializationException.cs
index 36dab27f22..ba6645be20 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializationException.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializationException.cs
@@ -30,6 +30,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// The exception thrown when an error occurs during JSON serialization or deserialization.
///
@@ -54,7 +55,7 @@ internal class JsonSerializationException : JsonException
/// Gets the path to the JSON where the error occurred.
///
/// The path to the JSON where the error occurred.
- public string Path { get; }
+ public string? Path { get; }
///
/// Initializes a new instance of the class.
@@ -107,7 +108,7 @@ public JsonSerializationException(SerializationInfo info, StreamingContext conte
/// The line number indicating where the error occurred.
/// The line position indicating where the error occurred.
/// The exception that is the cause of the current exception, or null if no inner exception is specified.
- public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception innerException)
+ public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
: base(message, innerException)
{
Path = path;
@@ -120,12 +121,12 @@ internal static JsonSerializationException Create(JsonReader reader, string mess
return Create(reader, message, null);
}
- internal static JsonSerializationException Create(JsonReader reader, string message, Exception ex)
+ internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
{
return Create(reader as IJsonLineInfo, reader.Path, message, ex);
}
- internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
+ internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
{
message = JsonPosition.FormatMessage(lineInfo, path, message);
@@ -145,4 +146,5 @@ internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string
return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializer.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializer.cs
index 0767b97824..b15f47c954 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializer.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializer.cs
@@ -35,9 +35,12 @@
using Microsoft.IdentityModel.Json.Utilities;
using System.Runtime.Serialization;
using ErrorEventArgs = Microsoft.IdentityModel.Json.Serialization.ErrorEventArgs;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Serializes and deserializes objects into and from the JSON format.
/// The enables you to control how objects are encoded into JSON.
@@ -54,13 +57,13 @@ internal class JsonSerializer
internal DefaultValueHandling _defaultValueHandling;
internal ConstructorHandling _constructorHandling;
internal MetadataPropertyHandling _metadataPropertyHandling;
- internal JsonConverterCollection _converters;
+ internal JsonConverterCollection? _converters;
internal IContractResolver _contractResolver;
- internal ITraceWriter _traceWriter;
- internal IEqualityComparer _equalityComparer;
+ internal ITraceWriter? _traceWriter;
+ internal IEqualityComparer? _equalityComparer;
internal ISerializationBinder _serializationBinder;
internal StreamingContext _context;
- private IReferenceResolver _referenceResolver;
+ private IReferenceResolver? _referenceResolver;
private Formatting? _formatting;
private DateFormatHandling? _dateFormatHandling;
@@ -73,18 +76,18 @@ internal class JsonSerializer
private int? _maxDepth;
private bool _maxDepthSet;
private bool? _checkAdditionalContent;
- private string _dateFormatString;
+ private string? _dateFormatString;
private bool _dateFormatStringSet;
///
/// Occurs when the errors during serialization and deserialization.
///
- public virtual event EventHandler Error;
+ public virtual event EventHandler? Error;
///
/// Gets or sets the used by the serializer when resolving references.
///
- public virtual IReferenceResolver ReferenceResolver
+ public virtual IReferenceResolver? ReferenceResolver
{
get => GetReferenceResolver();
set
@@ -98,41 +101,36 @@ public virtual IReferenceResolver ReferenceResolver
}
}
- /////
- ///// Gets or sets the used by the serializer when resolving type names.
- /////
- //[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
- //public virtual SerializationBinder Binder
- //{
- // get
- // {
- // if (_serializationBinder == null)
- // {
- // return null;
- // }
-
- // if (_serializationBinder is SerializationBinder legacySerializationBinder)
- // {
- // return legacySerializationBinder;
- // }
-
- // if (_serializationBinder is SerializationBinderAdapter adapter)
- // {
- // return adapter.SerializationBinder;
- // }
-
- // throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
- // }
- // set
- // {
- // if (value == null)
- // {
- // throw new ArgumentNullException(nameof(value), "Serialization binder cannot be null.");
- // }
-
- // _serializationBinder = value as ISerializationBinder ?? new SerializationBinderAdapter(value);
- // }
- //}
+ ///
+ /// Gets or sets the used by the serializer when resolving type names.
+ ///
+ [Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
+ public virtual SerializationBinder Binder
+ {
+ get
+ {
+ if (_serializationBinder is SerializationBinder legacySerializationBinder)
+ {
+ return legacySerializationBinder;
+ }
+
+ if (_serializationBinder is SerializationBinderAdapter adapter)
+ {
+ return adapter.SerializationBinder;
+ }
+
+ throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value), "Serialization binder cannot be null.");
+ }
+
+ _serializationBinder = value as ISerializationBinder ?? new SerializationBinderAdapter(value);
+ }
+ }
///
/// Gets or sets the used by the serializer when resolving type names.
@@ -155,7 +153,7 @@ public virtual ISerializationBinder SerializationBinder
/// Gets or sets the used by the serializer when writing trace messages.
///
/// The trace writer.
- public virtual ITraceWriter TraceWriter
+ public virtual ITraceWriter? TraceWriter
{
get => _traceWriter;
set => _traceWriter = value;
@@ -165,7 +163,7 @@ public virtual ITraceWriter TraceWriter
/// Gets or sets the equality comparer used by the serializer when comparing references.
///
/// The equality comparer.
- public virtual IEqualityComparer EqualityComparer
+ public virtual IEqualityComparer? EqualityComparer
{
get => _equalityComparer;
set => _equalityComparer = value;
@@ -517,7 +515,7 @@ public virtual CultureInfo Culture
///
/// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a .
/// A null value means there is no maximum.
- /// The default value is null.
+ /// The default value is 64.
///
public virtual int? MaxDepth
{
@@ -575,12 +573,12 @@ public JsonSerializer()
///
/// Creates a new instance.
- /// The will not use default settings
+ /// The will not use default settings
/// from .
///
///
/// A new instance.
- /// The will not use default settings
+ /// The will not use default settings
/// from .
///
public static JsonSerializer Create()
@@ -590,16 +588,16 @@ public static JsonSerializer Create()
///
/// Creates a new instance using the specified .
- /// The will not use default settings
+ /// The will not use default settings
/// from .
///
/// The settings to be applied to the .
///
/// A new instance using the specified .
- /// The will not use default settings
+ /// The will not use default settings
/// from .
///
- public static JsonSerializer Create(JsonSerializerSettings settings)
+ public static JsonSerializer Create(JsonSerializerSettings? settings)
{
JsonSerializer serializer = Create();
@@ -613,34 +611,34 @@ public static JsonSerializer Create(JsonSerializerSettings settings)
///
/// Creates a new instance.
- /// The will use default settings
+ /// The will use default settings
/// from .
///
///
/// A new instance.
- /// The will use default settings
+ /// The will use default settings
/// from .
///
public static JsonSerializer CreateDefault()
{
// copy static to local variable to avoid concurrency issues
- JsonSerializerSettings defaultSettings = JsonConvert.DefaultSettings?.Invoke();
+ JsonSerializerSettings? defaultSettings = JsonConvert.DefaultSettings?.Invoke();
return Create(defaultSettings);
}
///
/// Creates a new instance using the specified .
- /// The will use default settings
+ /// The will use default settings
/// from as well as the specified .
///
/// The settings to be applied to the .
///
/// A new instance using the specified .
- /// The will use default settings
+ /// The will use default settings
/// from as well as the specified .
///
- public static JsonSerializer CreateDefault(JsonSerializerSettings settings)
+ public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
{
JsonSerializer serializer = CreateDefault();
if (settings != null)
@@ -814,14 +812,14 @@ internal virtual void PopulateInternal(JsonReader reader, object target)
SetupReader(
reader,
- out CultureInfo previousCulture,
+ out CultureInfo? previousCulture,
out DateTimeZoneHandling? previousDateTimeZoneHandling,
out DateParseHandling? previousDateParseHandling,
out FloatParseHandling? previousFloatParseHandling,
out int? previousMaxDepth,
- out string previousDateFormatString);
+ out string? previousDateFormatString);
- TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
+ TraceJsonReader? traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
? CreateTraceJsonReader(reader)
: null;
@@ -830,7 +828,7 @@ internal virtual void PopulateInternal(JsonReader reader, object target)
if (traceJsonReader != null)
{
- TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
+ TraceWriter!.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
}
ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
@@ -842,20 +840,20 @@ internal virtual void PopulateInternal(JsonReader reader, object target)
/// The that contains the JSON structure to deserialize.
/// The being deserialized.
[DebuggerStepThrough]
- public object Deserialize(JsonReader reader)
+ public object? Deserialize(JsonReader reader)
{
return Deserialize(reader, null);
}
///
- /// Deserializes the JSON structure contained by the specified
+ /// Deserializes the JSON structure contained by the specified
/// into an instance of the specified type.
///
/// The containing the object.
/// The of object being deserialized.
/// The instance of being deserialized.
[DebuggerStepThrough]
- public object Deserialize(TextReader reader, Type objectType)
+ public object? Deserialize(TextReader reader, Type objectType)
{
return Deserialize(new JsonTextReader(reader), objectType);
}
@@ -868,9 +866,9 @@ public object Deserialize(TextReader reader, Type objectType)
/// The type of the object to deserialize.
/// The instance of being deserialized.
[DebuggerStepThrough]
- public T Deserialize(JsonReader reader)
+ public T? Deserialize(JsonReader reader)
{
- return (T)Deserialize(reader, typeof(T));
+ return (T?)Deserialize(reader, typeof(T));
}
///
@@ -881,34 +879,34 @@ public T Deserialize(JsonReader reader)
/// The of object being deserialized.
/// The instance of being deserialized.
[DebuggerStepThrough]
- public object Deserialize(JsonReader reader, Type objectType)
+ public object? Deserialize(JsonReader reader, Type? objectType)
{
return DeserializeInternal(reader, objectType);
}
- internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
+ internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
SetupReader(
reader,
- out CultureInfo previousCulture,
+ out CultureInfo? previousCulture,
out DateTimeZoneHandling? previousDateTimeZoneHandling,
out DateParseHandling? previousDateParseHandling,
out FloatParseHandling? previousFloatParseHandling,
out int? previousMaxDepth,
- out string previousDateFormatString);
+ out string? previousDateFormatString);
- TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
+ TraceJsonReader? traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
? CreateTraceJsonReader(reader)
: null;
JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
- object value = serializerReader.Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
+ object? value = serializerReader.Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
if (traceJsonReader != null)
{
- TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
+ TraceWriter!.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
}
ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
@@ -916,7 +914,7 @@ internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
return value;
}
- private void SetupReader(JsonReader reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString)
+ internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
{
if (_culture != null && !_culture.Equals(reader.Culture))
{
@@ -987,7 +985,7 @@ private void SetupReader(JsonReader reader, out CultureInfo previousCulture, out
}
}
- private void ResetReader(JsonReader reader, CultureInfo previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string previousDateFormatString)
+ private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString)
{
// reset reader back to previous options
if (previousCulture != null)
@@ -1028,7 +1026,7 @@ private void ResetReader(JsonReader reader, CultureInfo previousCulture, DateTim
///
/// The used to write the JSON structure.
/// The to serialize.
- public void Serialize(TextWriter textWriter, object value)
+ public void Serialize(TextWriter textWriter, object? value)
{
Serialize(new JsonTextWriter(textWriter), value);
}
@@ -1044,7 +1042,7 @@ public void Serialize(TextWriter textWriter, object value)
/// This parameter is used when is to write out the type name if the type of the value does not match.
/// Specifying the type is optional.
///
- public void Serialize(JsonWriter jsonWriter, object value, Type objectType)
+ public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType)
{
SerializeInternal(jsonWriter, value, objectType);
}
@@ -1060,7 +1058,7 @@ public void Serialize(JsonWriter jsonWriter, object value, Type objectType)
/// This parameter is used when is Auto to write out the type name if the type of the value does not match.
/// Specifying the type is optional.
///
- public void Serialize(TextWriter textWriter, object value, Type objectType)
+ public void Serialize(TextWriter textWriter, object? value, Type objectType)
{
Serialize(new JsonTextWriter(textWriter), value, objectType);
}
@@ -1071,7 +1069,7 @@ public void Serialize(TextWriter textWriter, object value, Type objectType)
///
/// The used to write the JSON structure.
/// The to serialize.
- public void Serialize(JsonWriter jsonWriter, object value)
+ public void Serialize(JsonWriter jsonWriter, object? value)
{
SerializeInternal(jsonWriter, value, null);
}
@@ -1087,7 +1085,7 @@ private TraceJsonReader CreateTraceJsonReader(JsonReader reader)
return traceReader;
}
- internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType)
+ internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType)
{
ValidationUtils.ArgumentNotNull(jsonWriter, nameof(jsonWriter));
@@ -1127,21 +1125,21 @@ internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Typ
jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
}
- CultureInfo previousCulture = null;
+ CultureInfo? previousCulture = null;
if (_culture != null && !_culture.Equals(jsonWriter.Culture))
{
previousCulture = jsonWriter.Culture;
jsonWriter.Culture = _culture;
}
- string previousDateFormatString = null;
+ string? previousDateFormatString = null;
if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
{
previousDateFormatString = jsonWriter.DateFormatString;
jsonWriter.DateFormatString = _dateFormatString;
}
- TraceJsonWriter traceJsonWriter = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
+ TraceJsonWriter? traceJsonWriter = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
? new TraceJsonWriter(jsonWriter)
: null;
@@ -1150,7 +1148,7 @@ internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Typ
if (traceJsonWriter != null)
{
- TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
+ TraceWriter!.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
}
// reset writer back to previous options
@@ -1194,12 +1192,12 @@ internal IReferenceResolver GetReferenceResolver()
return _referenceResolver;
}
- internal JsonConverter GetMatchingConverter(Type type)
+ internal JsonConverter? GetMatchingConverter(Type type)
{
return GetMatchingConverter(_converters, type);
}
- internal static JsonConverter GetMatchingConverter(IList converters, Type objectType)
+ internal static JsonConverter? GetMatchingConverter(IList? converters, Type objectType)
{
#if DEBUG
ValidationUtils.ArgumentNotNull(objectType, nameof(objectType));
@@ -1226,4 +1224,5 @@ internal void OnError(ErrorEventArgs e)
Error?.Invoke(this, e);
}
}
+#nullable disable
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializerSettings.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializerSettings.cs
index b8907cc390..8486499e64 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializerSettings.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonSerializerSettings.cs
@@ -31,9 +31,16 @@
using Microsoft.IdentityModel.Json.Serialization;
using System.Runtime.Serialization;
using System.Diagnostics;
+using System.Runtime;
+#if !HAVE_LINQ
+using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
+#else
+using System.Linq;
+#endif
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// Specifies the settings on a object.
///
@@ -61,6 +68,7 @@ internal class JsonSerializerSettings
internal static readonly CultureInfo DefaultCulture;
internal const bool DefaultCheckAdditionalContent = false;
internal const string DefaultDateFormatString = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
+ internal const int DefaultMaxDepth = 64;
internal Formatting? _formatting;
internal DateFormatHandling? _dateFormatHandling;
@@ -69,11 +77,11 @@ internal class JsonSerializerSettings
internal FloatFormatHandling? _floatFormatHandling;
internal FloatParseHandling? _floatParseHandling;
internal StringEscapeHandling? _stringEscapeHandling;
- internal CultureInfo _culture;
+ internal CultureInfo? _culture;
internal bool? _checkAdditionalContent;
internal int? _maxDepth;
internal bool _maxDepthSet;
- internal string _dateFormatString;
+ internal string? _dateFormatString;
internal bool _dateFormatStringSet;
internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling;
internal DefaultValueHandling? _defaultValueHandling;
@@ -225,27 +233,27 @@ public ConstructorHandling ConstructorHandling
/// serializing .NET objects to JSON and vice versa.
///
/// The contract resolver.
- public IContractResolver ContractResolver { get; set; }
+ public IContractResolver? ContractResolver { get; set; }
///
/// Gets or sets the equality comparer used by the serializer when comparing references.
///
/// The equality comparer.
- public IEqualityComparer EqualityComparer { get; set; }
+ public IEqualityComparer? EqualityComparer { get; set; }
///
/// Gets or sets the used by the serializer when resolving references.
///
/// The reference resolver.
[Obsolete("ReferenceResolver property is obsolete. Use the ReferenceResolverProvider property to set the IReferenceResolver: settings.ReferenceResolverProvider = () => resolver")]
- public IReferenceResolver ReferenceResolver
+ public IReferenceResolver? ReferenceResolver
{
get => ReferenceResolverProvider?.Invoke();
set
{
ReferenceResolverProvider = (value != null)
? () => value
- : (Func)null;
+ : (Func?)null;
}
}
@@ -253,49 +261,49 @@ public IReferenceResolver ReferenceResolver
/// Gets or sets a function that creates the used by the serializer when resolving references.
///
/// A function that creates the used by the serializer when resolving references.
- public Func ReferenceResolverProvider { get; set; }
+ public Func? ReferenceResolverProvider { get; set; }
///
/// Gets or sets the used by the serializer when writing trace messages.
///
/// The trace writer.
- public ITraceWriter TraceWriter { get; set; }
-
- /////
- ///// Gets or sets the used by the serializer when resolving type names.
- /////
- ///// The binder.
- //[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
- //public SerializationBinder Binder
- //{
- // get
- // {
- // if (SerializationBinder == null)
- // {
- // return null;
- // }
-
- // if (SerializationBinder is SerializationBinderAdapter adapter)
- // {
- // return adapter.SerializationBinder;
- // }
-
- // throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
- // }
- // set => SerializationBinder = value == null ? null : new SerializationBinderAdapter(value);
- //}
+ public ITraceWriter? TraceWriter { get; set; }
+
+ ///
+ /// Gets or sets the used by the serializer when resolving type names.
+ ///
+ /// The binder.
+ [Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
+ public SerializationBinder? Binder
+ {
+ get
+ {
+ if (SerializationBinder == null)
+ {
+ return null;
+ }
+
+ if (SerializationBinder is SerializationBinderAdapter adapter)
+ {
+ return adapter.SerializationBinder;
+ }
+
+ throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
+ }
+ set => SerializationBinder = value == null ? null : new SerializationBinderAdapter(value);
+ }
///
/// Gets or sets the used by the serializer when resolving type names.
///
/// The binder.
- public ISerializationBinder SerializationBinder { get; set; }
+ public ISerializationBinder? SerializationBinder { get; set; }
///
/// Gets or sets the error handler called during serialization and deserialization.
///
/// The error handler called during serialization and deserialization.
- public EventHandler Error { get; set; }
+ public EventHandler? Error { get; set; }
///
/// Gets or sets the used by the serializer when invoking serialization callback methods.
@@ -325,11 +333,11 @@ public string DateFormatString
///
/// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a .
/// A null value means there is no maximum.
- /// The default value is null.
+ /// The default value is 64.
///
public int? MaxDepth
{
- get => _maxDepth;
+ get => _maxDepthSet ? _maxDepth : DefaultMaxDepth;
set
{
if (value <= 0)
@@ -451,5 +459,45 @@ public JsonSerializerSettings()
{
Converters = new List();
}
+
+ ///
+ /// Initializes a new instance of the class
+ /// using values copied from the passed in .
+ ///
+ public JsonSerializerSettings(JsonSerializerSettings original)
+ {
+ _floatParseHandling = original._floatParseHandling;
+ _floatFormatHandling = original._floatFormatHandling;
+ _dateParseHandling = original._dateParseHandling;
+ _dateTimeZoneHandling = original._dateTimeZoneHandling;
+ _dateFormatHandling = original._dateFormatHandling;
+ _formatting = original._formatting;
+ _maxDepth = original._maxDepth;
+ _maxDepthSet = original._maxDepthSet;
+ _dateFormatString = original._dateFormatString;
+ _dateFormatStringSet = original._dateFormatStringSet;
+ _context = original._context;
+ Error = original.Error;
+ SerializationBinder = original.SerializationBinder;
+ TraceWriter = original.TraceWriter;
+ _culture = original._culture;
+ ReferenceResolverProvider = original.ReferenceResolverProvider;
+ EqualityComparer = original.EqualityComparer;
+ ContractResolver = original.ContractResolver;
+ _constructorHandling = original._constructorHandling;
+ _typeNameAssemblyFormatHandling = original._typeNameAssemblyFormatHandling;
+ _metadataPropertyHandling = original._metadataPropertyHandling;
+ _typeNameHandling = original._typeNameHandling;
+ _preserveReferencesHandling = original._preserveReferencesHandling;
+ Converters = original.Converters.ToList();
+ _defaultValueHandling = original._defaultValueHandling;
+ _nullValueHandling = original._nullValueHandling;
+ _objectCreationHandling = original._objectCreationHandling;
+ _missingMemberHandling = original._missingMemberHandling;
+ _referenceLoopHandling = original._referenceLoopHandling;
+ _checkAdditionalContent = original._checkAdditionalContent;
+ _stringEscapeHandling = original._stringEscapeHandling;
+ }
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.Async.cs
index 88915c4bd9..7fd16d2fcc 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.Async.cs
@@ -34,9 +34,11 @@
using System.Threading.Tasks;
using Microsoft.IdentityModel.Json.Serialization;
using Microsoft.IdentityModel.Json.Utilities;
+using System.Diagnostics;
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
internal partial class JsonTextReader
{
// It's not safe to perform the async methods here in a derived class as if the synchronous equivalent
@@ -78,7 +80,7 @@ internal Task DoReadAsync(CancellationToken cancellationToken)
return ParseObjectAsync(cancellationToken);
case State.PostValue:
Task task = ParsePostValueAsync(false, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
if (task.Result)
{
@@ -110,6 +112,8 @@ private async Task DoReadAsync(Task task, CancellationToken cancella
private async Task ParsePostValueAsync(bool ignoreComments, CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -193,6 +197,8 @@ private async Task ParsePostValueAsync(bool ignoreComments, CancellationTo
private async Task ReadFromFinishedAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (await EnsureCharsAsync(0, false, cancellationToken).ConfigureAwait(false))
{
await EatWhitespaceAsync(cancellationToken).ConfigureAwait(false);
@@ -222,6 +228,8 @@ private Task ReadDataAsync(bool append, CancellationToken cancellationToken
private async Task ReadDataAsync(bool append, int charsRequired, CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (_isEndOfFile)
{
return 0;
@@ -244,6 +252,8 @@ private async Task ReadDataAsync(bool append, int charsRequired, Cancellati
private async Task ParseValueAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -373,6 +383,8 @@ private async Task ParseValueAsync(CancellationToken cancellationToken)
private async Task ReadStringIntoBufferAsync(char quote, CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
int charPos = _charPos;
int initialPosition = _charPos;
int lastWritePosition = _charPos;
@@ -531,7 +543,7 @@ private Task ProcessCarriageReturnAsync(bool append, CancellationToken cancellat
_charPos++;
Task task = EnsureCharsAsync(1, append, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
SetNewLine(task.Result);
return AsyncUtils.CompletedTask;
@@ -589,6 +601,8 @@ private async Task ReadCharsAsync(int relativePosition, bool append, Cance
private async Task ParseObjectAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -646,6 +660,8 @@ private async Task ParseObjectAsync(CancellationToken cancellationToken)
private async Task ParseCommentAsync(bool setToken, CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
// should have already parsed / character before reaching this method
_charPos++;
@@ -742,6 +758,8 @@ private async Task ParseCommentAsync(bool setToken, CancellationToken cancellati
private async Task EatWhitespaceAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -798,6 +816,8 @@ private async Task MatchValueAsync(string value, CancellationToken cancell
private async Task MatchValueWithTrailingSeparatorAsync(string value, CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
// will match value and then move to the next character, checking that it is a separator character
if (!await MatchValueAsync(value, cancellationToken).ConfigureAwait(false))
{
@@ -812,7 +832,7 @@ private async Task MatchValueWithTrailingSeparatorAsync(string value, Canc
return IsSeparator(_chars[_charPos]) || _chars[_charPos] == '\0';
}
- private async Task MatchAndSetAsync(string value, JsonToken newToken, object tokenValue, CancellationToken cancellationToken)
+ private async Task MatchAndSetAsync(string value, JsonToken newToken, object? tokenValue, CancellationToken cancellationToken)
{
if (await MatchValueWithTrailingSeparatorAsync(value, cancellationToken).ConfigureAwait(false))
{
@@ -841,6 +861,8 @@ private Task ParseNullAsync(CancellationToken cancellationToken)
private async Task ParseConstructorAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (await MatchValueWithTrailingSeparatorAsync("new", cancellationToken).ConfigureAwait(false))
{
await EatWhitespaceAsync(cancellationToken).ConfigureAwait(false);
@@ -939,6 +961,8 @@ private async Task ParseNumberNegativeInfinityAsync(ReadType readType, C
private async Task ParseNumberAsync(ReadType readType, CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
ShiftBufferIfNeeded();
char firstChar = _chars[_charPos];
@@ -956,6 +980,8 @@ private Task ParseUndefinedAsync(CancellationToken cancellationToken)
private async Task ParsePropertyAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
char firstChar = _chars[_charPos];
char quoteChar;
@@ -1008,6 +1034,8 @@ private async Task ParsePropertyAsync(CancellationToken cancellationToken)
private async Task ReadNumberIntoBufferAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
int charPos = _charPos;
while (true)
@@ -1042,6 +1070,8 @@ private async Task ReadNumberIntoBufferAsync(CancellationToken cancellationToken
private async Task ParseUnquotedPropertyAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
int initialPosition = _charPos;
// parse unquoted property name until whitespace or colon
@@ -1091,6 +1121,8 @@ private async Task ReadNullCharAsync(CancellationToken cancellationToken)
private async Task HandleNullAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (await EnsureCharsAsync(1, true, cancellationToken).ConfigureAwait(false))
{
if (_chars[_charPos + 1] == 'u')
@@ -1109,6 +1141,8 @@ private async Task HandleNullAsync(CancellationToken cancellationToken)
private async Task ReadFinishedAsync(CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (await EnsureCharsAsync(0, false, cancellationToken).ConfigureAwait(false))
{
await EatWhitespaceAsync(cancellationToken).ConfigureAwait(false);
@@ -1131,9 +1165,10 @@ private async Task ReadFinishedAsync(CancellationToken cancellationToken)
SetToken(JsonToken.None);
}
- private async Task ReadStringValueAsync(ReadType readType, CancellationToken cancellationToken)
+ private async Task ReadStringValueAsync(ReadType readType, CancellationToken cancellationToken)
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
switch (_currentState)
{
@@ -1266,9 +1301,10 @@ private async Task ReadStringValueAsync(ReadType readType, CancellationT
}
}
- private async Task ReadNumberValueAsync(ReadType readType, CancellationToken cancellationToken)
+ private async Task ReadNumberValueAsync(ReadType readType, CancellationToken cancellationToken)
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
switch (_currentState)
{
@@ -1395,6 +1431,7 @@ private async Task ReadNumberValueAsync(ReadType readType, CancellationT
internal async Task DoReadAsBooleanAsync(CancellationToken cancellationToken)
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
switch (_currentState)
{
@@ -1522,14 +1559,16 @@ private async Task ReadNumberValueAsync(ReadType readType, CancellationT
/// property returns the []. This result will be null at the end of an array.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task ReadAsBytesAsync(CancellationToken cancellationToken = default)
+ public override Task ReadAsBytesAsync(CancellationToken cancellationToken = default)
{
return _safeAsync ? DoReadAsBytesAsync(cancellationToken) : base.ReadAsBytesAsync(cancellationToken);
}
- internal async Task DoReadAsBytesAsync(CancellationToken cancellationToken)
+ internal async Task DoReadAsBytesAsync(CancellationToken cancellationToken)
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
+
bool isWrapped = false;
switch (_currentState)
@@ -1563,7 +1602,7 @@ internal async Task DoReadAsBytesAsync(CancellationToken cancellationTok
case '"':
case '\'':
await ParseStringAsync(currentChar, ReadType.ReadAsBytes, cancellationToken).ConfigureAwait(false);
- byte[] data = (byte[])Value;
+ byte[]? data = (byte[]?)Value;
if (isWrapped)
{
await ReaderReadAndAssertAsync(cancellationToken).ConfigureAwait(false);
@@ -1642,7 +1681,7 @@ private async Task ReadIntoWrappedTypeObjectAsync(CancellationToken cancellation
if (Value != null && Value.ToString() == JsonTypeReflector.TypePropertyName)
{
await ReaderReadAndAssertAsync(cancellationToken).ConfigureAwait(false);
- if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
+ if (Value != null && Value.ToString()!.StartsWith("System.Byte[]", StringComparison.Ordinal))
{
await ReaderReadAndAssertAsync(cancellationToken).ConfigureAwait(false);
if (Value.ToString() == JsonTypeReflector.ValuePropertyName)
@@ -1753,16 +1792,17 @@ private async Task ReadIntoWrappedTypeObjectAsync(CancellationToken cancellation
/// property returns the . This result will be null at the end of an array.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task ReadAsStringAsync(CancellationToken cancellationToken = default)
+ public override Task ReadAsStringAsync(CancellationToken cancellationToken = default)
{
return _safeAsync ? DoReadAsStringAsync(cancellationToken) : base.ReadAsStringAsync(cancellationToken);
}
- internal async Task DoReadAsStringAsync(CancellationToken cancellationToken)
+ internal async Task DoReadAsStringAsync(CancellationToken cancellationToken)
{
- return (string)await ReadStringValueAsync(ReadType.ReadAsString, cancellationToken).ConfigureAwait(false);
+ return (string?)await ReadStringValueAsync(ReadType.ReadAsString, cancellationToken).ConfigureAwait(false);
}
}
+#nullable disable
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.cs
index e84f607a86..ffd90de265 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextReader.cs
@@ -27,6 +27,7 @@
using System.Runtime.CompilerServices;
using System.IO;
using System.Globalization;
+using System.Diagnostics;
#if HAVE_BIG_INTEGER
using System.Numerics;
#endif
@@ -34,6 +35,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
internal enum ReadType
{
Read,
@@ -56,8 +58,9 @@ internal enum ReadType
internal partial class JsonTextReader : JsonReader, IJsonLineInfo
{
private const char UnicodeReplacementChar = '\uFFFD';
+#if HAVE_BIG_INTEGER
private const int MaximumJavascriptIntegerCharacterLength = 380;
-
+#endif
#if DEBUG
internal int LargeBufferLength { get; set; } = int.MaxValue / 2;
#else
@@ -65,7 +68,7 @@ internal partial class JsonTextReader : JsonReader, IJsonLineInfo
#endif
private readonly TextReader _reader;
- private char[] _chars;
+ private char[]? _chars;
private int _charsUsed;
private int _charPos;
private int _lineStartPos;
@@ -73,7 +76,7 @@ internal partial class JsonTextReader : JsonReader, IJsonLineInfo
private bool _isEndOfFile;
private StringBuffer _stringBuffer;
private StringReference _stringReference;
- private IArrayPool _arrayPool;
+ private IArrayPool? _arrayPool;
///
/// Initializes a new instance of the class with the specified .
@@ -95,7 +98,7 @@ public JsonTextReader(TextReader reader)
}
#if DEBUG
- internal char[] CharBuffer
+ internal char[]? CharBuffer
{
get => _chars;
set => _chars = value;
@@ -107,12 +110,12 @@ internal char[] CharBuffer
///
/// Gets or sets the reader's property name table.
///
- public JsonNameTable PropertyNameTable { get; set; }
+ public JsonNameTable? PropertyNameTable { get; set; }
///
/// Gets or sets the reader's character buffer pool.
///
- public IArrayPool ArrayPool
+ public IArrayPool? ArrayPool
{
get => _arrayPool;
set
@@ -136,6 +139,8 @@ private void EnsureBufferNotEmpty()
private void SetNewLine(bool hasNextChar)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (hasNextChar && _chars[_charPos] == StringUtils.LineFeed)
{
_charPos++;
@@ -160,7 +165,7 @@ private void ParseString(char quote, ReadType readType)
}
private void ParseReadString(char quote, ReadType readType)
- {
+ {
SetPostValueState(true);
switch (readType)
@@ -248,6 +253,8 @@ private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int ds
private void ShiftBufferIfNeeded()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
// once in the last 10% of the buffer, or buffer is already very large then
// shift the remaining content to the start to avoid unnecessarily increasing
// the buffer size when reading numbers/strings
@@ -274,6 +281,8 @@ private int ReadData(bool append)
private void PrepareBufferForReadData(bool append, int charsRequired)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
// char buffer is full
if (_charsUsed + charsRequired >= _chars.Length - 1)
{
@@ -337,6 +346,7 @@ private int ReadData(bool append, int charsRequired)
}
PrepareBufferForReadData(append, charsRequired);
+ MiscellaneousUtils.Assert(_chars != null);
int attemptCharReadCount = _chars.Length - _charsUsed - 1;
@@ -405,6 +415,7 @@ private bool ReadChars(int relativePosition, bool append)
public override bool Read()
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
while (true)
{
@@ -475,18 +486,20 @@ public override bool Read()
/// Reads the next JSON token from the underlying as a .
///
/// A . This method will return null at the end of an array.
- public override string ReadAsString()
+ public override string? ReadAsString()
{
- return (string)ReadStringValue(ReadType.ReadAsString);
+ return (string?)ReadStringValue(ReadType.ReadAsString);
}
///
/// Reads the next JSON token from the underlying as a [].
///
/// A [] or null if the next JSON token is null. This method will return null at the end of an array.
- public override byte[] ReadAsBytes()
+ public override byte[]? ReadAsBytes()
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
+
bool isWrapped = false;
switch (_currentState)
@@ -519,7 +532,7 @@ public override byte[] ReadAsBytes()
case '"':
case '\'':
ParseString(currentChar, ReadType.ReadAsBytes);
- byte[] data = (byte[])Value;
+ byte[]? data = (byte[]?)Value;
if (isWrapped)
{
ReaderReadAndAssert();
@@ -588,9 +601,10 @@ public override byte[] ReadAsBytes()
}
}
- private object ReadStringValue(ReadType readType)
+ private object? ReadStringValue(ReadType readType)
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
switch (_currentState)
{
@@ -717,7 +731,7 @@ private object ReadStringValue(ReadType readType)
}
}
- private object FinishReadQuotedStringValue(ReadType readType)
+ private object? FinishReadQuotedStringValue(ReadType readType)
{
switch (readType)
{
@@ -730,7 +744,7 @@ private object FinishReadQuotedStringValue(ReadType readType)
return time;
}
- return ReadDateTimeString((string)Value);
+ return ReadDateTimeString((string?)Value);
#if HAVE_DATE_TIME_OFFSET
case ReadType.ReadAsDateTimeOffset:
if (Value is DateTimeOffset offset)
@@ -738,7 +752,7 @@ private object FinishReadQuotedStringValue(ReadType readType)
return offset;
}
- return ReadDateTimeOffsetString((string)Value);
+ return ReadDateTimeOffsetString((string?)Value);
#endif
default:
throw new ArgumentOutOfRangeException(nameof(readType));
@@ -757,6 +771,7 @@ private JsonReaderException CreateUnexpectedCharacterException(char c)
public override bool? ReadAsBoolean()
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
switch (_currentState)
{
@@ -827,7 +842,7 @@ private JsonReaderException CreateUnexpectedCharacterException(char c)
{
throw CreateUnexpectedCharacterException(_chars[_charPos]);
}
- SetToken(JsonToken.Boolean, isTrue);
+ SetToken(JsonToken.Boolean, BoxedPrimitives.Get(isTrue));
return isTrue;
case '/':
ParseComment(false);
@@ -891,9 +906,10 @@ private void ProcessValueComma()
SetStateBasedOnCurrent();
}
- private object ReadNumberValue(ReadType readType)
+ private object? ReadNumberValue(ReadType readType)
{
EnsureBuffer();
+ MiscellaneousUtils.Assert(_chars != null);
switch (_currentState)
{
@@ -1001,7 +1017,7 @@ private object ReadNumberValue(ReadType readType)
}
}
- private object FinishReadQuotedNumber(ReadType readType)
+ private object? FinishReadQuotedNumber(ReadType readType)
{
switch (readType)
{
@@ -1047,6 +1063,8 @@ private object FinishReadQuotedNumber(ReadType readType)
private void HandleNull()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (EnsureChars(1, true))
{
char next = _chars[_charPos + 1];
@@ -1067,6 +1085,8 @@ private void HandleNull()
private void ReadFinished()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (EnsureChars(0, false))
{
EatWhitespace();
@@ -1116,6 +1136,8 @@ private void EnsureBuffer()
private void ReadStringIntoBuffer(char quote)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
int charPos = _charPos;
int initialPosition = _charPos;
int lastWritePosition = _charPos;
@@ -1269,6 +1291,8 @@ private void ReadStringIntoBuffer(char quote)
private void FinishReadStringIntoBuffer(int charPos, int initialPosition, int lastWritePosition)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (initialPosition == lastWritePosition)
{
_stringReference = new StringReference(_chars, initialPosition, charPos - initialPosition);
@@ -1282,7 +1306,7 @@ private void FinishReadStringIntoBuffer(int charPos, int initialPosition, int la
_stringBuffer.Append(_arrayPool, _chars, lastWritePosition, charPos - lastWritePosition);
}
- _stringReference = new StringReference(_stringBuffer.InternalBuffer, 0, _stringBuffer.Position);
+ _stringReference = new StringReference(_stringBuffer.InternalBuffer!, 0, _stringBuffer.Position);
}
_charPos = charPos + 1;
@@ -1290,6 +1314,8 @@ private void FinishReadStringIntoBuffer(int charPos, int initialPosition, int la
private void WriteCharToBuffer(char writeChar, int lastWritePosition, int writeToPosition)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (writeToPosition > lastWritePosition)
{
_stringBuffer.Append(_arrayPool, _chars, lastWritePosition, writeToPosition - lastWritePosition);
@@ -1300,6 +1326,8 @@ private void WriteCharToBuffer(char writeChar, int lastWritePosition, int writeT
private char ConvertUnicode(bool enoughChars)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (enoughChars)
{
if (ConvertUtils.TryHexTextToInt(_chars, _charPos, _charPos + 4, out int value))
@@ -1326,6 +1354,8 @@ private char ParseUnicode()
private void ReadNumberIntoBuffer()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
int charPos = _charPos;
while (true)
@@ -1410,6 +1440,8 @@ private void ClearRecentString()
private bool ParsePostValue(bool ignoreComments)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -1490,6 +1522,8 @@ private bool ParsePostValue(bool ignoreComments)
private bool ParseObject()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -1544,6 +1578,8 @@ private bool ParseObject()
private bool ParseProperty()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
char firstChar = _chars[_charPos];
char quoteChar;
@@ -1565,7 +1601,7 @@ private bool ParseProperty()
throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
}
- string propertyName;
+ string? propertyName;
if (PropertyNameTable != null)
{
@@ -1605,6 +1641,8 @@ private bool ValidIdentifierChar(char value)
private void ParseUnquotedProperty()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
int initialPosition = _charPos;
// parse unquoted property name until whitespace or colon
@@ -1636,6 +1674,8 @@ private void ParseUnquotedProperty()
private bool ReadUnquotedPropertyReportIfDone(char currentChar, int initialPosition)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (ValidIdentifierChar(currentChar))
{
_charPos++;
@@ -1653,6 +1693,8 @@ private bool ReadUnquotedPropertyReportIfDone(char currentChar, int initialPosit
private bool ParseValue()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -1793,6 +1835,8 @@ private void ProcessCarriageReturn(bool append)
private void EatWhitespace()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
while (true)
{
char currentChar = _chars[_charPos];
@@ -1834,6 +1878,8 @@ private void EatWhitespace()
private void ParseConstructor()
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (MatchValueWithTrailingSeparator("new"))
{
EatWhitespace();
@@ -1918,6 +1964,7 @@ private void ParseConstructor()
private void ParseNumber(ReadType readType)
{
ShiftBufferIfNeeded();
+ MiscellaneousUtils.Assert(_chars != null);
char firstChar = _chars[_charPos];
int initialPosition = _charPos;
@@ -1929,6 +1976,8 @@ private void ParseNumber(ReadType readType)
private void ParseReadNumber(ReadType readType, char firstChar, int initialPosition)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
// set state to PostValue now so that if there is an error parsing the number then the reader can continue
SetPostValueState(true);
@@ -1982,7 +2031,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
if (singleDigit)
{
// digit char values start at 48
- numberValue = firstChar - 48;
+ numberValue = BoxedPrimitives.Get(firstChar - 48);
}
else if (nonBase10)
{
@@ -1992,7 +2041,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
{
int integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt32(number, 16) : Convert.ToInt32(number, 8);
- numberValue = integer;
+ numberValue = BoxedPrimitives.Get(integer);
}
catch (Exception ex)
{
@@ -2004,7 +2053,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
ParseResult parseResult = ConvertUtils.Int32TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out int value);
if (parseResult == ParseResult.Success)
{
- numberValue = value;
+ numberValue = BoxedPrimitives.Get(value);
}
else if (parseResult == ParseResult.Overflow)
{
@@ -2024,7 +2073,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
if (singleDigit)
{
// digit char values start at 48
- numberValue = (decimal)firstChar - 48;
+ numberValue = BoxedPrimitives.Get((decimal)firstChar - 48);
}
else if (nonBase10)
{
@@ -2035,7 +2084,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
// decimal.Parse doesn't support parsing hexadecimal values
long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);
- numberValue = Convert.ToDecimal(integer);
+ numberValue = BoxedPrimitives.Get(Convert.ToDecimal(integer));
}
catch (Exception ex)
{
@@ -2047,7 +2096,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
ParseResult parseResult = ConvertUtils.DecimalTryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out decimal value);
if (parseResult == ParseResult.Success)
{
- numberValue = value;
+ numberValue = BoxedPrimitives.Get(value);
}
else
{
@@ -2063,7 +2112,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
if (singleDigit)
{
// digit char values start at 48
- numberValue = (double)firstChar - 48;
+ numberValue = BoxedPrimitives.Get((double)firstChar - 48);
}
else if (nonBase10)
{
@@ -2074,7 +2123,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
// double.Parse doesn't support parsing hexadecimal values
long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);
- numberValue = Convert.ToDouble(integer);
+ numberValue = BoxedPrimitives.Get(Convert.ToDouble(integer));
}
catch (Exception ex)
{
@@ -2087,7 +2136,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
if (double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
{
- numberValue = value;
+ numberValue = BoxedPrimitives.Get(value);
}
else
{
@@ -2104,7 +2153,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
if (singleDigit)
{
// digit char values start at 48
- numberValue = (long)firstChar - 48;
+ numberValue = BoxedPrimitives.Get((long)firstChar - 48);
numberType = JsonToken.Integer;
}
else if (nonBase10)
@@ -2113,7 +2162,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
try
{
- numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);
+ numberValue = BoxedPrimitives.Get(number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8));
}
catch (Exception ex)
{
@@ -2127,7 +2176,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
ParseResult parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out long value);
if (parseResult == ParseResult.Success)
{
- numberValue = value;
+ numberValue = BoxedPrimitives.Get(value);
numberType = JsonToken.Integer;
}
else if (parseResult == ParseResult.Overflow)
@@ -2153,7 +2202,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
parseResult = ConvertUtils.DecimalTryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out decimal d);
if (parseResult == ParseResult.Success)
{
- numberValue = d;
+ numberValue = BoxedPrimitives.Get(d);
}
else
{
@@ -2166,7 +2215,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
if (double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out double d))
{
- numberValue = d;
+ numberValue = BoxedPrimitives.Get(d);
}
else
{
@@ -2189,7 +2238,7 @@ private void ParseReadNumber(ReadType readType, char firstChar, int initialPosit
SetToken(numberType, numberValue, false);
}
- private JsonReaderException ThrowReaderError(string message, Exception ex = null)
+ private JsonReaderException ThrowReaderError(string message, Exception? ex = null)
{
SetToken(JsonToken.Undefined, null, false);
return JsonReaderException.Create(this, message, ex);
@@ -2197,7 +2246,7 @@ private JsonReaderException ThrowReaderError(string message, Exception ex = null
#if HAVE_BIG_INTEGER
// By using the BigInteger type in a separate method,
- // the runtime can execute the ParseNumber even if
+ // the runtime can execute the ParseNumber even if
// the System.Numerics.BigInteger.Parse method is
// missing, which happens in some versions of Mono
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -2209,6 +2258,8 @@ private static object BigIntegerParse(string number, CultureInfo culture)
private void ParseComment(bool setToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
// should have already parsed / character before reaching this method
_charPos++;
@@ -2303,6 +2354,7 @@ private void EndComment(bool setToken, int initialPosition, int endPosition)
{
if (setToken)
{
+ MiscellaneousUtils.Assert(_chars != null);
SetToken(JsonToken.Comment, new string(_chars, initialPosition, endPosition - initialPosition));
}
}
@@ -2314,6 +2366,8 @@ private bool MatchValue(string value)
private bool MatchValue(bool enoughChars, string value)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
if (!enoughChars)
{
_charPos = _charsUsed;
@@ -2336,6 +2390,8 @@ private bool MatchValue(bool enoughChars, string value)
private bool MatchValueWithTrailingSeparator(string value)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
// will match value and then move to the next character, checking that it is a separator character
bool match = MatchValue(value);
@@ -2354,6 +2410,8 @@ private bool MatchValueWithTrailingSeparator(string value)
private bool IsSeparator(char c)
{
+ MiscellaneousUtils.Assert(_chars != null);
+
switch (c)
{
case '}':
@@ -2399,7 +2457,7 @@ private void ParseTrue()
// or the text ends
if (MatchValueWithTrailingSeparator(JsonConvert.True))
{
- SetToken(JsonToken.Boolean, true);
+ SetToken(JsonToken.Boolean, BoxedPrimitives.BooleanTrue);
}
else
{
@@ -2435,7 +2493,7 @@ private void ParseFalse()
{
if (MatchValueWithTrailingSeparator(JsonConvert.False))
{
- SetToken(JsonToken.Boolean, false);
+ SetToken(JsonToken.Boolean, BoxedPrimitives.BooleanFalse);
}
else
{
@@ -2458,7 +2516,7 @@ private object ParseNumberNegativeInfinity(ReadType readType, bool matched)
case ReadType.ReadAsDouble:
if (_floatParseHandling == FloatParseHandling.Double)
{
- SetToken(JsonToken.Float, double.NegativeInfinity);
+ SetToken(JsonToken.Float, BoxedPrimitives.DoubleNegativeInfinity);
return double.NegativeInfinity;
}
break;
@@ -2487,7 +2545,7 @@ private object ParseNumberPositiveInfinity(ReadType readType, bool matched)
case ReadType.ReadAsDouble:
if (_floatParseHandling == FloatParseHandling.Double)
{
- SetToken(JsonToken.Float, double.PositiveInfinity);
+ SetToken(JsonToken.Float, BoxedPrimitives.DoublePositiveInfinity);
return double.PositiveInfinity;
}
break;
@@ -2517,7 +2575,7 @@ private object ParseNumberNaN(ReadType readType, bool matched)
case ReadType.ReadAsDouble:
if (_floatParseHandling == FloatParseHandling.Double)
{
- SetToken(JsonToken.Float, double.NaN);
+ SetToken(JsonToken.Float, BoxedPrimitives.DoubleNaN);
return double.NaN;
}
break;
@@ -2596,4 +2654,5 @@ public int LineNumber
///
public int LinePosition => _charPos - _lineStartPos;
}
+#nullable disable
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.Async.cs
index 737315a24f..aecb6d8fdf 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.Async.cs
@@ -33,9 +33,12 @@
#endif
using System.Threading.Tasks;
using Microsoft.IdentityModel.Json.Utilities;
+using System.Diagnostics;
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
internal partial class JsonTextWriter
{
// It's not safe to perform the async methods here in a derived class as if the synchronous equivalent
@@ -131,7 +134,34 @@ internal async Task DoCloseAsync(CancellationToken cancellationToken)
await WriteEndAsync(cancellationToken).ConfigureAwait(false);
}
- CloseBufferAndWriter();
+ await CloseBufferAndWriterAsync().ConfigureAwait(false);
+ }
+
+ private async Task CloseBufferAndWriterAsync()
+ {
+ if (_writeBuffer != null)
+ {
+ BufferUtils.ReturnBuffer(_arrayPool, _writeBuffer);
+ _writeBuffer = null;
+ }
+
+ if (CloseOutput && _writer != null)
+ {
+#if HAVE_ASYNC_DISPOSABLE
+ await _writer.DisposeAsync().ConfigureAwait(false);
+#else
+ // DisposeAsync isn't available. Instead, flush any remaining content with FlushAsync
+ // to prevent Close/Dispose from making a blocking flush.
+ //
+ // No cancellation token on TextWriter.FlushAsync?!
+ await _writer.FlushAsync().ConfigureAwait(false);
+#if HAVE_STREAM_READER_WRITER_CLOSE
+ _writer.Close();
+#else
+ _writer.Dispose();
+#endif
+#endif
+ }
}
///
@@ -164,6 +194,7 @@ internal Task DoWriteIndentAsync(CancellationToken cancellationToken)
int currentIndentCount = Top * _indentation;
int newLineLen = SetIndentChars();
+ MiscellaneousUtils.Assert(_indentChars != null);
if (currentIndentCount <= IndentCharBufferSize)
{
@@ -175,6 +206,8 @@ internal Task DoWriteIndentAsync(CancellationToken cancellationToken)
private async Task WriteIndentAsync(int currentIndentCount, int newLineLen, CancellationToken cancellationToken)
{
+ MiscellaneousUtils.Assert(_indentChars != null);
+
await _writer.WriteAsync(_indentChars, 0, newLineLen + Math.Min(currentIndentCount, IndentCharBufferSize), cancellationToken).ConfigureAwait(false);
while ((currentIndentCount -= IndentCharBufferSize) > 0)
@@ -186,7 +219,7 @@ private async Task WriteIndentAsync(int currentIndentCount, int newLineLen, Canc
private Task WriteValueInternalAsync(JsonToken token, string value, CancellationToken cancellationToken)
{
Task task = InternalWriteValueAsync(token, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return _writer.WriteAsync(value, cancellationToken);
}
@@ -225,12 +258,12 @@ internal Task DoWriteIndentSpaceAsync(CancellationToken cancellationToken)
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task WriteRawAsync(string json, CancellationToken cancellationToken = default)
+ public override Task WriteRawAsync(string? json, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteRawAsync(json, cancellationToken) : base.WriteRawAsync(json, cancellationToken);
}
- internal Task DoWriteRawAsync(string json, CancellationToken cancellationToken)
+ internal Task DoWriteRawAsync(string? json, CancellationToken cancellationToken)
{
return _writer.WriteAsync(json, cancellationToken);
}
@@ -260,13 +293,13 @@ private Task WriteDigitsAsync(ulong uvalue, bool negative, CancellationToken can
}
int length = WriteNumberToBuffer(uvalue, negative);
- return _writer.WriteAsync(_writeBuffer, 0, length, cancellationToken);
+ return _writer.WriteAsync(_writeBuffer!, 0, length, cancellationToken);
}
private Task WriteIntegerValueAsync(ulong uvalue, bool negative, CancellationToken cancellationToken)
{
Task task = InternalWriteValueAsync(JsonToken.Integer, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return WriteDigitsAsync(uvalue, negative, cancellationToken);
}
@@ -298,7 +331,7 @@ internal Task WriteIntegerValueAsync(ulong uvalue, CancellationToken cancellatio
private Task WriteEscapedStringAsync(string value, bool quote, CancellationToken cancellationToken)
{
- return JavaScriptUtils.WriteEscapedJavaScriptStringAsync(_writer, value, _quoteChar, quote, _charEscapeFlags, StringEscapeHandling, this, _writeBuffer, cancellationToken);
+ return JavaScriptUtils.WriteEscapedJavaScriptStringAsync(_writer, value, _quoteChar, quote, _charEscapeFlags!, StringEscapeHandling, this, _writeBuffer!, cancellationToken);
}
///
@@ -317,13 +350,13 @@ public override Task WritePropertyNameAsync(string name, CancellationToken cance
internal Task DoWritePropertyNameAsync(string name, CancellationToken cancellationToken)
{
Task task = InternalWritePropertyNameAsync(name, cancellationToken);
- if (!task.IsCompletedSucessfully())
+ if (!task.IsCompletedSuccessfully())
{
return DoWritePropertyNameAsync(task, name, cancellationToken);
}
task = WriteEscapedStringAsync(name, _quoteName, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return _writer.WriteAsync(':', cancellationToken);
}
@@ -395,7 +428,7 @@ public override Task WriteStartArrayAsync(CancellationToken cancellationToken =
internal Task DoWriteStartArrayAsync(CancellationToken cancellationToken)
{
Task task = InternalWriteStartAsync(JsonToken.StartArray, JsonContainerType.Array, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return _writer.WriteAsync('[', cancellationToken);
}
@@ -425,7 +458,7 @@ public override Task WriteStartObjectAsync(CancellationToken cancellationToken =
internal Task DoWriteStartObjectAsync(CancellationToken cancellationToken)
{
Task task = InternalWriteStartAsync(JsonToken.StartObject, JsonContainerType.Object, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return _writer.WriteAsync('{', cancellationToken);
}
@@ -477,7 +510,7 @@ public override Task WriteUndefinedAsync(CancellationToken cancellationToken = d
internal Task DoWriteUndefinedAsync(CancellationToken cancellationToken)
{
Task task = InternalWriteValueAsync(JsonToken.Undefined, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return _writer.WriteAsync(JsonConvert.Undefined, cancellationToken);
}
@@ -585,7 +618,7 @@ internal Task DoWriteValueAsync(byte? value, CancellationToken cancellationToken
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task WriteValueAsync(byte[] value, CancellationToken cancellationToken = default)
+ public override Task WriteValueAsync(byte[]? value, CancellationToken cancellationToken = default)
{
return _safeAsync ? (value == null ? WriteNullAsync(cancellationToken) : WriteValueNonNullAsync(value, cancellationToken)) : base.WriteValueAsync(value, cancellationToken);
}
@@ -653,11 +686,11 @@ internal async Task DoWriteValueAsync(DateTime value, CancellationToken cancella
await InternalWriteValueAsync(JsonToken.Date, cancellationToken).ConfigureAwait(false);
value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling);
- if (string.IsNullOrEmpty(DateFormatString))
+ if (StringUtils.IsNullOrEmpty(DateFormatString))
{
int length = WriteValueToBuffer(value);
- await _writer.WriteAsync(_writeBuffer, 0, length, cancellationToken).ConfigureAwait(false);
+ await _writer.WriteAsync(_writeBuffer!, 0, length, cancellationToken).ConfigureAwait(false);
}
else
{
@@ -702,11 +735,11 @@ internal async Task DoWriteValueAsync(DateTimeOffset value, CancellationToken ca
{
await InternalWriteValueAsync(JsonToken.Date, cancellationToken).ConfigureAwait(false);
- if (string.IsNullOrEmpty(DateFormatString))
+ if (StringUtils.IsNullOrEmpty(DateFormatString))
{
int length = WriteValueToBuffer(value);
- await _writer.WriteAsync(_writeBuffer, 0, length, cancellationToken).ConfigureAwait(false);
+ await _writer.WriteAsync(_writeBuffer!, 0, length, cancellationToken).ConfigureAwait(false);
}
else
{
@@ -853,9 +886,7 @@ internal async Task DoWriteValueAsync(Guid value, CancellationToken cancellation
#if HAVE_CHAR_TO_STRING_WITH_CULTURE
await _writer.WriteAsync(value.ToString("D", CultureInfo.InvariantCulture), cancellationToken).ConfigureAwait(false);
#else
-#pragma warning disable CA1305 // Specify IFormatProvider
await _writer.WriteAsync(value.ToString("D"), cancellationToken).ConfigureAwait(false);
-#pragma warning restore CA1305 // Specify IFormatProvider
#endif
await _writer.WriteAsync(_quoteChar).ConfigureAwait(false);
}
@@ -955,7 +986,7 @@ internal Task WriteValueAsync(BigInteger value, CancellationToken cancellationTo
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task WriteValueAsync(object value, CancellationToken cancellationToken = default)
+ public override Task WriteValueAsync(object? value, CancellationToken cancellationToken = default)
{
if (_safeAsync)
{
@@ -984,7 +1015,7 @@ public override Task WriteValueAsync(object value, CancellationToken cancellatio
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(sbyte value, CancellationToken cancellationToken = default)
{
return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -998,7 +1029,7 @@ public override Task WriteValueAsync(sbyte value, CancellationToken cancellation
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(sbyte? value, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -1048,15 +1079,15 @@ internal Task DoWriteValueAsync(short? value, CancellationToken cancellationToke
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task WriteValueAsync(string value, CancellationToken cancellationToken = default)
+ public override Task WriteValueAsync(string? value, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
}
- internal Task DoWriteValueAsync(string value, CancellationToken cancellationToken)
+ internal Task DoWriteValueAsync(string? value, CancellationToken cancellationToken)
{
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken);
}
@@ -1064,7 +1095,7 @@ internal Task DoWriteValueAsync(string value, CancellationToken cancellationToke
return DoWriteValueAsync(task, value, cancellationToken);
}
- private async Task DoWriteValueAsync(Task task, string value, CancellationToken cancellationToken)
+ private async Task DoWriteValueAsync(Task task, string? value, CancellationToken cancellationToken)
{
await task.ConfigureAwait(false);
await (value == null ? _writer.WriteAsync(JsonConvert.Null, cancellationToken) : WriteEscapedStringAsync(value, true, cancellationToken)).ConfigureAwait(false);
@@ -1117,7 +1148,7 @@ internal Task DoWriteValueAsync(TimeSpan? value, CancellationToken cancellationT
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(uint value, CancellationToken cancellationToken = default)
{
return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -1131,7 +1162,7 @@ public override Task WriteValueAsync(uint value, CancellationToken cancellationT
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(uint? value, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -1150,7 +1181,7 @@ internal Task DoWriteValueAsync(uint? value, CancellationToken cancellationToken
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(ulong value, CancellationToken cancellationToken = default)
{
return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -1164,7 +1195,7 @@ public override Task WriteValueAsync(ulong value, CancellationToken cancellation
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(ulong? value, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -1183,7 +1214,7 @@ internal Task DoWriteValueAsync(ulong? value, CancellationToken cancellationToke
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task WriteValueAsync(Uri value, CancellationToken cancellationToken = default)
+ public override Task WriteValueAsync(Uri? value, CancellationToken cancellationToken = default)
{
return _safeAsync ? (value == null ? WriteNullAsync(cancellationToken) : WriteValueNotNullAsync(value, cancellationToken)) : base.WriteValueAsync(value, cancellationToken);
}
@@ -1191,7 +1222,7 @@ public override Task WriteValueAsync(Uri value, CancellationToken cancellationTo
internal Task WriteValueNotNullAsync(Uri value, CancellationToken cancellationToken)
{
Task task = InternalWriteValueAsync(JsonToken.String, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return WriteEscapedStringAsync(value.OriginalString, true, cancellationToken);
}
@@ -1213,7 +1244,7 @@ internal async Task WriteValueNotNullAsync(Task task, Uri value, CancellationTok
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(ushort value, CancellationToken cancellationToken = default)
{
return _safeAsync ? WriteIntegerValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -1227,7 +1258,7 @@ public override Task WriteValueAsync(ushort value, CancellationToken cancellatio
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override Task WriteValueAsync(ushort? value, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteValueAsync(value, cancellationToken) : base.WriteValueAsync(value, cancellationToken);
@@ -1246,16 +1277,16 @@ internal Task DoWriteValueAsync(ushort? value, CancellationToken cancellationTok
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task WriteCommentAsync(string text, CancellationToken cancellationToken = default)
+ public override Task WriteCommentAsync(string? text, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteCommentAsync(text, cancellationToken) : base.WriteCommentAsync(text, cancellationToken);
}
- internal async Task DoWriteCommentAsync(string text, CancellationToken cancellationToken)
+ internal async Task DoWriteCommentAsync(string? text, CancellationToken cancellationToken)
{
await InternalWriteCommentAsync(cancellationToken).ConfigureAwait(false);
await _writer.WriteAsync("/*", cancellationToken).ConfigureAwait(false);
- await _writer.WriteAsync(text, cancellationToken).ConfigureAwait(false);
+ await _writer.WriteAsync(text ?? string.Empty, cancellationToken).ConfigureAwait(false);
await _writer.WriteAsync("*/", cancellationToken).ConfigureAwait(false);
}
@@ -1303,16 +1334,16 @@ public override Task WriteEndObjectAsync(CancellationToken cancellationToken = d
/// A that represents the asynchronous operation.
/// Derived classes must override this method to get asynchronous behaviour. Otherwise it will
/// execute synchronously, returning an already-completed task.
- public override Task WriteRawValueAsync(string json, CancellationToken cancellationToken = default)
+ public override Task WriteRawValueAsync(string? json, CancellationToken cancellationToken = default)
{
return _safeAsync ? DoWriteRawValueAsync(json, cancellationToken) : base.WriteRawValueAsync(json, cancellationToken);
}
- internal Task DoWriteRawValueAsync(string json, CancellationToken cancellationToken)
+ internal Task DoWriteRawValueAsync(string? json, CancellationToken cancellationToken)
{
UpdateScopeWithFinishedValue();
Task task = AutoCompleteAsync(JsonToken.Undefined, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return WriteRawAsync(json, cancellationToken);
}
@@ -1320,7 +1351,7 @@ internal Task DoWriteRawValueAsync(string json, CancellationToken cancellationTo
return DoWriteRawValueAsync(task, json, cancellationToken);
}
- private async Task DoWriteRawValueAsync(Task task, string json, CancellationToken cancellationToken)
+ private async Task DoWriteRawValueAsync(Task task, string? json, CancellationToken cancellationToken)
{
await task.ConfigureAwait(false);
await WriteRawAsync(json, cancellationToken).ConfigureAwait(false);
@@ -1333,7 +1364,7 @@ internal char[] EnsureWriteBuffer(int length, int copyTo)
length = 35;
}
- char[] buffer = _writeBuffer;
+ char[]? buffer = _writeBuffer;
if (buffer == null)
{
return _writeBuffer = BufferUtils.RentBuffer(_arrayPool, length);
@@ -1355,5 +1386,7 @@ internal char[] EnsureWriteBuffer(int length, int copyTo)
return newBuffer;
}
}
+#nullable disable
+#pragma warning restore CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.cs
index 71013d2988..7d9ed0c5b1 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonTextWriter.cs
@@ -33,9 +33,12 @@
using System.IO;
using System.Xml;
using Microsoft.IdentityModel.Json.Utilities;
+using System.Diagnostics;
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
///
/// Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
///
@@ -43,15 +46,15 @@ internal partial class JsonTextWriter : JsonWriter
{
private const int IndentCharBufferSize = 12;
private readonly TextWriter _writer;
- private Base64Encoder _base64Encoder;
+ private Base64Encoder? _base64Encoder;
private char _indentChar;
private int _indentation;
private char _quoteChar;
private bool _quoteName;
- private bool[] _charEscapeFlags;
- private char[] _writeBuffer;
- private IArrayPool _arrayPool;
- private char[] _indentChars;
+ private bool[]? _charEscapeFlags;
+ private char[]? _writeBuffer;
+ private IArrayPool? _arrayPool;
+ private char[]? _indentChars;
private Base64Encoder Base64Encoder
{
@@ -69,7 +72,7 @@ private Base64Encoder Base64Encoder
///
/// Gets or sets the writer's character array pool.
///
- public IArrayPool ArrayPool
+ public IArrayPool? ArrayPool
{
get => _arrayPool;
set
@@ -324,6 +327,7 @@ protected override void WriteIndent()
int newLineLen = SetIndentChars();
+ MiscellaneousUtils.Assert(_indentChars != null);
_writer.Write(_indentChars, 0, newLineLen + Math.Min(currentIndentCount, IndentCharBufferSize));
while ((currentIndentCount -= IndentCharBufferSize) > 0)
@@ -342,7 +346,7 @@ private int SetIndentChars()
{
for (int i = 0; i != newLineLen; ++i)
{
- if (writerNewLine[i] != _indentChars[i])
+ if (writerNewLine[i] != _indentChars![i])
{
match = false;
break;
@@ -387,7 +391,7 @@ private void WriteValueInternal(string value, JsonToken token)
/// An error will raised if the value cannot be written as a single JSON token.
///
/// The value to write.
- public override void WriteValue(object value)
+ public override void WriteValue(object? value)
{
#if HAVE_BIG_INTEGER
if (value is BigInteger i)
@@ -424,7 +428,7 @@ public override void WriteUndefined()
/// Writes raw JSON.
///
/// The raw JSON to write.
- public override void WriteRaw(string json)
+ public override void WriteRaw(string? json)
{
InternalWriteRaw();
@@ -435,7 +439,7 @@ public override void WriteRaw(string json)
/// Writes a value.
///
/// The value to write.
- public override void WriteValue(string value)
+ public override void WriteValue(string? value)
{
InternalWriteValue(JsonToken.String);
@@ -452,7 +456,7 @@ public override void WriteValue(string value)
private void WriteEscapedString(string value, bool quote)
{
EnsureWriteBuffer();
- JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, quote, _charEscapeFlags, StringEscapeHandling, _arrayPool, ref _writeBuffer);
+ JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, quote, _charEscapeFlags!, StringEscapeHandling, _arrayPool, ref _writeBuffer);
}
///
@@ -469,7 +473,7 @@ public override void WriteValue(int value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(uint value)
{
InternalWriteValue(JsonToken.Integer);
@@ -490,7 +494,7 @@ public override void WriteValue(long value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(ulong value)
{
InternalWriteValue(JsonToken.Integer);
@@ -575,7 +579,7 @@ public override void WriteValue(short value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(ushort value)
{
InternalWriteValue(JsonToken.Integer);
@@ -606,7 +610,7 @@ public override void WriteValue(byte value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(sbyte value)
{
InternalWriteValue(JsonToken.Integer);
@@ -632,10 +636,11 @@ public override void WriteValue(DateTime value)
InternalWriteValue(JsonToken.Date);
value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling);
- if (string.IsNullOrEmpty(DateFormatString))
+ if (StringUtils.IsNullOrEmpty(DateFormatString))
{
int length = WriteValueToBuffer(value);
+ MiscellaneousUtils.Assert(_writeBuffer != null);
_writer.Write(_writeBuffer, 0, length);
}
else
@@ -649,6 +654,7 @@ public override void WriteValue(DateTime value)
private int WriteValueToBuffer(DateTime value)
{
EnsureWriteBuffer();
+ MiscellaneousUtils.Assert(_writeBuffer != null);
int pos = 0;
_writeBuffer[pos++] = _quoteChar;
@@ -661,7 +667,7 @@ private int WriteValueToBuffer(DateTime value)
/// Writes a [] value.
///
/// The [] value to write.
- public override void WriteValue(byte[] value)
+ public override void WriteValue(byte[]? value)
{
if (value == null)
{
@@ -686,10 +692,11 @@ public override void WriteValue(DateTimeOffset value)
{
InternalWriteValue(JsonToken.Date);
- if (string.IsNullOrEmpty(DateFormatString))
+ if (StringUtils.IsNullOrEmpty(DateFormatString))
{
int length = WriteValueToBuffer(value);
+ MiscellaneousUtils.Assert(_writeBuffer != null);
_writer.Write(_writeBuffer, 0, length);
}
else
@@ -703,6 +710,7 @@ public override void WriteValue(DateTimeOffset value)
private int WriteValueToBuffer(DateTimeOffset value)
{
EnsureWriteBuffer();
+ MiscellaneousUtils.Assert(_writeBuffer != null);
int pos = 0;
_writeBuffer[pos++] = _quoteChar;
@@ -720,14 +728,12 @@ public override void WriteValue(Guid value)
{
InternalWriteValue(JsonToken.String);
- string text = null;
+ string text;
#if HAVE_CHAR_TO_STRING_WITH_CULTURE
text = value.ToString("D", CultureInfo.InvariantCulture);
#else
-#pragma warning disable CA1305 // Specify IFormatProvider
text = value.ToString("D");
-#pragma warning restore CA1305 // Specify IFormatProvider
#endif
_writer.Write(_quoteChar);
@@ -759,7 +765,7 @@ public override void WriteValue(TimeSpan value)
/// Writes a value.
///
/// The value to write.
- public override void WriteValue(Uri value)
+ public override void WriteValue(Uri? value)
{
if (value == null)
{
@@ -774,10 +780,10 @@ public override void WriteValue(Uri value)
#endregion
///
- /// Writes a comment /*...*/ containing the specified text.
+ /// Writes a comment /*...*/ containing the specified text.
///
/// Text to place inside the comment.
- public override void WriteComment(string text)
+ public override void WriteComment(string? text)
{
InternalWriteComment();
@@ -828,6 +834,8 @@ private void WriteIntegerValue(ulong value, bool negative)
else
{
int length = WriteNumberToBuffer(value, negative);
+
+ MiscellaneousUtils.Assert(_writeBuffer != null);
_writer.Write(_writeBuffer, 0, length);
}
}
@@ -841,6 +849,7 @@ private int WriteNumberToBuffer(ulong value, bool negative)
}
EnsureWriteBuffer();
+ MiscellaneousUtils.Assert(_writeBuffer != null);
int totalLength = MathUtils.IntLength(value);
@@ -885,6 +894,8 @@ private void WriteIntegerValue(uint value, bool negative)
else
{
int length = WriteNumberToBuffer(value, negative);
+
+ MiscellaneousUtils.Assert(_writeBuffer != null);
_writer.Write(_writeBuffer, 0, length);
}
}
@@ -892,6 +903,7 @@ private void WriteIntegerValue(uint value, bool negative)
private int WriteNumberToBuffer(uint value, bool negative)
{
EnsureWriteBuffer();
+ MiscellaneousUtils.Assert(_writeBuffer != null);
int totalLength = MathUtils.IntLength(value);
@@ -914,4 +926,6 @@ private int WriteNumberToBuffer(uint value, bool negative)
return totalLength;
}
}
-}
\ No newline at end of file
+#nullable disable
+#pragma warning restore CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonToken.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonToken.cs
index 5dda7f69bf..6a734c26ee 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonToken.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonToken.cs
@@ -124,4 +124,4 @@ internal enum JsonToken
///
Bytes = 17
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonValidatingReader.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonValidatingReader.cs
index de3b55b01e..3d22398750 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonValidatingReader.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonValidatingReader.cs
@@ -41,6 +41,8 @@
#endif
+#nullable disable
+
namespace Microsoft.IdentityModel.Json
{
///
@@ -121,7 +123,7 @@ private IEnumerable GetRequiredProperties(JsonSchemaModel schema)
public override int Depth => _reader.Depth;
///
- /// Gets the path of the current JSON token.
+ /// Gets the path of the current JSON token.
///
public override string Path => _reader.Path;
@@ -1020,4 +1022,4 @@ bool IJsonLineInfo.HasLineInfo()
int IJsonLineInfo.LinePosition => (_reader is IJsonLineInfo lineInfo) ? lineInfo.LinePosition : 0;
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.Async.cs
index c7262e1c65..2085c55354 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.Async.cs
@@ -36,8 +36,23 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
internal abstract partial class JsonWriter
+#if HAVE_ASYNC_DISPOABLE
+ : IAsyncDisposable
+#endif
{
+#if HAVE_ASYNC_DISPOABLE
+ async ValueTask IAsyncDisposable.DisposeAsync()
+ {
+ if (_currentState != State.Closed)
+ {
+ await CloseAsync().ConfigureAwait(false);
+ }
+ }
+#endif
+
internal Task AutoCompleteAsync(JsonToken tokenBeingWritten, CancellationToken cancellationToken)
{
State oldState = _currentState;
@@ -225,7 +240,7 @@ protected virtual Task WriteIndentSpaceAsync(CancellationToken cancellationToken
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task WriteRawAsync(string json, CancellationToken cancellationToken = default)
+ public virtual Task WriteRawAsync(string? json, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -291,7 +306,7 @@ internal Task InternalWriteEndAsync(JsonContainerType type, CancellationToken ca
if (_currentState == State.Property)
{
t = WriteNullAsync(cancellationToken);
- if (!t.IsCompletedSucessfully())
+ if (!t.IsCompletedSuccessfully())
{
return AwaitProperty(t, levelsToComplete, token, cancellationToken);
}
@@ -302,7 +317,7 @@ internal Task InternalWriteEndAsync(JsonContainerType type, CancellationToken ca
if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
{
t = WriteIndentAsync(cancellationToken);
- if (!t.IsCompletedSucessfully())
+ if (!t.IsCompletedSuccessfully())
{
return AwaitIndent(t, levelsToComplete, token, cancellationToken);
}
@@ -310,7 +325,7 @@ internal Task InternalWriteEndAsync(JsonContainerType type, CancellationToken ca
}
t = WriteEndAsync(token, cancellationToken);
- if (!t.IsCompletedSucessfully())
+ if (!t.IsCompletedSuccessfully())
{
return AwaitEnd(t, levelsToComplete, cancellationToken);
}
@@ -546,7 +561,7 @@ internal async Task InternalWriteStartAsync(JsonToken token, JsonContainerType c
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task WriteCommentAsync(string text, CancellationToken cancellationToken = default)
+ public virtual Task WriteCommentAsync(string? text, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -570,7 +585,7 @@ internal Task InternalWriteCommentAsync(CancellationToken cancellationToken)
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task WriteRawValueAsync(string json, CancellationToken cancellationToken = default)
+ public virtual Task WriteRawValueAsync(string? json, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -673,7 +688,7 @@ public Task WriteTokenAsync(JsonToken token, CancellationToken cancellationToken
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public Task WriteTokenAsync(JsonToken token, object value, CancellationToken cancellationToken = default)
+ public Task WriteTokenAsync(JsonToken token, object? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -691,10 +706,10 @@ public Task WriteTokenAsync(JsonToken token, object value, CancellationToken can
return WriteStartArrayAsync(cancellationToken);
case JsonToken.StartConstructor:
ValidationUtils.ArgumentNotNull(value, nameof(value));
- return WriteStartConstructorAsync(value.ToString(), cancellationToken);
+ return WriteStartConstructorAsync(value.ToString()!, cancellationToken);
case JsonToken.PropertyName:
ValidationUtils.ArgumentNotNull(value, nameof(value));
- return WritePropertyNameAsync(value.ToString(), cancellationToken);
+ return WritePropertyNameAsync(value.ToString()!, cancellationToken);
case JsonToken.Comment:
return WriteCommentAsync(value?.ToString(), cancellationToken);
case JsonToken.Integer:
@@ -755,7 +770,7 @@ public Task WriteTokenAsync(JsonToken token, object value, CancellationToken can
return WriteValueAsync(guid, cancellationToken);
}
- return WriteValueAsync((byte[])value, cancellationToken);
+ return WriteValueAsync((byte[]?)value, cancellationToken);
default:
throw MiscellaneousUtils.CreateArgumentOutOfRangeException(nameof(token), token, "Unexpected token type.");
}
@@ -768,7 +783,7 @@ internal virtual async Task WriteTokenAsync(JsonReader reader, bool writeChildre
do
{
// write a JValue date when the constructor is for a date
- if (writeDateConstructorAsDate && reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
+ if (writeDateConstructorAsDate && reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value?.ToString(), "Date", StringComparison.Ordinal))
{
await WriteConstructorDateAsync(reader, cancellationToken).ConfigureAwait(false);
}
@@ -785,7 +800,7 @@ internal virtual async Task WriteTokenAsync(JsonReader reader, bool writeChildre
&& writeChildren
&& await reader.ReadAsync(cancellationToken).ConfigureAwait(false));
- if (initialDepth < CalculateWriteTokenFinalDepth(reader))
+ if (IsWriteTokenIncomplete(reader, writeChildren, initialDepth))
{
throw JsonWriterException.Create(this, "Unexpected end when reading token.", null);
}
@@ -801,7 +816,7 @@ internal async Task WriteTokenSyncReadingAsync(JsonReader reader, CancellationTo
do
{
// write a JValue date when the constructor is for a date
- if (reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
+ if (reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value?.ToString(), "Date", StringComparison.Ordinal))
{
WriteConstructorDate(reader);
}
@@ -831,7 +846,7 @@ private async Task WriteConstructorDateAsync(JsonReader reader, CancellationToke
throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null);
}
- DateTime date = DateTimeUtils.ConvertJavaScriptTicksToDateTime((long)reader.Value);
+ DateTime date = DateTimeUtils.ConvertJavaScriptTicksToDateTime((long)reader.Value!);
if (!await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
{
@@ -929,7 +944,7 @@ public virtual Task WriteValueAsync(byte? value, CancellationToken cancellationT
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task WriteValueAsync(byte[] value, CancellationToken cancellationToken = default)
+ public virtual Task WriteValueAsync(byte[]? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -1290,7 +1305,7 @@ public virtual Task WriteValueAsync(long? value, CancellationToken cancellationT
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task WriteValueAsync(object value, CancellationToken cancellationToken = default)
+ public virtual Task WriteValueAsync(object? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -1309,7 +1324,7 @@ public virtual Task WriteValueAsync(object value, CancellationToken cancellation
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(sbyte value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1329,7 +1344,7 @@ public virtual Task WriteValueAsync(sbyte value, CancellationToken cancellationT
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(sbyte? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1387,7 +1402,7 @@ public virtual Task WriteValueAsync(short? value, CancellationToken cancellation
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task WriteValueAsync(string value, CancellationToken cancellationToken = default)
+ public virtual Task WriteValueAsync(string? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -1444,7 +1459,7 @@ public virtual Task WriteValueAsync(TimeSpan? value, CancellationToken cancellat
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(uint value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1464,7 +1479,7 @@ public virtual Task WriteValueAsync(uint value, CancellationToken cancellationTo
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(uint? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1484,7 +1499,7 @@ public virtual Task WriteValueAsync(uint? value, CancellationToken cancellationT
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(ulong value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1504,7 +1519,7 @@ public virtual Task WriteValueAsync(ulong value, CancellationToken cancellationT
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(ulong? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1524,7 +1539,7 @@ public virtual Task WriteValueAsync(ulong? value, CancellationToken cancellation
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- public virtual Task WriteValueAsync(Uri value, CancellationToken cancellationToken = default)
+ public virtual Task WriteValueAsync(Uri? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -1543,7 +1558,7 @@ public virtual Task WriteValueAsync(Uri value, CancellationToken cancellationTok
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(ushort value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1563,7 +1578,7 @@ public virtual Task WriteValueAsync(ushort value, CancellationToken cancellation
/// A that represents the asynchronous operation.
/// The default behaviour is to execute synchronously, returning an already-completed task. Derived
/// classes can override this behaviour for true asynchronicity.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual Task WriteValueAsync(ushort? value, CancellationToken cancellationToken = default)
{
if (cancellationToken.IsCancellationRequested)
@@ -1781,7 +1796,7 @@ internal static Task WriteValueAsync(JsonWriter writer, PrimitiveTypeCode typeCo
}
#endif
- // write an unknown null value, fix https://github.com/JamesNK/Microsoft.IdentityModel.Json/issues/1460
+ // write an unknown null value, fix https://github.com/JamesNK/Newtonsoft.Json/issues/1460
if (value == null)
{
return writer.WriteNullAsync(cancellationToken);
@@ -1792,6 +1807,8 @@ internal static Task WriteValueAsync(JsonWriter writer, PrimitiveTypeCode typeCo
}
}
}
+#nullable disable
+#pragma warning restore CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.cs
index af651253cf..117d11754a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriter.cs
@@ -40,6 +40,8 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
///
/// Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
///
@@ -62,7 +64,7 @@ internal enum State
// array that gives a new state based on the current state an the token being written
private static readonly State[][] StateArray;
- internal static readonly State[][] StateArrayTempate = new[]
+ internal static readonly State[][] StateArrayTemplate = new[]
{
// Start PropertyName ObjectStart Object ArrayStart Array ConstructorStart Constructor Closed Error
//
@@ -78,9 +80,9 @@ internal enum State
internal static State[][] BuildStateArray()
{
- List allStates = StateArrayTempate.ToList();
- State[] errorStates = StateArrayTempate[0];
- State[] valueStates = StateArrayTempate[7];
+ List allStates = StateArrayTemplate.ToList();
+ State[] errorStates = StateArrayTemplate[0];
+ State[] valueStates = StateArrayTemplate[7];
EnumInfo enumValuesAndNames = EnumUtils.GetEnumValuesAndNames(typeof(JsonToken));
@@ -116,7 +118,7 @@ static JsonWriter()
StateArray = BuildStateArray();
}
- private List _stack;
+ private List? _stack;
private JsonPosition _currentPosition;
private State _currentState;
private Formatting _formatting;
@@ -182,7 +184,9 @@ public WriteState WriteState
case State.Start:
return WriteState.Start;
default:
+#pragma warning disable CA1065 // Do not raise exceptions in unexpected locations
throw JsonWriterException.Create(this, "Invalid state: " + _currentState, null);
+#pragma warning restore CA1065 // Do not raise exceptions in unexpected locations
}
}
}
@@ -201,7 +205,7 @@ internal string ContainerPath
}
///
- /// Gets the path of the writer.
+ /// Gets the path of the writer.
///
public string Path
{
@@ -218,7 +222,7 @@ public string Path
JsonPosition? current = insideContainer ? (JsonPosition?)_currentPosition : null;
- return JsonPosition.BuildPath(_stack, current);
+ return JsonPosition.BuildPath(_stack!, current);
}
}
@@ -226,8 +230,8 @@ public string Path
private DateTimeZoneHandling _dateTimeZoneHandling;
private StringEscapeHandling _stringEscapeHandling;
private FloatFormatHandling _floatFormatHandling;
- private string _dateFormatString;
- private CultureInfo _culture;
+ private string? _dateFormatString;
+ private CultureInfo? _culture;
///
/// Gets or sets a value indicating how JSON text output should be formatted.
@@ -325,7 +329,7 @@ public FloatFormatHandling FloatFormatHandling
///
/// Gets or sets how and values are formatted when writing JSON text.
///
- public string DateFormatString
+ public string? DateFormatString
{
get => _dateFormatString;
set => _dateFormatString = value;
@@ -522,7 +526,7 @@ public void WriteToken(JsonReader reader, bool writeChildren)
/// A value is only required for tokens that have an associated value, e.g. the property name for .
/// null can be passed to the method for tokens that don't have a value, e.g. .
///
- public void WriteToken(JsonToken token, object value)
+ public void WriteToken(JsonToken token, object? value)
{
switch (token)
{
@@ -537,11 +541,11 @@ public void WriteToken(JsonToken token, object value)
break;
case JsonToken.StartConstructor:
ValidationUtils.ArgumentNotNull(value, nameof(value));
- WriteStartConstructor(value.ToString());
+ WriteStartConstructor(value.ToString()!);
break;
case JsonToken.PropertyName:
ValidationUtils.ArgumentNotNull(value, nameof(value));
- WritePropertyName(value.ToString());
+ WritePropertyName(value.ToString()!);
break;
case JsonToken.Comment:
WriteComment(value?.ToString());
@@ -579,8 +583,9 @@ public void WriteToken(JsonToken token, object value)
}
break;
case JsonToken.String:
- ValidationUtils.ArgumentNotNull(value, nameof(value));
- WriteValue(value.ToString());
+ // Allow for a null string. This matches JTokenReader behavior which can read
+ // a JsonToken.String with a null value.
+ WriteValue(value?.ToString());
break;
case JsonToken.Boolean:
ValidationUtils.ArgumentNotNull(value, nameof(value));
@@ -625,7 +630,7 @@ public void WriteToken(JsonToken token, object value)
}
else
{
- WriteValue((byte[])value);
+ WriteValue((byte[])value!);
}
break;
default:
@@ -649,7 +654,7 @@ internal virtual void WriteToken(JsonReader reader, bool writeChildren, bool wri
do
{
// write a JValue date when the constructor is for a date
- if (writeDateConstructorAsDate && reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal))
+ if (writeDateConstructorAsDate && reader.TokenType == JsonToken.StartConstructor && string.Equals(reader.Value?.ToString(), "Date", StringComparison.Ordinal))
{
WriteConstructorDate(reader);
}
@@ -666,12 +671,19 @@ internal virtual void WriteToken(JsonReader reader, bool writeChildren, bool wri
&& writeChildren
&& reader.Read());
- if (initialDepth < CalculateWriteTokenFinalDepth(reader))
+ if (IsWriteTokenIncomplete(reader, writeChildren, initialDepth))
{
throw JsonWriterException.Create(this, "Unexpected end when reading token.", null);
}
}
+ private bool IsWriteTokenIncomplete(JsonReader reader, bool writeChildren, int initialDepth)
+ {
+ int finalDepth = CalculateWriteTokenFinalDepth(reader);
+ return initialDepth < finalDepth ||
+ (writeChildren && initialDepth == finalDepth && JsonTokenUtils.IsStartToken(reader.TokenType));
+ }
+
private int CalculateWriteTokenInitialDepth(JsonReader reader)
{
JsonToken type = reader.TokenType;
@@ -696,7 +708,7 @@ private int CalculateWriteTokenFinalDepth(JsonReader reader)
private void WriteConstructorDate(JsonReader reader)
{
- if (!JavaScriptUtils.TryGetDateFromConstructorJson(reader, out DateTime dateTime, out string errorMessage))
+ if (!JavaScriptUtils.TryGetDateFromConstructorJson(reader, out DateTime dateTime, out string? errorMessage))
{
throw JsonWriterException.Create(this, errorMessage, null);
}
@@ -787,7 +799,7 @@ private int CalculateLevelsToComplete(JsonContainerType type)
{
int currentLevel = top - i;
- if (_stack[currentLevel].Type == type)
+ if (_stack![currentLevel].Type == type)
{
levelsToComplete = i + 2;
break;
@@ -909,7 +921,7 @@ public virtual void WriteUndefined()
/// Writes raw JSON without changing the writer's state.
///
/// The raw JSON to write.
- public virtual void WriteRaw(string json)
+ public virtual void WriteRaw(string? json)
{
InternalWriteRaw();
}
@@ -918,7 +930,7 @@ public virtual void WriteRaw(string json)
/// Writes raw JSON where a value is expected and updates the writer's state.
///
/// The raw JSON to write.
- public virtual void WriteRawValue(string json)
+ public virtual void WriteRawValue(string? json)
{
// hack. want writer to change state as if a value had been written
UpdateScopeWithFinishedValue();
@@ -930,7 +942,7 @@ public virtual void WriteRawValue(string json)
/// Writes a value.
///
/// The value to write.
- public virtual void WriteValue(string value)
+ public virtual void WriteValue(string? value)
{
InternalWriteValue(JsonToken.String);
}
@@ -948,7 +960,7 @@ public virtual void WriteValue(int value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(uint value)
{
InternalWriteValue(JsonToken.Integer);
@@ -967,7 +979,7 @@ public virtual void WriteValue(long value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(ulong value)
{
InternalWriteValue(JsonToken.Integer);
@@ -1013,7 +1025,7 @@ public virtual void WriteValue(short value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(ushort value)
{
InternalWriteValue(JsonToken.Integer);
@@ -1041,7 +1053,7 @@ public virtual void WriteValue(byte value)
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(sbyte value)
{
InternalWriteValue(JsonToken.Integer);
@@ -1114,7 +1126,7 @@ public virtual void WriteValue(int? value)
/// Writes a of value.
///
/// The of value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(uint? value)
{
if (value == null)
@@ -1147,7 +1159,7 @@ public virtual void WriteValue(long? value)
/// Writes a of value.
///
/// The of value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(ulong? value)
{
if (value == null)
@@ -1228,7 +1240,7 @@ public virtual void WriteValue(short? value)
/// Writes a of value.
///
/// The of value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(ushort? value)
{
if (value == null)
@@ -1277,7 +1289,7 @@ public virtual void WriteValue(byte? value)
/// Writes a of value.
///
/// The of value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public virtual void WriteValue(sbyte? value)
{
if (value == null)
@@ -1376,7 +1388,7 @@ public virtual void WriteValue(TimeSpan? value)
/// Writes a [] value.
///
/// The [] value to write.
- public virtual void WriteValue(byte[] value)
+ public virtual void WriteValue(byte[]? value)
{
if (value == null)
{
@@ -1392,7 +1404,7 @@ public virtual void WriteValue(byte[] value)
/// Writes a value.
///
/// The value to write.
- public virtual void WriteValue(Uri value)
+ public virtual void WriteValue(Uri? value)
{
if (value == null)
{
@@ -1409,7 +1421,7 @@ public virtual void WriteValue(Uri value)
/// An error will raised if the value cannot be written as a single JSON token.
///
/// The value to write.
- public virtual void WriteValue(object value)
+ public virtual void WriteValue(object? value)
{
if (value == null)
{
@@ -1435,7 +1447,7 @@ public virtual void WriteValue(object value)
/// Writes a comment /*...*/ containing the specified text.
///
/// Text to place inside the comment.
- public virtual void WriteComment(string text)
+ public virtual void WriteComment(string? text)
{
InternalWriteComment();
}
@@ -1449,7 +1461,9 @@ public virtual void WriteWhitespace(string ws)
InternalWriteWhitespace(ws);
}
+#pragma warning disable CA1063 // Implement IDisposable Correctly
void IDisposable.Dispose()
+#pragma warning restore CA1063 // Implement IDisposable Correctly
{
Dispose(true);
GC.SuppressFinalize(this);
@@ -1647,7 +1661,7 @@ internal static void WriteValue(JsonWriter writer, PrimitiveTypeCode typeCode, o
}
#endif
- // write an unknown null value, fix https://github.com/JamesNK/Microsoft.IdentityModel.Json/issues/1460
+ // write an unknown null value, fix https://github.com/JamesNK/Newtonsoft.Json/issues/1460
if (value == null)
{
writer.WriteNull();
@@ -1778,4 +1792,6 @@ internal void InternalWriteComment()
AutoComplete(JsonToken.Comment);
}
}
-}
\ No newline at end of file
+#nullable disable
+#pragma warning restore CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriterException.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriterException.cs
index bbfba9c112..1dc33ae37d 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriterException.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/JsonWriterException.cs
@@ -30,6 +30,7 @@
namespace Microsoft.IdentityModel.Json
{
+#nullable enable
///
/// The exception thrown when an error occurs while writing JSON text.
///
@@ -42,7 +43,7 @@ internal class JsonWriterException : JsonException
/// Gets the path to the JSON where the error occurred.
///
/// The path to the JSON where the error occurred.
- public string Path { get; }
+ public string? Path { get; }
///
/// Initializes a new instance of the class.
@@ -93,22 +94,23 @@ public JsonWriterException(SerializationInfo info, StreamingContext context)
/// The error message that explains the reason for the exception.
/// The path to the JSON where the error occurred.
/// The exception that is the cause of the current exception, or null if no inner exception is specified.
- public JsonWriterException(string message, string path, Exception innerException)
+ public JsonWriterException(string message, string path, Exception? innerException)
: base(message, innerException)
{
Path = path;
}
- internal static JsonWriterException Create(JsonWriter writer, string message, Exception ex)
+ internal static JsonWriterException Create(JsonWriter writer, string message, Exception? ex)
{
return Create(writer.ContainerPath, message, ex);
}
- internal static JsonWriterException Create(string path, string message, Exception ex)
+ internal static JsonWriterException Create(string path, string message, Exception? ex)
{
message = JsonPosition.FormatMessage(null, path, message);
return new JsonWriterException(message, path, ex);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/CommentHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/CommentHandling.cs
index 4fd8bcf488..eea593959b 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/CommentHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/CommentHandling.cs
@@ -40,4 +40,4 @@ internal enum CommentHandling
///
Load = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/DuplicatePropertyNameHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/DuplicatePropertyNameHandling.cs
new file mode 100644
index 0000000000..d7800d4057
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/DuplicatePropertyNameHandling.cs
@@ -0,0 +1,46 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Microsoft.IdentityModel.Json.Linq
+{
+ ///
+ /// Specifies how duplicate property names are handled when loading JSON.
+ ///
+ internal enum DuplicatePropertyNameHandling
+ {
+ ///
+ /// Replace the existing value when there is a duplicate property. The value of the last property in the JSON object will be used.
+ ///
+ Replace = 0,
+ ///
+ /// Ignore the new value when there is a duplicate property. The value of the first property in the JSON object will be used.
+ ///
+ Ignore = 1,
+ ///
+ /// Throw a when a duplicate property is encountered.
+ ///
+ Error = 2
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/Extensions.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/Extensions.cs
index fb880d2da0..1507a21edd 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/Extensions.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/Extensions.cs
@@ -27,6 +27,8 @@
using System.Collections.Generic;
using Microsoft.IdentityModel.Json.Utilities;
using System.Globalization;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
@@ -36,6 +38,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Contains the LINQ to JSON extension methods.
///
@@ -111,9 +114,9 @@ public static IJEnumerable Properties(this IEnumerable sourc
/// An of that contains the source collection.
/// The token key.
/// An of that contains the values of every token in the source collection with the given key.
- public static IJEnumerable Values(this IEnumerable source, object key)
+ public static IJEnumerable Values(this IEnumerable source, object? key)
{
- return Values(source, key).AsJEnumerable();
+ return Values(source, key)!.AsJEnumerable();
}
///
@@ -133,7 +136,7 @@ public static IJEnumerable Values(this IEnumerable source)
/// An of that contains the source collection.
/// The token key.
/// An that contains the converted values of every token in the source collection with the given key.
- public static IEnumerable Values(this IEnumerable source, object key)
+ public static IEnumerable Values(this IEnumerable source, object key)
{
return Values(source, key);
}
@@ -144,7 +147,7 @@ public static IEnumerable Values(this IEnumerable source, object k
/// The type to convert the values to.
/// An of that contains the source collection.
/// An that contains the converted values of every token in the source collection.
- public static IEnumerable Values(this IEnumerable source)
+ public static IEnumerable Values(this IEnumerable source)
{
return Values(source, null);
}
@@ -155,7 +158,7 @@ public static IEnumerable Values(this IEnumerable source)
/// The type to convert the value to.
/// A cast as a of .
/// A converted value.
- public static U Value(this IEnumerable value)
+ public static U? Value(this IEnumerable value)
{
return value.Value();
}
@@ -167,7 +170,7 @@ public static U Value(this IEnumerable value)
/// The type to convert the value to.
/// A cast as a of .
/// A converted value.
- public static U Value(this IEnumerable value) where T : JToken
+ public static U? Value(this IEnumerable value) where T : JToken
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
@@ -179,7 +182,7 @@ public static U Value(this IEnumerable value) where T : JToken
return token.Convert();
}
- internal static IEnumerable Values(this IEnumerable source, object key) where T : JToken
+ internal static IEnumerable Values(this IEnumerable source, object? key) where T : JToken
{
ValidationUtils.ArgumentNotNull(source, nameof(source));
@@ -204,7 +207,7 @@ internal static IEnumerable Values(this IEnumerable source, object k
{
foreach (T token in source)
{
- JToken value = token[key];
+ JToken? value = token[key];
if (value != null)
{
yield return value.Convert();
@@ -224,7 +227,7 @@ internal static IEnumerable Values(this IEnumerable source, object k
/// An of that contains the values of every token in the source collection.
public static IJEnumerable Children(this IEnumerable source) where T : JToken
{
- return Children(source).AsJEnumerable();
+ return Children(source)!.AsJEnumerable();
}
///
@@ -234,14 +237,14 @@ public static IJEnumerable Children(this IEnumerable source) where
/// The type to convert the values to.
/// The source collection type.
/// An that contains the converted values of every token in the source collection.
- public static IEnumerable Children(this IEnumerable source) where T : JToken
+ public static IEnumerable Children(this IEnumerable source) where T : JToken
{
ValidationUtils.ArgumentNotNull(source, nameof(source));
return source.SelectMany(c => c.Children()).Convert();
}
- internal static IEnumerable Convert(this IEnumerable source) where T : JToken
+ internal static IEnumerable Convert(this IEnumerable source) where T : JToken
{
ValidationUtils.ArgumentNotNull(source, nameof(source));
@@ -251,7 +254,7 @@ internal static IEnumerable Convert(this IEnumerable source) where T
}
}
- internal static U Convert(this T token) where T : JToken
+ internal static U? Convert(this T token) where T : JToken?
{
if (token == null)
{
@@ -285,10 +288,10 @@ internal static U Convert(this T token) where T : JToken
return default;
}
- targetType = Nullable.GetUnderlyingType(targetType);
+ targetType = Nullable.GetUnderlyingType(targetType)!;
}
- return (U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture);
+ return (U?)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture);
}
}
@@ -315,7 +318,7 @@ public static IJEnumerable AsJEnumerable(this IEnumerable source) where
{
if (source == null)
{
- return null;
+ return null!;
}
else if (source is IJEnumerable customEnumerable)
{
@@ -327,4 +330,5 @@ public static IJEnumerable AsJEnumerable(this IEnumerable source) where
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/IJEnumerable.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/IJEnumerable.cs
index a1443fff94..93e20e1059 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/IJEnumerable.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/IJEnumerable.cs
@@ -43,4 +43,4 @@ internal interface IJEnumerable<
///
IJEnumerable this[object key] { get; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.Async.cs
index d4e035a9da..dd32a6ac39 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.Async.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
internal partial class JArray
{
///
@@ -54,7 +55,7 @@ public override async Task WriteToAsync(JsonWriter writer, CancellationToken can
}
///
- /// Asynchronously loads a from a .
+ /// Asynchronously loads a from a .
///
/// A that will be read for the content of the .
/// If this is null, default load settings will be used.
@@ -66,14 +67,14 @@ public override async Task WriteToAsync(JsonWriter writer, CancellationToken can
}
///
- /// Asynchronously loads a from a .
+ /// Asynchronously loads a from a .
///
/// A that will be read for the content of the .
/// The used to load the JSON.
/// If this is null, default load settings will be used.
/// The token to monitor for cancellation requests. The default value is .
/// A representing the asynchronous load. The property contains the JSON that was read from the specified .
- public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default)
+ public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings? settings, CancellationToken cancellationToken = default)
{
if (reader.TokenType == JsonToken.None)
{
@@ -98,6 +99,7 @@ public override async Task WriteToAsync(JsonWriter writer, CancellationToken can
return a;
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.cs
index 1d3180f190..a5a18bc502 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JArray.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a JSON array.
///
@@ -99,7 +100,7 @@ internal override JToken CloneToken()
}
///
- /// Loads an from a .
+ /// Loads an from a .
///
/// A that will be read for the content of the .
/// A that contains the JSON that was read from the specified .
@@ -109,13 +110,13 @@ internal override JToken CloneToken()
}
///
- /// Loads an from a .
+ /// Loads an from a .
///
/// A that will be read for the content of the .
/// The used to load the JSON.
/// If this is null, default load settings will be used.
/// A that contains the JSON that was read from the specified .
- public new static JArray Load(JsonReader reader, JsonLoadSettings settings)
+ public new static JArray Load(JsonReader reader, JsonLoadSettings? settings)
{
if (reader.TokenType == JsonToken.None)
{
@@ -163,7 +164,7 @@ internal override JToken CloneToken()
///
///
///
- public new static JArray Parse(string json, JsonLoadSettings settings)
+ public new static JArray Parse(string json, JsonLoadSettings? settings)
{
using (JsonReader reader = new JsonTextReader(new StringReader(json)))
{
@@ -227,7 +228,7 @@ public override void WriteTo(JsonWriter writer, params JsonConverter[] converter
/// Gets the with the specified key.
///
/// The with the specified key.
- public override JToken this[object key]
+ public override JToken? this[object key]
{
get
{
@@ -263,14 +264,19 @@ public JToken this[int index]
set => SetItem(index, value);
}
- internal override int IndexOfItem(JToken item)
+ internal override int IndexOfItem(JToken? item)
{
+ if (item == null)
+ {
+ return -1;
+ }
+
return _values.IndexOfReference(item);
}
- internal override void MergeItem(object content, JsonMergeSettings settings)
+ internal override void MergeItem(object content, JsonMergeSettings? settings)
{
- IEnumerable a = (IsMultiContent(content) || content is JArray)
+ IEnumerable? a = (IsMultiContent(content) || content is JArray)
? (IEnumerable)content
: null;
if (a == null)
@@ -395,4 +401,5 @@ internal override int GetDeepHashCode()
return ContentsHashCode();
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.Async.cs
index d256d96610..7c64a53ca3 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.Async.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
internal partial class JConstructor
{
///
@@ -43,7 +44,7 @@ internal partial class JConstructor
/// A that represents the asynchronous write operation.
public override async Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
{
- await writer.WriteStartConstructorAsync(_name, cancellationToken).ConfigureAwait(false);
+ await writer.WriteStartConstructorAsync(_name ?? string.Empty, cancellationToken).ConfigureAwait(false);
for (int i = 0; i < _values.Count; i++)
{
@@ -76,7 +77,7 @@ public override async Task WriteToAsync(JsonWriter writer, CancellationToken can
///
/// A that represents the asynchronous load. The
/// property returns a that contains the JSON that was read from the specified .
- public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default)
+ public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings? settings, CancellationToken cancellationToken = default)
{
if (reader.TokenType == JsonToken.None)
{
@@ -93,7 +94,7 @@ public override async Task WriteToAsync(JsonWriter writer, CancellationToken can
throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
- JConstructor c = new JConstructor((string)reader.Value);
+ JConstructor c = new JConstructor((string)reader.Value!);
c.SetLineInfo(reader as IJsonLineInfo, settings);
await c.ReadTokenFromAsync(reader, settings, cancellationToken).ConfigureAwait(false);
@@ -101,6 +102,7 @@ public override async Task WriteToAsync(JsonWriter writer, CancellationToken can
return c;
}
}
+#nullable disable
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.cs
index c4c27e5ebe..686acafeb5 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JConstructor.cs
@@ -31,12 +31,13 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a JSON constructor.
///
internal partial class JConstructor : JContainer
{
- private string _name;
+ private string? _name;
private readonly List _values = new List();
///
@@ -45,12 +46,17 @@ internal partial class JConstructor : JContainer
/// The container's children tokens.
protected override IList ChildrenTokens => _values;
- internal override int IndexOfItem(JToken item)
+ internal override int IndexOfItem(JToken? item)
{
+ if (item == null)
+ {
+ return -1;
+ }
+
return _values.IndexOfReference(item);
}
- internal override void MergeItem(object content, JsonMergeSettings settings)
+ internal override void MergeItem(object content, JsonMergeSettings? settings)
{
if (!(content is JConstructor c))
{
@@ -68,7 +74,7 @@ internal override void MergeItem(object content, JsonMergeSettings settings)
/// Gets or sets the name of this constructor.
///
/// The constructor name.
- public string Name
+ public string? Name
{
get => _name;
set => _name = value;
@@ -154,7 +160,7 @@ internal override JToken CloneToken()
/// A collection of which will be used when writing the token.
public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
{
- writer.WriteStartConstructor(_name);
+ writer.WriteStartConstructor(_name!);
int count = _values.Count;
for (int i = 0; i < count; i++)
@@ -169,7 +175,7 @@ public override void WriteTo(JsonWriter writer, params JsonConverter[] converter
/// Gets the with the specified key.
///
/// The with the specified key.
- public override JToken this[object key]
+ public override JToken? this[object key]
{
get
{
@@ -197,7 +203,13 @@ public override JToken this[object key]
internal override int GetDeepHashCode()
{
- return _name.GetHashCode() ^ ContentsHashCode();
+ int hash;
+#if HAVE_GETHASHCODE_STRING_COMPARISON
+ hash = _name?.GetHashCode(StringComparison.Ordinal) ?? 0;
+#else
+ hash = _name?.GetHashCode() ?? 0;
+#endif
+ return hash ^ ContentsHashCode();
}
///
@@ -217,7 +229,7 @@ internal override int GetDeepHashCode()
/// The used to load the JSON.
/// If this is null, default load settings will be used.
/// A that contains the JSON that was read from the specified .
- public new static JConstructor Load(JsonReader reader, JsonLoadSettings settings)
+ public new static JConstructor Load(JsonReader reader, JsonLoadSettings? settings)
{
if (reader.TokenType == JsonToken.None)
{
@@ -234,7 +246,7 @@ internal override int GetDeepHashCode()
throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
- JConstructor c = new JConstructor((string)reader.Value);
+ JConstructor c = new JConstructor((string)reader.Value!);
c.SetLineInfo(reader as IJsonLineInfo, settings);
c.ReadTokenFrom(reader, settings);
@@ -242,4 +254,5 @@ internal override int GetDeepHashCode()
return c;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.Async.cs
index c7feb2fad7..1c9e7715fe 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.Async.cs
@@ -26,6 +26,7 @@
#if HAVE_ASYNC
using System;
+using System.Diagnostics;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
@@ -33,9 +34,10 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
internal abstract partial class JContainer
{
- internal async Task ReadTokenFromAsync(JsonReader reader, JsonLoadSettings options, CancellationToken cancellationToken = default)
+ internal async Task ReadTokenFromAsync(JsonReader reader, JsonLoadSettings? options, CancellationToken cancellationToken = default)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
int startDepth = reader.Depth;
@@ -53,11 +55,11 @@ internal async Task ReadTokenFromAsync(JsonReader reader, JsonLoadSettings optio
}
}
- private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default)
+ private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings? settings, CancellationToken cancellationToken = default)
{
- IJsonLineInfo lineInfo = reader as IJsonLineInfo;
+ IJsonLineInfo? lineInfo = reader as IJsonLineInfo;
- JContainer parent = this;
+ JContainer? parent = this;
do
{
@@ -71,6 +73,8 @@ private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings sett
parent = parent.Parent;
}
+ MiscellaneousUtils.Assert(parent != null);
+
switch (reader.TokenType)
{
case JsonToken.None:
@@ -106,7 +110,7 @@ private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings sett
parent = parent.Parent;
break;
case JsonToken.StartConstructor:
- JConstructor constructor = new JConstructor(reader.Value.ToString());
+ JConstructor constructor = new JConstructor(reader.Value!.ToString()!);
constructor.SetLineInfo(lineInfo, settings);
parent.Add(constructor);
parent = constructor;
@@ -132,7 +136,7 @@ private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings sett
case JsonToken.Comment:
if (settings != null && settings.CommentHandling == CommentHandling.Load)
{
- v = JValue.CreateComment(reader.Value.ToString());
+ v = JValue.CreateComment(reader.Value!.ToString());
v.SetLineInfo(lineInfo, settings);
parent.Add(v);
}
@@ -148,21 +152,15 @@ private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings sett
parent.Add(v);
break;
case JsonToken.PropertyName:
- string propertyName = reader.Value.ToString();
- JProperty property = new JProperty(propertyName);
- property.SetLineInfo(lineInfo, settings);
- JObject parentObject = (JObject)parent;
- // handle multiple properties with the same name in JSON
- JProperty existingPropertyWithName = parentObject.Property(propertyName);
- if (existingPropertyWithName == null)
+ JProperty? property = ReadProperty(reader, settings, lineInfo, parent);
+ if (property != null)
{
- parent.Add(property);
+ parent = property;
}
else
{
- existingPropertyWithName.Replace(property);
+ await reader.SkipAsync().ConfigureAwait(false);
}
- parent = property;
break;
default:
throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
@@ -170,6 +168,7 @@ private async Task ReadContentFromAsync(JsonReader reader, JsonLoadSettings sett
} while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false));
}
}
+#nullable disable
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.cs
index e3d894bd55..4f64973c53 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JContainer.cs
@@ -33,15 +33,18 @@
using System.Collections;
using System.Globalization;
using System.ComponentModel;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
using System.Linq;
-
#endif
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a token that can contain other tokens.
///
@@ -55,8 +58,8 @@ namespace Microsoft.IdentityModel.Json.Linq
#endif
{
#if HAVE_COMPONENT_MODEL
- internal ListChangedEventHandler _listChanged;
- internal AddingNewEventHandler _addingNew;
+ internal ListChangedEventHandler? _listChanged;
+ internal AddingNewEventHandler? _addingNew;
///
/// Occurs when the list changes or an item in the list changes.
@@ -77,12 +80,12 @@ public event AddingNewEventHandler AddingNew
}
#endif
#if HAVE_INOTIFY_COLLECTION_CHANGED
- internal NotifyCollectionChangedEventHandler _collectionChanged;
+ internal NotifyCollectionChangedEventHandler? _collectionChanged;
///
/// Occurs when the items list of the collection has changed, or the collection is reset.
///
- public event NotifyCollectionChangedEventHandler CollectionChanged
+ public event NotifyCollectionChangedEventHandler? CollectionChanged
{
add { _collectionChanged += value; }
remove { _collectionChanged -= value; }
@@ -95,7 +98,7 @@ public event NotifyCollectionChangedEventHandler CollectionChanged
/// The container's children tokens.
protected abstract IList ChildrenTokens { get; }
- private object _syncRoot;
+ private object? _syncRoot;
#if (HAVE_COMPONENT_MODEL || HAVE_INOTIFY_COLLECTION_CHANGED)
private bool _busy;
#endif
@@ -112,9 +115,11 @@ internal JContainer(JContainer other)
int i = 0;
foreach (JToken child in other)
{
- AddInternal(i, child, false);
+ TryAddInternal(i, child, false);
i++;
}
+
+ CopyAnnotations(this, other);
}
internal void CheckReentrancy()
@@ -148,7 +153,7 @@ protected virtual void OnAddingNew(AddingNewEventArgs e)
/// The instance containing the event data.
protected virtual void OnListChanged(ListChangedEventArgs e)
{
- ListChangedEventHandler handler = _listChanged;
+ ListChangedEventHandler? handler = _listChanged;
if (handler != null)
{
@@ -171,7 +176,7 @@ protected virtual void OnListChanged(ListChangedEventArgs e)
/// The instance containing the event data.
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
- NotifyCollectionChangedEventHandler handler = _collectionChanged;
+ NotifyCollectionChangedEventHandler? handler = _collectionChanged;
if (handler != null)
{
@@ -228,7 +233,7 @@ internal bool ContentsEqual(JContainer container)
///
/// A containing the first child token of the .
///
- public override JToken First
+ public override JToken? First
{
get
{
@@ -243,7 +248,7 @@ public override JToken First
///
/// A containing the last child token of the .
///
- public override JToken Last
+ public override JToken? Last
{
get
{
@@ -271,7 +276,7 @@ public override JEnumerable Children()
///
/// A containing the child values of this , in document order.
///
- public override IEnumerable Values()
+ public override IEnumerable Values() where T : default
{
return ChildrenTokens.Convert();
}
@@ -314,12 +319,12 @@ internal IEnumerable GetDescendants(bool self)
}
}
- internal bool IsMultiContent(object content)
+ internal bool IsMultiContent([NotNullWhen(true)]object? content)
{
return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[]));
}
- internal JToken EnsureParentToken(JToken item, bool skipParentCheck)
+ internal JToken EnsureParentToken(JToken? item, bool skipParentCheck)
{
if (item == null)
{
@@ -343,9 +348,9 @@ internal JToken EnsureParentToken(JToken item, bool skipParentCheck)
return item;
}
- internal abstract int IndexOfItem(JToken item);
+ internal abstract int IndexOfItem(JToken? item);
- internal virtual void InsertItem(int index, JToken item, bool skipParentCheck)
+ internal virtual bool InsertItem(int index, JToken? item, bool skipParentCheck)
{
IList children = ChildrenTokens;
@@ -358,9 +363,9 @@ internal virtual void InsertItem(int index, JToken item, bool skipParentCheck)
item = EnsureParentToken(item, skipParentCheck);
- JToken previous = (index == 0) ? null : children[index - 1];
+ JToken? previous = (index == 0) ? null : children[index - 1];
// haven't inserted new token yet so next token is still at the inserting index
- JToken next = (index == children.Count) ? null : children[index];
+ JToken? next = (index == children.Count) ? null : children[index];
ValidateToken(item, null);
@@ -392,6 +397,8 @@ internal virtual void InsertItem(int index, JToken item, bool skipParentCheck)
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
}
#endif
+
+ return true;
}
internal virtual void RemoveItemAt(int index)
@@ -410,8 +417,8 @@ internal virtual void RemoveItemAt(int index)
CheckReentrancy();
JToken item = children[index];
- JToken previous = (index == 0) ? null : children[index - 1];
- JToken next = (index == children.Count - 1) ? null : children[index + 1];
+ JToken? previous = (index == 0) ? null : children[index - 1];
+ JToken? next = (index == children.Count - 1) ? null : children[index + 1];
if (previous != null)
{
@@ -442,13 +449,16 @@ internal virtual void RemoveItemAt(int index)
#endif
}
- internal virtual bool RemoveItem(JToken item)
+ internal virtual bool RemoveItem(JToken? item)
{
- int index = IndexOfItem(item);
- if (index >= 0)
+ if (item != null)
{
- RemoveItemAt(index);
- return true;
+ int index = IndexOfItem(item);
+ if (index >= 0)
+ {
+ RemoveItemAt(index);
+ return true;
+ }
}
return false;
@@ -459,7 +469,7 @@ internal virtual JToken GetItem(int index)
return ChildrenTokens[index];
}
- internal virtual void SetItem(int index, JToken item)
+ internal virtual void SetItem(int index, JToken? item)
{
IList children = ChildrenTokens;
@@ -485,8 +495,8 @@ internal virtual void SetItem(int index, JToken item)
ValidateToken(item, existing);
- JToken previous = (index == 0) ? null : children[index - 1];
- JToken next = (index == children.Count - 1) ? null : children[index + 1];
+ JToken? previous = (index == 0) ? null : children[index - 1];
+ JToken? next = (index == children.Count - 1) ? null : children[index + 1];
item.Parent = this;
@@ -562,7 +572,7 @@ internal virtual void ReplaceItem(JToken existing, JToken replacement)
SetItem(index, replacement);
}
- internal virtual bool ContainsItem(JToken item)
+ internal virtual bool ContainsItem(JToken? item)
{
return (IndexOfItem(item) != -1);
}
@@ -594,14 +604,14 @@ internal virtual void CopyItemsTo(Array array, int arrayIndex)
}
}
- internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue)
+ internal static bool IsTokenUnchanged(JToken currentValue, JToken? newValue)
{
if (currentValue is JValue v1)
{
- // null will get turned into a JValue of type null
- if (v1.Type == JTokenType.Null && newValue == null)
+ if (newValue == null)
{
- return true;
+ // null will get turned into a JValue of type null
+ return v1.Type == JTokenType.Null;
}
return v1.Equals(newValue);
@@ -610,7 +620,7 @@ internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue)
return false;
}
- internal virtual void ValidateToken(JToken o, JToken existing)
+ internal virtual void ValidateToken(JToken o, JToken? existing)
{
ValidationUtils.ArgumentNotNull(o, nameof(o));
@@ -624,26 +634,31 @@ internal virtual void ValidateToken(JToken o, JToken existing)
/// Adds the specified content as children of this .
///
/// The content to be added.
- public virtual void Add(object content)
+ public virtual void Add(object? content)
+ {
+ TryAddInternal(ChildrenTokens.Count, content, false);
+ }
+
+ internal bool TryAdd(object? content)
{
- AddInternal(ChildrenTokens.Count, content, false);
+ return TryAddInternal(ChildrenTokens.Count, content, false);
}
internal void AddAndSkipParentCheck(JToken token)
{
- AddInternal(ChildrenTokens.Count, token, true);
+ TryAddInternal(ChildrenTokens.Count, token, true);
}
///
/// Adds the specified content as the first children of this .
///
/// The content to be added.
- public void AddFirst(object content)
+ public void AddFirst(object? content)
{
- AddInternal(0, content, false);
+ TryAddInternal(0, content, false);
}
- internal void AddInternal(int index, object content, bool skipParentCheck)
+ internal bool TryAddInternal(int index, object? content, bool skipParentCheck)
{
if (IsMultiContent(content))
{
@@ -652,19 +667,21 @@ internal void AddInternal(int index, object content, bool skipParentCheck)
int multiIndex = index;
foreach (object c in enumerable)
{
- AddInternal(multiIndex, c, skipParentCheck);
+ TryAddInternal(multiIndex, c, skipParentCheck);
multiIndex++;
}
+
+ return true;
}
else
{
JToken item = CreateFromContent(content);
- InsertItem(index, item, skipParentCheck);
+ return InsertItem(index, item, skipParentCheck);
}
}
- internal static JToken CreateFromContent(object content)
+ internal static JToken CreateFromContent(object? content)
{
if (content is JToken token)
{
@@ -701,15 +718,21 @@ public void RemoveAll()
ClearItems();
}
- internal abstract void MergeItem(object content, JsonMergeSettings settings);
+ internal abstract void MergeItem(object content, JsonMergeSettings? settings);
///
/// Merge the specified content into this .
///
/// The content to be merged.
- public void Merge(object content)
+ public void Merge(object? content)
{
- MergeItem(content, new JsonMergeSettings());
+ if (content == null)
+ {
+ return;
+ }
+
+ ValidateContent(content);
+ MergeItem(content, null);
}
///
@@ -717,12 +740,32 @@ public void Merge(object content)
///
/// The content to be merged.
/// The used to merge the content.
- public void Merge(object content, JsonMergeSettings settings)
+ public void Merge(object? content, JsonMergeSettings? settings)
{
+ if (content == null)
+ {
+ return;
+ }
+
+ ValidateContent(content);
MergeItem(content, settings);
}
- internal void ReadTokenFrom(JsonReader reader, JsonLoadSettings options)
+ private void ValidateContent(object content)
+ {
+ if (content.GetType().IsSubclassOf(typeof(JToken)))
+ {
+ return;
+ }
+ if (IsMultiContent(content))
+ {
+ return;
+ }
+
+ throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, content.GetType()), nameof(content));
+ }
+
+ internal void ReadTokenFrom(JsonReader reader, JsonLoadSettings? options)
{
int startDepth = reader.Depth;
@@ -741,12 +784,12 @@ internal void ReadTokenFrom(JsonReader reader, JsonLoadSettings options)
}
}
- internal void ReadContentFrom(JsonReader r, JsonLoadSettings settings)
+ internal void ReadContentFrom(JsonReader r, JsonLoadSettings? settings)
{
ValidationUtils.ArgumentNotNull(r, nameof(r));
- IJsonLineInfo lineInfo = r as IJsonLineInfo;
+ IJsonLineInfo? lineInfo = r as IJsonLineInfo;
- JContainer parent = this;
+ JContainer? parent = this;
do
{
@@ -760,6 +803,8 @@ internal void ReadContentFrom(JsonReader r, JsonLoadSettings settings)
parent = parent.Parent;
}
+ MiscellaneousUtils.Assert(parent != null);
+
switch (r.TokenType)
{
case JsonToken.None:
@@ -795,7 +840,7 @@ internal void ReadContentFrom(JsonReader r, JsonLoadSettings settings)
parent = parent.Parent;
break;
case JsonToken.StartConstructor:
- JConstructor constructor = new JConstructor(r.Value.ToString());
+ JConstructor constructor = new JConstructor(r.Value!.ToString()!);
constructor.SetLineInfo(lineInfo, settings);
parent.Add(constructor);
parent = constructor;
@@ -821,7 +866,7 @@ internal void ReadContentFrom(JsonReader r, JsonLoadSettings settings)
case JsonToken.Comment:
if (settings != null && settings.CommentHandling == CommentHandling.Load)
{
- v = JValue.CreateComment(r.Value.ToString());
+ v = JValue.CreateComment(r.Value!.ToString());
v.SetLineInfo(lineInfo, settings);
parent.Add(v);
}
@@ -837,21 +882,15 @@ internal void ReadContentFrom(JsonReader r, JsonLoadSettings settings)
parent.Add(v);
break;
case JsonToken.PropertyName:
- string propertyName = r.Value.ToString();
- JProperty property = new JProperty(propertyName);
- property.SetLineInfo(lineInfo, settings);
- JObject parentObject = (JObject)parent;
- // handle multiple properties with the same name in JSON
- JProperty existingPropertyWithName = parentObject.Property(propertyName);
- if (existingPropertyWithName == null)
+ JProperty? property = ReadProperty(r, settings, lineInfo, parent);
+ if (property != null)
{
- parent.Add(property);
+ parent = property;
}
else
{
- existingPropertyWithName.Replace(property);
+ r.Skip();
}
- parent = property;
break;
default:
throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, r.TokenType));
@@ -859,6 +898,40 @@ internal void ReadContentFrom(JsonReader r, JsonLoadSettings settings)
} while (r.Read());
}
+ private static JProperty? ReadProperty(JsonReader r, JsonLoadSettings? settings, IJsonLineInfo? lineInfo, JContainer parent)
+ {
+ DuplicatePropertyNameHandling duplicatePropertyNameHandling = settings?.DuplicatePropertyNameHandling ?? DuplicatePropertyNameHandling.Replace;
+
+ JObject parentObject = (JObject)parent;
+ string propertyName = r.Value!.ToString()!;
+ JProperty? existingPropertyWithName = parentObject.Property(propertyName, StringComparison.Ordinal);
+ if (existingPropertyWithName != null)
+ {
+ if (duplicatePropertyNameHandling == DuplicatePropertyNameHandling.Ignore)
+ {
+ return null;
+ }
+ else if (duplicatePropertyNameHandling == DuplicatePropertyNameHandling.Error)
+ {
+ throw JsonReaderException.Create(r, "Property with the name '{0}' already exists in the current JSON object.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+ }
+ }
+
+ JProperty property = new JProperty(propertyName);
+ property.SetLineInfo(lineInfo, settings);
+ // handle multiple properties with the same name in JSON
+ if (existingPropertyWithName == null)
+ {
+ parent.Add(property);
+ }
+ else
+ {
+ existingPropertyWithName.Replace(property);
+ }
+
+ return property;
+ }
+
internal int ContentsHashCode()
{
int hashCode = 0;
@@ -877,8 +950,9 @@ string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
{
- ICustomTypeDescriptor d = First as ICustomTypeDescriptor;
- return d?.GetProperties();
+ ICustomTypeDescriptor? d = First as ICustomTypeDescriptor;
+
+ return d?.GetProperties() ?? new PropertyDescriptorCollection(CollectionUtils.ArrayEmpty());
}
#endif
@@ -934,7 +1008,7 @@ bool ICollection.Remove(JToken item)
}
#endregion
- private JToken EnsureValue(object value)
+ private JToken? EnsureValue(object? value)
{
if (value == null)
{
@@ -950,7 +1024,7 @@ private JToken EnsureValue(object value)
}
#region IList Members
- int IList.Add(object value)
+ int IList.Add(object? value)
{
Add(EnsureValue(value));
return Count - 1;
@@ -961,17 +1035,17 @@ void IList.Clear()
ClearItems();
}
- bool IList.Contains(object value)
+ bool IList.Contains(object? value)
{
return ContainsItem(EnsureValue(value));
}
- int IList.IndexOf(object value)
+ int IList.IndexOf(object? value)
{
return IndexOfItem(EnsureValue(value));
}
- void IList.Insert(int index, object value)
+ void IList.Insert(int index, object? value)
{
InsertItem(index, EnsureValue(value), false);
}
@@ -980,7 +1054,7 @@ void IList.Insert(int index, object value)
bool IList.IsReadOnly => false;
- void IList.Remove(object value)
+ void IList.Remove(object? value)
{
RemoveItem(EnsureValue(value));
}
@@ -990,7 +1064,7 @@ void IList.RemoveAt(int index)
RemoveItemAt(index);
}
- object IList.this[int index]
+ object? IList.this[int index]
{
get => GetItem(index);
set => SetItem(index, EnsureValue(value));
@@ -1080,7 +1154,7 @@ void IBindingList.RemoveSort()
ListSortDirection IBindingList.SortDirection => ListSortDirection.Ascending;
- PropertyDescriptor IBindingList.SortProperty => null;
+ PropertyDescriptor? IBindingList.SortProperty => null;
bool IBindingList.SupportsChangeNotification => true;
@@ -1090,25 +1164,27 @@ void IBindingList.RemoveSort()
#endif
#endregion
- internal static void MergeEnumerableContent(JContainer target, IEnumerable content, JsonMergeSettings settings)
+ internal static void MergeEnumerableContent(JContainer target, IEnumerable content, JsonMergeSettings? settings)
{
- switch (settings.MergeArrayHandling)
+ switch (settings?.MergeArrayHandling ?? MergeArrayHandling.Concat)
{
case MergeArrayHandling.Concat:
- foreach (JToken item in content)
+ foreach (object item in content)
{
- target.Add(item);
+ target.Add(CreateFromContent(item));
}
break;
case MergeArrayHandling.Union:
#if HAVE_HASH_SET
HashSet items = new HashSet(target, EqualityComparer);
- foreach (JToken item in content)
+ foreach (object item in content)
{
- if (items.Add(item))
+ JToken contentItem = CreateFromContent(item);
+
+ if (items.Add(contentItem))
{
- target.Add(item);
+ target.Add(contentItem);
}
}
#else
@@ -1118,21 +1194,27 @@ internal static void MergeEnumerableContent(JContainer target, IEnumerable conte
items[t] = true;
}
- foreach (JToken item in content)
+ foreach (object item in content)
{
- if (!items.ContainsKey(item))
+ JToken contentItem = CreateFromContent(item);
+
+ if (!items.ContainsKey(contentItem))
{
- items[item] = true;
- target.Add(item);
+ items[contentItem] = true;
+ target.Add(contentItem);
}
}
#endif
break;
case MergeArrayHandling.Replace:
+ if (target == content)
+ {
+ break;
+ }
target.ClearItems();
- foreach (JToken item in content)
+ foreach (object item in content)
{
- target.Add(item);
+ target.Add(CreateFromContent(item));
}
break;
case MergeArrayHandling.Merge:
@@ -1141,7 +1223,7 @@ internal static void MergeEnumerableContent(JContainer target, IEnumerable conte
{
if (i < target.Count)
{
- JToken sourceItem = target[i];
+ JToken? sourceItem = target[i];
if (sourceItem is JContainer existingContainer)
{
@@ -1161,7 +1243,7 @@ internal static void MergeEnumerableContent(JContainer target, IEnumerable conte
}
else
{
- target.Add(targetItem);
+ target.Add(CreateFromContent(targetItem));
}
i++;
@@ -1172,4 +1254,5 @@ internal static void MergeEnumerableContent(JContainer target, IEnumerable conte
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JEnumerable.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JEnumerable.cs
index d21ccd3ba0..6e15a2e831 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JEnumerable.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JEnumerable.cs
@@ -35,6 +35,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a collection of objects.
///
@@ -88,7 +89,7 @@ public IJEnumerable this[object key]
return JEnumerable.Empty;
}
- return new JEnumerable(_enumerable.Values(key));
+ return new JEnumerable(_enumerable.Values(key)!);
}
}
@@ -111,7 +112,7 @@ public bool Equals(JEnumerable other)
///
/// true if the specified is equal to this instance; otherwise, false.
///
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (obj is JEnumerable enumerable)
{
@@ -125,7 +126,7 @@ public override bool Equals(object obj)
/// Returns a hash code for this instance.
///
///
- /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
+ /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
///
public override int GetHashCode()
{
@@ -137,4 +138,5 @@ public override int GetHashCode()
return _enumerable.GetHashCode();
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.Async.cs
index 7f92bb479b..b91d3e43b2 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.Async.cs
@@ -33,6 +33,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
internal partial class JObject
{
///
@@ -45,7 +46,7 @@ internal partial class JObject
public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
{
Task t = writer.WriteStartObjectAsync(cancellationToken);
- if (!t.IsCompletedSucessfully())
+ if (!t.IsCompletedSuccessfully())
{
return AwaitProperties(t, 0, writer, cancellationToken, converters);
}
@@ -53,7 +54,7 @@ public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellat
for (int i = 0; i < _properties.Count; i++)
{
t = _properties[i].WriteToAsync(writer, cancellationToken, converters);
- if (!t.IsCompletedSucessfully())
+ if (!t.IsCompletedSuccessfully())
{
return AwaitProperties(t, i + 1, writer, cancellationToken, converters);
}
@@ -97,7 +98,7 @@ async Task AwaitProperties(Task task, int i, JsonWriter Writer, CancellationToke
///
/// A that represents the asynchronous load. The
/// property returns a that contains the JSON that was read from the specified .
- public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default)
+ public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings? settings, CancellationToken cancellationToken = default)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
@@ -124,6 +125,7 @@ async Task AwaitProperties(Task task, int i, JsonWriter Writer, CancellationToke
return o;
}
}
+#nullable disable
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.cs
index 46da192e2f..2569dd3643 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JObject.cs
@@ -37,6 +37,8 @@
using System.IO;
using Microsoft.IdentityModel.Json.Utilities;
using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
@@ -45,13 +47,14 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a JSON object.
///
///
///
///
- internal partial class JObject : JContainer, IDictionary, INotifyPropertyChanged
+ internal partial class JObject : JContainer, IDictionary, INotifyPropertyChanged
#if HAVE_COMPONENT_MODEL
, ICustomTypeDescriptor
#endif
@@ -70,13 +73,13 @@ internal partial class JObject : JContainer, IDictionary, INotif
///
/// Occurs when a property value changes.
///
- public event PropertyChangedEventHandler PropertyChanged;
+ public event PropertyChangedEventHandler? PropertyChanged;
#if HAVE_INOTIFY_PROPERTY_CHANGING
///
/// Occurs when a property value is changing.
///
- public event PropertyChangingEventHandler PropertyChanging;
+ public event PropertyChangingEventHandler? PropertyChanging;
#endif
///
@@ -123,23 +126,28 @@ internal override bool DeepEquals(JToken node)
return _properties.Compare(t._properties);
}
- internal override int IndexOfItem(JToken item)
+ internal override int IndexOfItem(JToken? item)
{
+ if (item == null)
+ {
+ return -1;
+ }
+
return _properties.IndexOfReference(item);
}
- internal override void InsertItem(int index, JToken item, bool skipParentCheck)
+ internal override bool InsertItem(int index, JToken? item, bool skipParentCheck)
{
// don't add comments to JObject, no name to reference comment by
if (item != null && item.Type == JTokenType.Comment)
{
- return;
+ return false;
}
- base.InsertItem(index, item, skipParentCheck);
+ return base.InsertItem(index, item, skipParentCheck);
}
- internal override void ValidateToken(JToken o, JToken existing)
+ internal override void ValidateToken(JToken o, JToken? existing)
{
ValidationUtils.ArgumentNotNull(o, nameof(o));
@@ -166,16 +174,16 @@ internal override void ValidateToken(JToken o, JToken existing)
}
}
- internal override void MergeItem(object content, JsonMergeSettings settings)
+ internal override void MergeItem(object content, JsonMergeSettings? settings)
{
if (!(content is JObject o))
{
return;
}
- foreach (KeyValuePair contentItem in o)
+ foreach (KeyValuePair contentItem in o)
{
- JProperty existingProperty = Property(contentItem.Key, settings?.PropertyNameComparison ?? StringComparison.Ordinal);
+ JProperty? existingProperty = Property(contentItem.Key, settings?.PropertyNameComparison ?? StringComparison.Ordinal);
if (existingProperty == null)
{
@@ -262,7 +270,7 @@ public IEnumerable Properties()
///
/// The property name.
/// A with the specified name or null.
- public JProperty Property(string name)
+ public JProperty? Property(string name)
{
return Property(name, StringComparison.Ordinal);
}
@@ -275,14 +283,14 @@ public JProperty Property(string name)
/// The property name.
/// One of the enumeration values that specifies how the strings will be compared.
/// A matched with the specified name or null.
- public JProperty Property(string name, StringComparison comparison)
+ public JProperty? Property(string name, StringComparison comparison)
{
if (name == null)
{
return null;
}
- if (_properties.TryGetValue(name, out JToken property))
+ if (_properties.TryGetValue(name, out JToken? property))
{
return (JProperty)property;
}
@@ -316,7 +324,7 @@ public JEnumerable PropertyValues()
/// Gets the with the specified key.
///
/// The with the specified key.
- public override JToken this[object key]
+ public override JToken? this[object key]
{
get
{
@@ -346,29 +354,29 @@ public override JToken this[object key]
/// Gets or sets the with the specified property name.
///
///
- public JToken this[string propertyName]
+ public JToken? this[string propertyName]
{
get
{
ValidationUtils.ArgumentNotNull(propertyName, nameof(propertyName));
- JProperty property = Property(propertyName);
+ JProperty? property = Property(propertyName, StringComparison.Ordinal);
return property?.Value;
}
set
{
- JProperty property = Property(propertyName);
+ JProperty? property = Property(propertyName, StringComparison.Ordinal);
if (property != null)
{
- property.Value = value;
+ property.Value = value!;
}
else
{
#if HAVE_INOTIFY_PROPERTY_CHANGING
OnPropertyChanging(propertyName);
#endif
- Add(new JProperty(propertyName, value));
+ Add(propertyName, value);
OnPropertyChanged(propertyName);
}
}
@@ -397,7 +405,7 @@ public JToken this[string propertyName]
///
/// is not valid JSON.
///
- public new static JObject Load(JsonReader reader, JsonLoadSettings settings)
+ public new static JObject Load(JsonReader reader, JsonLoadSettings? settings)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
@@ -453,7 +461,7 @@ public JToken this[string propertyName]
///
///
///
- public new static JObject Parse(string json, JsonLoadSettings settings)
+ public new static JObject Parse(string json, JsonLoadSettings? settings)
{
using (JsonReader reader = new JsonTextReader(new StringReader(json)))
{
@@ -488,7 +496,7 @@ public JToken this[string propertyName]
{
JToken token = FromObjectInternal(o, jsonSerializer);
- if (token != null && token.Type != JTokenType.Object)
+ if (token.Type != JTokenType.Object)
{
throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type));
}
@@ -518,7 +526,7 @@ public override void WriteTo(JsonWriter writer, params JsonConverter[] converter
///
/// Name of the property.
/// The with the specified property name.
- public JToken GetValue(string propertyName)
+ public JToken? GetValue(string? propertyName)
{
return GetValue(propertyName, StringComparison.Ordinal);
}
@@ -531,7 +539,7 @@ public JToken GetValue(string propertyName)
/// Name of the property.
/// One of the enumeration values that specifies how the strings will be compared.
/// The with the specified property name.
- public JToken GetValue(string propertyName, StringComparison comparison)
+ public JToken? GetValue(string? propertyName, StringComparison comparison)
{
if (propertyName == null)
{
@@ -553,7 +561,7 @@ public JToken GetValue(string propertyName, StringComparison comparison)
/// The value.
/// One of the enumeration values that specifies how the strings will be compared.
/// true if a value was successfully retrieved; otherwise, false.
- public bool TryGetValue(string propertyName, StringComparison comparison, out JToken value)
+ public bool TryGetValue(string propertyName, StringComparison comparison, [NotNullWhen(true)]out JToken? value)
{
value = GetValue(propertyName, comparison);
return (value != null);
@@ -565,7 +573,7 @@ public bool TryGetValue(string propertyName, StringComparison comparison, out JT
///
/// Name of the property.
/// The value.
- public void Add(string propertyName, JToken value)
+ public void Add(string propertyName, JToken? value)
{
Add(new JProperty(propertyName, value));
}
@@ -582,7 +590,7 @@ public bool ContainsKey(string propertyName)
return _properties.Contains(propertyName);
}
- ICollection IDictionary.Keys => _properties.Keys;
+ ICollection IDictionary.Keys => _properties.Keys;
///
/// Removes the property with the specified name.
@@ -591,7 +599,7 @@ public bool ContainsKey(string propertyName)
/// true if item was successfully removed; otherwise, false.
public bool Remove(string propertyName)
{
- JProperty property = Property(propertyName);
+ JProperty? property = Property(propertyName, StringComparison.Ordinal);
if (property == null)
{
return false;
@@ -607,9 +615,9 @@ public bool Remove(string propertyName)
/// Name of the property.
/// The value.
/// true if a value was successfully retrieved; otherwise, false.
- public bool TryGetValue(string propertyName, out JToken value)
+ public bool TryGetValue(string propertyName, [NotNullWhen(true)]out JToken? value)
{
- JProperty property = Property(propertyName);
+ JProperty? property = Property(propertyName, StringComparison.Ordinal);
if (property == null)
{
value = null;
@@ -620,24 +628,24 @@ public bool TryGetValue(string propertyName, out JToken value)
return true;
}
- ICollection IDictionary.Values => throw new NotImplementedException();
+ ICollection IDictionary.Values => throw new NotImplementedException();
#endregion
#region ICollection> Members
- void ICollection>.Add(KeyValuePair item)
+ void ICollection>.Add(KeyValuePair item)
{
Add(new JProperty(item.Key, item.Value));
}
- void ICollection>.Clear()
+ void ICollection>.Clear()
{
RemoveAll();
}
- bool ICollection>.Contains(KeyValuePair item)
+ bool ICollection>.Contains(KeyValuePair item)
{
- JProperty property = Property(item.Key);
+ JProperty? property = Property(item.Key, StringComparison.Ordinal);
if (property == null)
{
return false;
@@ -646,7 +654,7 @@ bool ICollection>.Contains(KeyValuePair>.CopyTo(KeyValuePair[] array, int arrayIndex)
+ void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex)
{
if (array == null)
{
@@ -668,16 +676,16 @@ void ICollection>.CopyTo(KeyValuePair(property.Name, property.Value);
+ array[arrayIndex + index] = new KeyValuePair(property.Name, property.Value);
index++;
}
}
- bool ICollection>.IsReadOnly => false;
+ bool ICollection>.IsReadOnly => false;
- bool ICollection>.Remove(KeyValuePair item)
+ bool ICollection>.Remove(KeyValuePair item)
{
- if (!((ICollection>)this).Contains(item))
+ if (!((ICollection>)this).Contains(item))
{
return false;
}
@@ -698,11 +706,11 @@ internal override int GetDeepHashCode()
///
/// A that can be used to iterate through the collection.
///
- public IEnumerator> GetEnumerator()
+ public IEnumerator> GetEnumerator()
{
foreach (JProperty property in _properties)
{
- yield return new KeyValuePair(property.Name, property.Value);
+ yield return new KeyValuePair(property.Name, property.Value);
}
}
@@ -735,16 +743,17 @@ PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
return ((ICustomTypeDescriptor)this).GetProperties(null);
}
- PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
+ PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[]? attributes)
{
- PropertyDescriptorCollection descriptors = new PropertyDescriptorCollection(null);
-
- foreach (KeyValuePair propertyValue in this)
+ PropertyDescriptor[] propertiesArray = new PropertyDescriptor[Count];
+ int i = 0;
+ foreach (KeyValuePair propertyValue in this)
{
- descriptors.Add(new JPropertyDescriptor(propertyValue.Key));
+ propertiesArray[i] = new JPropertyDescriptor(propertyValue.Key);
+ i++;
}
- return descriptors;
+ return new PropertyDescriptorCollection(propertiesArray);
}
AttributeCollection ICustomTypeDescriptor.GetAttributes()
@@ -752,12 +761,12 @@ AttributeCollection ICustomTypeDescriptor.GetAttributes()
return AttributeCollection.Empty;
}
- string ICustomTypeDescriptor.GetClassName()
+ string? ICustomTypeDescriptor.GetClassName()
{
return null;
}
- string ICustomTypeDescriptor.GetComponentName()
+ string? ICustomTypeDescriptor.GetComponentName()
{
return null;
}
@@ -767,22 +776,22 @@ TypeConverter ICustomTypeDescriptor.GetConverter()
return new TypeConverter();
}
- EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
+ EventDescriptor? ICustomTypeDescriptor.GetDefaultEvent()
{
return null;
}
- PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
+ PropertyDescriptor? ICustomTypeDescriptor.GetDefaultProperty()
{
return null;
}
- object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
+ object? ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{
return null;
}
- EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
+ EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[]? attributes)
{
return EventDescriptorCollection.Empty;
}
@@ -792,7 +801,7 @@ EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
return EventDescriptorCollection.Empty;
}
- object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
+ object? ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor? pd)
{
if (pd is JPropertyDescriptor)
{
@@ -805,7 +814,7 @@ object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
#endif
-#if HAVE_DYNAMIC
+#if HAVE_DYNAMIC
///
/// Returns the responsible for binding operations performed on this object.
///
@@ -820,7 +829,7 @@ protected override DynamicMetaObject GetMetaObject(Expression parameter)
private class JObjectDynamicProxy : DynamicProxy
{
- public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object result)
+ public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object? result)
{
// result can be null
result = instance[binder.Name];
@@ -846,4 +855,5 @@ public override IEnumerable GetDynamicMemberNames(JObject instance)
}
#endif
}
+#nullable disable
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.Async.cs
index 4cd487672b..74043335d2 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.Async.cs
@@ -32,6 +32,8 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
+#pragma warning disable CA1068 // CancellationToken parameters must come last
internal partial class JProperty
{
///
@@ -44,7 +46,7 @@ internal partial class JProperty
public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellationToken, params JsonConverter[] converters)
{
Task task = writer.WritePropertyNameAsync(_name, cancellationToken);
- if (task.IsCompletedSucessfully())
+ if (task.IsCompletedSuccessfully())
{
return WriteValueAsync(writer, cancellationToken, converters);
}
@@ -59,9 +61,7 @@ private async Task WriteToAsync(Task task, JsonWriter writer, CancellationToken
await WriteValueAsync(writer, cancellationToken, converters).ConfigureAwait(false);
}
-#pragma warning disable CA1068 // CancellationToken parameters must come last
private Task WriteValueAsync(JsonWriter writer, CancellationToken cancellationToken, JsonConverter[] converters)
-#pragma warning restore CA1068 // CancellationToken parameters must come last
{
JToken value = Value;
return value != null
@@ -90,7 +90,7 @@ private Task WriteValueAsync(JsonWriter writer, CancellationToken cancellationTo
/// The token to monitor for cancellation requests. The default value is .
/// A representing the asynchronous creation. The
/// property returns a that contains the JSON that was read from the specified .
- public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default)
+ public new static async Task LoadAsync(JsonReader reader, JsonLoadSettings? settings, CancellationToken cancellationToken = default)
{
if (reader.TokenType == JsonToken.None)
{
@@ -107,7 +107,7 @@ private Task WriteValueAsync(JsonWriter writer, CancellationToken cancellationTo
throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
- JProperty p = new JProperty((string)reader.Value);
+ JProperty p = new JProperty((string)reader.Value!);
p.SetLineInfo(reader as IJsonLineInfo, settings);
await p.ReadTokenFromAsync(reader, settings, cancellationToken).ConfigureAwait(false);
@@ -115,6 +115,8 @@ private Task WriteValueAsync(JsonWriter writer, CancellationToken cancellationTo
return p;
}
}
+#nullable disable
+#pragma warning restore CA1068 // CancellationToken parameters must come last
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.cs
index e212526bc2..e769632d85 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JProperty.cs
@@ -35,12 +35,13 @@ namespace Microsoft.IdentityModel.Json.Linq
///
/// Represents a JSON property.
///
+#nullable enable
internal partial class JProperty : JContainer
{
#region JPropertyList
private class JPropertyList : IList
{
- internal JToken _token;
+ internal JToken? _token;
public IEnumerator GetEnumerator()
{
@@ -115,13 +116,24 @@ public void RemoveAt(int index)
public JToken this[int index]
{
- get => (index == 0) ? _token : null;
+ get
+ {
+ if (index != 0)
+ {
+ throw new IndexOutOfRangeException();
+ }
+
+ MiscellaneousUtils.Assert(_token != null);
+ return _token;
+ }
set
{
- if (index == 0)
+ if (index != 0)
{
- _token = value;
+ throw new IndexOutOfRangeException();
}
+
+ _token = value;
}
}
}
@@ -153,7 +165,7 @@ public string Name
public JToken Value
{
[DebuggerStepThrough]
- get { return _content._token; }
+ get { return _content._token!; }
set
{
CheckReentrancy();
@@ -191,7 +203,7 @@ internal override JToken GetItem(int index)
return Value;
}
- internal override void SetItem(int index, JToken item)
+ internal override void SetItem(int index, JToken? item)
{
if (index != 0)
{
@@ -203,14 +215,14 @@ internal override void SetItem(int index, JToken item)
return;
}
- ((JObject)Parent)?.InternalPropertyChanging(this);
+ ((JObject?)Parent)?.InternalPropertyChanging(this);
base.SetItem(0, item);
- ((JObject)Parent)?.InternalPropertyChanged(this);
+ ((JObject?)Parent)?.InternalPropertyChanged(this);
}
- internal override bool RemoveItem(JToken item)
+ internal override bool RemoveItem(JToken? item)
{
throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
}
@@ -220,17 +232,22 @@ internal override void RemoveItemAt(int index)
throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
}
- internal override int IndexOfItem(JToken item)
+ internal override int IndexOfItem(JToken? item)
{
+ if (item == null)
+ {
+ return -1;
+ }
+
return _content.IndexOf(item);
}
- internal override void InsertItem(int index, JToken item, bool skipParentCheck)
+ internal override bool InsertItem(int index, JToken? item, bool skipParentCheck)
{
// don't add comments to JProperty
if (item != null && item.Type == JTokenType.Comment)
{
- return;
+ return false;
}
if (Value != null)
@@ -238,17 +255,17 @@ internal override void InsertItem(int index, JToken item, bool skipParentCheck)
throw new JsonException("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
}
- base.InsertItem(0, item, false);
+ return base.InsertItem(0, item, false);
}
- internal override bool ContainsItem(JToken item)
+ internal override bool ContainsItem(JToken? item)
{
return (Value == item);
}
- internal override void MergeItem(object content, JsonMergeSettings settings)
+ internal override void MergeItem(object content, JsonMergeSettings? settings)
{
- JToken value = (content as JProperty)?.Value;
+ JToken? value = (content as JProperty)?.Value;
if (value != null && value.Type != JTokenType.Null)
{
@@ -304,7 +321,7 @@ public JProperty(string name, params object[] content)
///
/// The property name.
/// The property content.
- public JProperty(string name, object content)
+ public JProperty(string name, object? content)
{
ValidationUtils.ArgumentNotNull(name, nameof(name));
@@ -337,7 +354,13 @@ public override void WriteTo(JsonWriter writer, params JsonConverter[] converter
internal override int GetDeepHashCode()
{
- return _name.GetHashCode() ^ (Value?.GetDeepHashCode() ?? 0);
+ int hash;
+#if HAVE_GETHASHCODE_STRING_COMPARISON
+ hash = _name.GetHashCode(StringComparison.Ordinal);
+#else
+ hash = _name.GetHashCode();
+#endif
+ return hash ^ (Value?.GetDeepHashCode() ?? 0);
}
///
@@ -357,7 +380,7 @@ internal override int GetDeepHashCode()
/// The used to load the JSON.
/// If this is null, default load settings will be used.
/// A that contains the JSON that was read from the specified .
- public new static JProperty Load(JsonReader reader, JsonLoadSettings settings)
+ public new static JProperty Load(JsonReader reader, JsonLoadSettings? settings)
{
if (reader.TokenType == JsonToken.None)
{
@@ -374,7 +397,7 @@ internal override int GetDeepHashCode()
throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
- JProperty p = new JProperty((string)reader.Value);
+ JProperty p = new JProperty((string)reader.Value!);
p.SetLineInfo(reader as IJsonLineInfo, settings);
p.ReadTokenFrom(reader, settings);
@@ -382,4 +405,5 @@ internal override int GetDeepHashCode()
return p;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyDescriptor.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyDescriptor.cs
index 703dacc26b..ee3e9943e2 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyDescriptor.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyDescriptor.cs
@@ -29,6 +29,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a view of a .
///
@@ -67,7 +68,7 @@ public override bool CanResetValue(object component)
/// The value of a property for a given component.
///
/// The component with the property for which to retrieve the value.
- public override object GetValue(object component)
+ public override object? GetValue(object? component)
{
return (component as JObject)?[Name];
}
@@ -85,7 +86,7 @@ public override void ResetValue(object component)
///
/// The component with the property value that is to be set.
/// The new value.
- public override void SetValue(object component, object value)
+ public override void SetValue(object? component, object? value)
{
if (component is JObject o)
{
@@ -151,6 +152,7 @@ protected override int NameHashCode
}
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyKeyedCollection.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyKeyedCollection.cs
index dd43d1d6d7..5cdb287297 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyKeyedCollection.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JPropertyKeyedCollection.cs
@@ -26,15 +26,18 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
using Microsoft.IdentityModel.Json.Utilities;
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
internal class JPropertyKeyedCollection : Collection
{
private static readonly IEqualityComparer Comparer = StringComparer.Ordinal;
- private Dictionary _dictionary;
+ private Dictionary? _dictionary;
public JPropertyKeyedCollection() : base(new List())
{
@@ -43,7 +46,7 @@ public JPropertyKeyedCollection() : base(new List())
private void AddKey(string key, JToken item)
{
EnsureDictionary();
- _dictionary[key] = item;
+ _dictionary![key] = item;
}
protected void ChangeItemKey(JToken item, string newKey)
@@ -129,7 +132,7 @@ public bool Remove(string key)
if (_dictionary != null)
{
- return _dictionary.ContainsKey(key) && Remove(_dictionary[key]);
+ return _dictionary.TryGetValue(key, out JToken? value) && Remove(value);
}
return false;
@@ -189,7 +192,7 @@ public JToken this[string key]
}
}
- public bool TryGetValue(string key, out JToken value)
+ public bool TryGetValue(string key, [NotNullWhen(true)]out JToken? value)
{
if (_dictionary == null)
{
@@ -205,7 +208,7 @@ public ICollection Keys
get
{
EnsureDictionary();
- return _dictionary.Keys;
+ return _dictionary!.Keys;
}
}
@@ -214,7 +217,7 @@ public ICollection Values
get
{
EnsureDictionary();
- return _dictionary.Values;
+ return _dictionary!.Values;
}
}
@@ -232,8 +235,8 @@ public bool Compare(JPropertyKeyedCollection other)
// dictionaries in JavaScript aren't ordered
// ignore order when comparing properties
- Dictionary d1 = _dictionary;
- Dictionary d2 = other._dictionary;
+ Dictionary? d1 = _dictionary;
+ Dictionary? d2 = other._dictionary;
if (d1 == null && d2 == null)
{
@@ -242,7 +245,7 @@ public bool Compare(JPropertyKeyedCollection other)
if (d1 == null)
{
- return (d2.Count == 0);
+ return (d2!.Count == 0);
}
if (d2 == null)
@@ -257,7 +260,7 @@ public bool Compare(JPropertyKeyedCollection other)
foreach (KeyValuePair keyAndProperty in d1)
{
- if (!d2.TryGetValue(keyAndProperty.Key, out JToken secondValue))
+ if (!d2.TryGetValue(keyAndProperty.Key, out JToken? secondValue))
{
return false;
}
@@ -279,4 +282,5 @@ public bool Compare(JPropertyKeyedCollection other)
return true;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JRaw.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JRaw.cs
index 34168e365f..ba599276de 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JRaw.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JRaw.cs
@@ -28,6 +28,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a raw JSON string.
///
@@ -46,7 +47,7 @@ public JRaw(JRaw other)
/// Initializes a new instance of the class.
///
/// The raw json.
- public JRaw(object rawJson)
+ public JRaw(object? rawJson)
: base(rawJson, JTokenType.Raw)
{
}
@@ -72,4 +73,5 @@ internal override JToken CloneToken()
return new JRaw(this);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.Async.cs
index 9c9568cb7b..12b6e948a8 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.Async.cs
@@ -33,6 +33,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
internal abstract partial class JToken
{
///
@@ -65,7 +66,7 @@ public Task WriteToAsync(JsonWriter writer, params JsonConverter[] converters)
/// The token to monitor for cancellation requests. The default value is .
///
/// A that represents the asynchronous creation. The
- /// property returns a that contains
+ /// property returns a that contains
/// the token and its descendant tokens
/// that were read from the reader. The runtime type of the token is determined
/// by the token type of the first token encountered in the reader.
@@ -84,12 +85,12 @@ public static Task ReadFromAsync(JsonReader reader, CancellationToken ca
/// The token to monitor for cancellation requests. The default value is .
///
/// A that represents the asynchronous creation. The
- /// property returns a that contains
+ /// property returns a that contains
/// the token and its descendant tokens
/// that were read from the reader. The runtime type of the token is determined
/// by the token type of the first token encountered in the reader.
///
- public static async Task ReadFromAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default)
+ public static async Task ReadFromAsync(JsonReader reader, JsonLoadSettings? settings, CancellationToken cancellationToken = default)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
@@ -101,7 +102,7 @@ public static async Task ReadFromAsync(JsonReader reader, JsonLoadSettin
}
}
- IJsonLineInfo lineInfo = reader as IJsonLineInfo;
+ IJsonLineInfo? lineInfo = reader as IJsonLineInfo;
switch (reader.TokenType)
{
@@ -123,7 +124,7 @@ public static async Task ReadFromAsync(JsonReader reader, JsonLoadSettin
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Comment:
- v = JValue.CreateComment(reader.Value.ToString());
+ v = JValue.CreateComment(reader.Value?.ToString());
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Null:
@@ -168,11 +169,12 @@ public static Task LoadAsync(JsonReader reader, CancellationToken cancel
/// that were read from the reader. The runtime type of the token is determined
/// by the token type of the first token encountered in the reader.
///
- public static Task LoadAsync(JsonReader reader, JsonLoadSettings settings, CancellationToken cancellationToken = default)
+ public static Task LoadAsync(JsonReader reader, JsonLoadSettings? settings, CancellationToken cancellationToken = default)
{
return ReadFromAsync(reader, settings, cancellationToken);
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.cs
index c5e2596139..1dc42cb130 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JToken.cs
@@ -38,15 +38,19 @@
using System.Diagnostics;
using System.Globalization;
using System.Collections;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
using System.Linq;
-
#endif
+using Microsoft.IdentityModel.Json.Serialization;
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
///
/// Represents an abstract JSON token.
///
@@ -58,12 +62,12 @@ internal abstract partial class JToken : IJEnumerable, IJsonLineInfo
, IDynamicMetaObjectProvider
#endif
{
- private static JTokenEqualityComparer _equalityComparer;
+ private static JTokenEqualityComparer? _equalityComparer;
- private JContainer _parent;
- private JToken _previous;
- private JToken _next;
- private object _annotations;
+ private JContainer? _parent;
+ private JToken? _previous;
+ private JToken? _next;
+ private object? _annotations;
private static readonly JTokenType[] BooleanTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
private static readonly JTokenType[] NumberTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
@@ -99,7 +103,7 @@ public static JTokenEqualityComparer EqualityComparer
/// Gets or sets the parent.
///
/// The parent.
- public JContainer Parent
+ public JContainer? Parent
{
[DebuggerStepThrough]
get { return _parent; }
@@ -114,7 +118,7 @@ public JToken Root
{
get
{
- JContainer parent = Parent;
+ JContainer? parent = Parent;
if (parent == null)
{
return this;
@@ -152,7 +156,7 @@ public JToken Root
/// The first to compare.
/// The second to compare.
/// true if the tokens are equal; otherwise false.
- public static bool DeepEquals(JToken t1, JToken t2)
+ public static bool DeepEquals(JToken? t1, JToken? t2)
{
return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
}
@@ -161,7 +165,7 @@ public static bool DeepEquals(JToken t1, JToken t2)
/// Gets the next sibling token of this node.
///
/// The that contains the next sibling token.
- public JToken Next
+ public JToken? Next
{
get => _next;
internal set => _next = value;
@@ -171,14 +175,14 @@ public JToken Next
/// Gets the previous sibling token of this node.
///
/// The that contains the previous sibling token.
- public JToken Previous
+ public JToken? Previous
{
get => _previous;
internal set => _previous = value;
}
///
- /// Gets the path of the JSON token.
+ /// Gets the path of the JSON token.
///
public string Path
{
@@ -190,8 +194,8 @@ public string Path
}
List positions = new List();
- JToken previous = null;
- for (JToken current = this; current != null; current = current.Parent)
+ JToken? previous = null;
+ for (JToken? current = this; current != null; current = current.Parent)
{
switch (current.Type)
{
@@ -231,7 +235,7 @@ internal JToken()
/// Adds the specified content immediately after this token.
///
/// A content object that contains simple content or a collection of content objects to be added after this token.
- public void AddAfterSelf(object content)
+ public void AddAfterSelf(object? content)
{
if (_parent == null)
{
@@ -239,14 +243,14 @@ public void AddAfterSelf(object content)
}
int index = _parent.IndexOfItem(this);
- _parent.AddInternal(index + 1, content, false);
+ _parent.TryAddInternal(index + 1, content, false);
}
///
/// Adds the specified content immediately before this token.
///
/// A content object that contains simple content or a collection of content objects to be added before this token.
- public void AddBeforeSelf(object content)
+ public void AddBeforeSelf(object? content)
{
if (_parent == null)
{
@@ -254,7 +258,7 @@ public void AddBeforeSelf(object content)
}
int index = _parent.IndexOfItem(this);
- _parent.AddInternal(index, content, false);
+ _parent.TryAddInternal(index, content, false);
}
///
@@ -277,7 +281,7 @@ public IEnumerable AncestorsAndSelf()
internal IEnumerable GetAncestors(bool self)
{
- for (JToken current = self ? this : Parent; current != null; current = current.Parent)
+ for (JToken? current = self ? this : Parent; current != null; current = current.Parent)
{
yield return current;
}
@@ -294,7 +298,7 @@ public IEnumerable AfterSelf()
yield break;
}
- for (JToken o = Next; o != null; o = o.Next)
+ for (JToken? o = Next; o != null; o = o.Next)
{
yield return o;
}
@@ -306,7 +310,12 @@ public IEnumerable AfterSelf()
/// A collection of the sibling tokens before this token, in document order.
public IEnumerable BeforeSelf()
{
- for (JToken o = Parent.First; o != this; o = o.Next)
+ if (Parent == null)
+ {
+ yield break;
+ }
+
+ for (JToken? o = Parent.First; o != this && o != null; o = o.Next)
{
yield return o;
}
@@ -316,7 +325,7 @@ public IEnumerable BeforeSelf()
/// Gets the with the specified key.
///
/// The with the specified key.
- public virtual JToken this[object key]
+ public virtual JToken? this[object key]
{
get => throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
set => throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
@@ -328,11 +337,11 @@ public virtual JToken this[object key]
/// The type to convert the token to.
/// The token key.
/// The converted token value.
- public virtual T Value(object key)
+ public virtual T? Value(object key)
{
- JToken token = this[key];
+ JToken? token = this[key];
- // null check to fix MonoTouch issue - https://github.com/dolbz/Microsoft.IdentityModel.Json/commit/a24e3062846b30ee505f3271ac08862bb471b822
+ // null check to fix MonoTouch issue - https://github.com/dolbz/Newtonsoft.Json/commit/a24e3062846b30ee505f3271ac08862bb471b822
return token == null ? default : Extensions.Convert(token);
}
@@ -340,13 +349,13 @@ public virtual T Value(object key)
/// Get the first child token of this token.
///
/// A containing the first child token of the .
- public virtual JToken First => throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+ public virtual JToken? First => throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
///
/// Get the last child token of this token.
///
/// A containing the last child token of the .
- public virtual JToken Last => throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+ public virtual JToken? Last => throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
///
/// Returns a collection of the child tokens of this token, in document order.
@@ -372,7 +381,7 @@ public JEnumerable Children() where T : JToken
///
/// The type to convert the values to.
/// A containing the child values of this , in document order.
- public virtual IEnumerable Values()
+ public virtual IEnumerable Values()
{
throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
}
@@ -414,6 +423,10 @@ public void Replace(JToken value)
///
/// Returns the indented JSON for this token.
///
+ ///
+ /// ToString() returns a non-JSON string value for tokens with a type of .
+ /// If you want the JSON for all token types then you should use .
+ ///
///
/// The indented JSON for this token.
///
@@ -441,7 +454,7 @@ public string ToString(Formatting formatting, params JsonConverter[] converters)
}
}
- private static JValue EnsureValue(JToken value)
+ private static JValue? EnsureValue(JToken value)
{
if (value == null)
{
@@ -453,7 +466,7 @@ private static JValue EnsureValue(JToken value)
value = property.Value;
}
- JValue v = value as JValue;
+ JValue? v = value as JValue;
return v;
}
@@ -475,7 +488,7 @@ private static bool ValidateToken(JToken o, JTokenType[] validTypes, bool nullab
return (Array.IndexOf(validTypes, o.Type) != -1) || (nullable && (o.Type == JTokenType.Null || o.Type == JTokenType.Undefined));
}
-#region Cast from operators
+ #region Cast from operators
///
/// Performs an explicit conversion from to .
///
@@ -483,7 +496,7 @@ private static bool ValidateToken(JToken o, JTokenType[] validTypes, bool nullab
/// The result of the conversion.
public static explicit operator bool(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, BooleanTypes, false))
{
throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -507,7 +520,7 @@ public static explicit operator bool(JToken value)
/// The result of the conversion.
public static explicit operator DateTimeOffset(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, DateTimeTypes, false))
{
throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -532,14 +545,14 @@ public static explicit operator DateTimeOffset(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator bool?(JToken value)
+ public static explicit operator bool?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, BooleanTypes, true))
{
throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -562,7 +575,7 @@ public static explicit operator DateTimeOffset(JToken value)
/// The result of the conversion.
public static explicit operator long(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -583,14 +596,14 @@ public static explicit operator long(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator DateTime?(JToken value)
+ public static explicit operator DateTime?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, DateTimeTypes, true))
{
throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -612,14 +625,14 @@ public static explicit operator long(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator DateTimeOffset?(JToken value)
+ public static explicit operator DateTimeOffset?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, DateTimeTypes, true))
{
throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -648,14 +661,14 @@ public static explicit operator long(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator decimal?(JToken value)
+ public static explicit operator decimal?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -676,14 +689,14 @@ public static explicit operator long(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator double?(JToken value)
+ public static explicit operator double?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -704,14 +717,14 @@ public static explicit operator long(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator char?(JToken value)
+ public static explicit operator char?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, CharTypes, true))
{
throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -734,7 +747,7 @@ public static explicit operator long(JToken value)
/// The result of the conversion.
public static explicit operator int(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -757,7 +770,7 @@ public static explicit operator int(JToken value)
/// The result of the conversion.
public static explicit operator short(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -778,10 +791,10 @@ public static explicit operator short(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static explicit operator ushort(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -802,10 +815,10 @@ public static explicit operator ushort(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static explicit operator char(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, CharTypes, false))
{
throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -828,7 +841,7 @@ public static explicit operator char(JToken value)
/// The result of the conversion.
public static explicit operator byte(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -849,10 +862,10 @@ public static explicit operator byte(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static explicit operator sbyte(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to SByte.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -873,14 +886,14 @@ public static explicit operator sbyte(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator int?(JToken value)
+ public static explicit operator int?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -901,14 +914,14 @@ public static explicit operator sbyte(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator short?(JToken value)
+ public static explicit operator short?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -929,15 +942,15 @@ public static explicit operator sbyte(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
- public static explicit operator ushort?(JToken value)
+ [CLSCompliant(false)]
+ public static explicit operator ushort?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -958,14 +971,14 @@ public static explicit operator sbyte(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator byte?(JToken value)
+ public static explicit operator byte?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -986,15 +999,15 @@ public static explicit operator sbyte(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
- public static explicit operator sbyte?(JToken value)
+ [CLSCompliant(false)]
+ public static explicit operator sbyte?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to SByte.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1017,7 +1030,7 @@ public static explicit operator sbyte(JToken value)
/// The result of the conversion.
public static explicit operator DateTime(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, DateTimeTypes, false))
{
throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1038,14 +1051,14 @@ public static explicit operator DateTime(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator long?(JToken value)
+ public static explicit operator long?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1066,14 +1079,14 @@ public static explicit operator DateTime(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator float?(JToken value)
+ public static explicit operator float?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1096,7 +1109,7 @@ public static explicit operator DateTime(JToken value)
/// The result of the conversion.
public static explicit operator decimal(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1117,15 +1130,15 @@ public static explicit operator decimal(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
- public static explicit operator uint?(JToken value)
+ [CLSCompliant(false)]
+ public static explicit operator uint?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1146,15 +1159,15 @@ public static explicit operator decimal(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
- public static explicit operator ulong?(JToken value)
+ [CLSCompliant(false)]
+ public static explicit operator ulong?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1177,7 +1190,7 @@ public static explicit operator decimal(JToken value)
/// The result of the conversion.
public static explicit operator double(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1200,7 +1213,7 @@ public static explicit operator double(JToken value)
/// The result of the conversion.
public static explicit operator float(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1221,14 +1234,14 @@ public static explicit operator float(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator string(JToken value)
+ public static explicit operator string?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, StringTypes, true))
{
throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1259,10 +1272,10 @@ public static explicit operator string(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static explicit operator uint(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1283,10 +1296,10 @@ public static explicit operator uint(JToken value)
///
/// The value.
/// The result of the conversion.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static explicit operator ulong(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, false))
{
throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1307,14 +1320,14 @@ public static explicit operator ulong(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator byte[](JToken value)
+ public static explicit operator byte[]?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, BytesTypes, false))
{
throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1322,7 +1335,7 @@ public static explicit operator byte[](JToken value)
if (v.Value is string)
{
- return Convert.FromBase64String(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
+ return Convert.FromBase64String(Convert.ToString(v.Value, CultureInfo.InvariantCulture)!);
}
#if HAVE_BIG_INTEGER
if (v.Value is BigInteger integer)
@@ -1346,7 +1359,7 @@ public static explicit operator byte[](JToken value)
/// The result of the conversion.
public static explicit operator Guid(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, GuidTypes, false))
{
throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1357,7 +1370,7 @@ public static explicit operator Guid(JToken value)
return new Guid(bytes);
}
- return (v.Value is Guid guid) ? guid : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
+ return (v.Value is Guid guid) ? guid : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture)!);
}
///
@@ -1365,14 +1378,14 @@ public static explicit operator Guid(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator Guid?(JToken value)
+ public static explicit operator Guid?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, GuidTypes, true))
{
throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1388,7 +1401,7 @@ public static explicit operator Guid(JToken value)
return new Guid(bytes);
}
- return (v.Value is Guid guid) ? guid : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
+ return (v.Value is Guid guid) ? guid : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture)!);
}
///
@@ -1398,13 +1411,13 @@ public static explicit operator Guid(JToken value)
/// The result of the conversion.
public static explicit operator TimeSpan(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, TimeSpanTypes, false))
{
throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
}
- return (v.Value is TimeSpan span) ? span : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
+ return (v.Value is TimeSpan span) ? span : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture)!);
}
///
@@ -1412,14 +1425,14 @@ public static explicit operator TimeSpan(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator TimeSpan?(JToken value)
+ public static explicit operator TimeSpan?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, TimeSpanTypes, true))
{
throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1430,7 +1443,7 @@ public static explicit operator TimeSpan(JToken value)
return null;
}
- return (v.Value is TimeSpan span) ? span : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
+ return (v.Value is TimeSpan span) ? span : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture)!);
}
///
@@ -1438,14 +1451,14 @@ public static explicit operator TimeSpan(JToken value)
///
/// The value.
/// The result of the conversion.
- public static explicit operator Uri(JToken value)
+ public static explicit operator Uri?(JToken? value)
{
if (value == null)
{
return null;
}
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, UriTypes, true))
{
throw new ArgumentException("Can not convert {0} to Uri.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1456,24 +1469,24 @@ public static explicit operator Uri(JToken value)
return null;
}
- return (v.Value is Uri uri) ? uri : new Uri(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
+ return (v.Value is Uri uri) ? uri : new Uri(Convert.ToString(v.Value, CultureInfo.InvariantCulture)!);
}
#if HAVE_BIG_INTEGER
private static BigInteger ToBigInteger(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, BigIntegerTypes, false))
{
throw new ArgumentException("Can not convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
}
- return ConvertUtils.ToBigInteger(v.Value);
+ return ConvertUtils.ToBigInteger(v.Value!);
}
private static BigInteger? ToBigIntegerNullable(JToken value)
{
- JValue v = EnsureValue(value);
+ JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, BigIntegerTypes, true))
{
throw new ArgumentException("Can not convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
@@ -1487,9 +1500,9 @@ private static BigInteger ToBigInteger(JToken value)
return ConvertUtils.ToBigInteger(v.Value);
}
#endif
-#endregion
+ #endregion
-#region Cast to operators
+ #region Cast to operators
///
/// Performs an implicit conversion from to .
///
@@ -1537,7 +1550,7 @@ public static implicit operator JToken(byte? value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(sbyte value)
{
return new JValue(value);
@@ -1548,7 +1561,7 @@ public static implicit operator JToken(sbyte value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(sbyte? value)
{
return new JValue(value);
@@ -1621,7 +1634,7 @@ public static implicit operator JToken(double? value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(short value)
{
return new JValue(value);
@@ -1632,7 +1645,7 @@ public static implicit operator JToken(short value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(ushort value)
{
return new JValue(value);
@@ -1703,7 +1716,7 @@ public static implicit operator JToken(decimal value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(short? value)
{
return new JValue(value);
@@ -1714,7 +1727,7 @@ public static implicit operator JToken(short? value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(ushort? value)
{
return new JValue(value);
@@ -1725,7 +1738,7 @@ public static implicit operator JToken(ushort? value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(uint? value)
{
return new JValue(value);
@@ -1736,7 +1749,7 @@ public static implicit operator JToken(uint? value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(ulong? value)
{
return new JValue(value);
@@ -1767,7 +1780,7 @@ public static implicit operator JToken(float value)
///
/// The value to create a from.
/// The initialized with the specified value.
- public static implicit operator JToken(string value)
+ public static implicit operator JToken(string? value)
{
return new JValue(value);
}
@@ -1777,7 +1790,7 @@ public static implicit operator JToken(string value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(uint value)
{
return new JValue(value);
@@ -1788,7 +1801,7 @@ public static implicit operator JToken(uint value)
///
/// The value to create a from.
/// The initialized with the specified value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public static implicit operator JToken(ulong value)
{
return new JValue(value);
@@ -1809,7 +1822,7 @@ public static implicit operator JToken(byte[] value)
///
/// The value to create a from.
/// The initialized with the specified value.
- public static implicit operator JToken(Uri value)
+ public static implicit operator JToken(Uri? value)
{
return new JValue(value);
}
@@ -1853,7 +1866,7 @@ public static implicit operator JToken(Guid? value)
{
return new JValue(value);
}
-#endregion
+ #endregion
IEnumerator IEnumerable.GetEnumerator()
{
@@ -1867,7 +1880,7 @@ IEnumerator IEnumerable.GetEnumerator()
internal abstract int GetDeepHashCode();
- IJEnumerable IJEnumerable.this[object key] => this[key];
+ IJEnumerable IJEnumerable.this[object key] => this[key]!;
///
/// Creates a for this token.
@@ -1887,7 +1900,7 @@ internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerialize
using (JTokenWriter jsonWriter = new JTokenWriter())
{
jsonSerializer.Serialize(jsonWriter, o);
- token = jsonWriter.Token;
+ token = jsonWriter.Token!;
}
return token;
@@ -1919,9 +1932,9 @@ public static JToken FromObject(object o, JsonSerializer jsonSerializer)
///
/// The object type that the token will be deserialized to.
/// The new object created from the JSON value.
- public T ToObject()
+ public T? ToObject()
{
- return (T)ToObject(typeof(T));
+ return (T?)ToObject(typeof(T));
}
///
@@ -1929,7 +1942,7 @@ public T ToObject()
///
/// The object type that the token will be deserialized to.
/// The new object created from the JSON value.
- public object ToObject(Type objectType)
+ public object? ToObject(Type objectType)
{
if (JsonConvert.DefaultSettings == null)
{
@@ -1946,15 +1959,15 @@ public object ToObject(Type objectType)
}
catch (Exception ex)
{
- Type enumType = objectType.IsEnum() ? objectType : Nullable.GetUnderlyingType(objectType);
- throw new ArgumentException("Could not convert '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, (string)this, enumType.Name), ex);
+ Type enumType = objectType.IsEnum() ? objectType : Nullable.GetUnderlyingType(objectType)!;
+ throw new ArgumentException("Could not convert '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, (string?)this, enumType.Name), ex);
}
}
if (Type == JTokenType.Integer)
{
- Type enumType = objectType.IsEnum() ? objectType : Nullable.GetUnderlyingType(objectType);
- return Enum.ToObject(enumType, ((JValue)this).Value);
+ Type enumType = objectType.IsEnum() ? objectType : Nullable.GetUnderlyingType(objectType)!;
+ return Enum.ToObject(enumType, ((JValue)this).Value!);
}
}
@@ -2023,13 +2036,13 @@ public object ToObject(Type objectType)
return (DateTimeOffset)this;
#endif
case PrimitiveTypeCode.String:
- return (string)this;
+ return (string?)this;
case PrimitiveTypeCode.GuidNullable:
return (Guid?)this;
case PrimitiveTypeCode.Guid:
return (Guid)this;
case PrimitiveTypeCode.Uri:
- return (Uri)this;
+ return (Uri?)this;
case PrimitiveTypeCode.TimeSpanNullable:
return (TimeSpan?)this;
case PrimitiveTypeCode.TimeSpan:
@@ -2052,9 +2065,9 @@ public object ToObject(Type objectType)
/// The object type that the token will be deserialized to.
/// The that will be used when creating the object.
/// The new object created from the JSON value.
- public T ToObject(JsonSerializer jsonSerializer)
+ public T? ToObject(JsonSerializer jsonSerializer)
{
- return (T)ToObject(typeof(T), jsonSerializer);
+ return (T?)ToObject(typeof(T), jsonSerializer);
}
///
@@ -2063,12 +2076,19 @@ public T ToObject(JsonSerializer jsonSerializer)
/// The object type that the token will be deserialized to.
/// The that will be used when creating the object.
/// The new object created from the JSON value.
- public object ToObject(Type objectType, JsonSerializer jsonSerializer)
+ public object? ToObject(Type? objectType, JsonSerializer jsonSerializer)
{
ValidationUtils.ArgumentNotNull(jsonSerializer, nameof(jsonSerializer));
using (JTokenReader jsonReader = new JTokenReader(this))
{
+ // Hacky fix to ensure the serializer settings are set onto the new reader.
+ // This is required because the serializer won't update settings when used inside of a converter.
+ if (jsonSerializer is JsonSerializerProxy proxy)
+ {
+ proxy._serializer.SetupReader(jsonReader, out _, out _, out _, out _, out _, out _);
+ }
+
return jsonSerializer.Deserialize(jsonReader, objectType);
}
}
@@ -2098,7 +2118,7 @@ public static JToken ReadFrom(JsonReader reader)
/// that were read from the reader. The runtime type of the token is determined
/// by the token type of the first token encountered in the reader.
///
- public static JToken ReadFrom(JsonReader reader, JsonLoadSettings settings)
+ public static JToken ReadFrom(JsonReader reader, JsonLoadSettings? settings)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
@@ -2123,7 +2143,7 @@ public static JToken ReadFrom(JsonReader reader, JsonLoadSettings settings)
throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader.");
}
- IJsonLineInfo lineInfo = reader as IJsonLineInfo;
+ IJsonLineInfo? lineInfo = reader as IJsonLineInfo;
switch (reader.TokenType)
{
@@ -2145,7 +2165,7 @@ public static JToken ReadFrom(JsonReader reader, JsonLoadSettings settings)
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Comment:
- v = JValue.CreateComment(reader.Value.ToString());
+ v = JValue.CreateComment(reader.Value!.ToString());
v.SetLineInfo(lineInfo, settings);
return v;
case JsonToken.Null:
@@ -2178,7 +2198,7 @@ public static JToken Parse(string json)
/// The used to load the JSON.
/// If this is null, default load settings will be used.
/// A populated from the string that contains JSON.
- public static JToken Parse(string json, JsonLoadSettings settings)
+ public static JToken Parse(string json, JsonLoadSettings? settings)
{
using (JsonReader reader = new JsonTextReader(new StringReader(json)))
{
@@ -2189,7 +2209,6 @@ public static JToken Parse(string json, JsonLoadSettings settings)
// Any content encountered here other than a comment will throw in the reader.
}
-
return t;
}
}
@@ -2205,7 +2224,7 @@ public static JToken Parse(string json, JsonLoadSettings settings)
/// that were read from the reader. The runtime type of the token is determined
/// by the token type of the first token encountered in the reader.
///
- public static JToken Load(JsonReader reader, JsonLoadSettings settings)
+ public static JToken Load(JsonReader reader, JsonLoadSettings? settings)
{
return ReadFrom(reader, settings);
}
@@ -2224,7 +2243,7 @@ public static JToken Load(JsonReader reader)
return Load(reader, null);
}
- internal void SetLineInfo(IJsonLineInfo lineInfo, JsonLoadSettings settings)
+ internal void SetLineInfo(IJsonLineInfo? lineInfo, JsonLoadSettings? settings)
{
if (settings != null && settings.LineInfoHandling != LineInfoHandling.Load)
{
@@ -2265,7 +2284,7 @@ int IJsonLineInfo.LineNumber
{
get
{
- LineInfoAnnotation annotation = Annotation();
+ LineInfoAnnotation? annotation = Annotation();
if (annotation != null)
{
return annotation.LineNumber;
@@ -2279,7 +2298,7 @@ int IJsonLineInfo.LinePosition
{
get
{
- LineInfoAnnotation annotation = Annotation();
+ LineInfoAnnotation? annotation = Annotation();
if (annotation != null)
{
return annotation.LinePosition;
@@ -2290,31 +2309,48 @@ int IJsonLineInfo.LinePosition
}
///
- /// Selects a using a JPath expression. Selects the token that matches the object path.
+ /// Selects a using a JSONPath expression. Selects the token that matches the object path.
///
///
- /// A that contains a JPath expression.
+ /// A that contains a JSONPath expression.
///
/// A , or null.
- public JToken SelectToken(string path)
+ public JToken? SelectToken(string path)
{
- return SelectToken(path, false);
+ return SelectToken(path, settings: null);
}
///
- /// Selects a using a JPath expression. Selects the token that matches the object path.
+ /// Selects a using a JSONPath expression. Selects the token that matches the object path.
///
///
- /// A that contains a JPath expression.
+ /// A that contains a JSONPath expression.
///
/// A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression.
/// A .
- public JToken SelectToken(string path, bool errorWhenNoMatch)
+ public JToken? SelectToken(string path, bool errorWhenNoMatch)
+ {
+ JsonSelectSettings? settings = errorWhenNoMatch
+ ? new JsonSelectSettings { ErrorWhenNoMatch = true }
+ : null;
+
+ return SelectToken(path, settings);
+ }
+
+ ///
+ /// Selects a using a JSONPath expression. Selects the token that matches the object path.
+ ///
+ ///
+ /// A that contains a JSONPath expression.
+ ///
+ /// The used to select tokens.
+ /// A .
+ public JToken? SelectToken(string path, JsonSelectSettings? settings)
{
JPath p = new JPath(path);
- JToken token = null;
- foreach (JToken t in p.Evaluate(this, this, errorWhenNoMatch))
+ JToken? token = null;
+ foreach (JToken t in p.Evaluate(this, this, settings))
{
if (token != null)
{
@@ -2328,29 +2364,46 @@ public JToken SelectToken(string path, bool errorWhenNoMatch)
}
///
- /// Selects a collection of elements using a JPath expression.
+ /// Selects a collection of elements using a JSONPath expression.
///
///
- /// A that contains a JPath expression.
+ /// A that contains a JSONPath expression.
///
/// An of that contains the selected elements.
public IEnumerable SelectTokens(string path)
{
- return SelectTokens(path, false);
+ return SelectTokens(path, settings: null);
}
///
- /// Selects a collection of elements using a JPath expression.
+ /// Selects a collection of elements using a JSONPath expression.
///
///
- /// A that contains a JPath expression.
+ /// A that contains a JSONPath expression.
///
/// A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression.
/// An of that contains the selected elements.
public IEnumerable SelectTokens(string path, bool errorWhenNoMatch)
{
- JPath p = new JPath(path);
- return p.Evaluate(this, this, errorWhenNoMatch);
+ JsonSelectSettings? settings = errorWhenNoMatch
+ ? new JsonSelectSettings { ErrorWhenNoMatch = true }
+ : null;
+
+ return SelectTokens(path, settings);
+ }
+
+ ///
+ /// Selects a collection of elements using a JSONPath expression.
+ ///
+ ///
+ /// A that contains a JSONPath expression.
+ ///
+ /// The used to select tokens.
+ /// An of that contains the selected elements.
+ public IEnumerable SelectTokens(string path, JsonSelectSettings? settings)
+ {
+ var p = new JPath(path);
+ return p.Evaluate(this, this, settings);
}
#if HAVE_DYNAMIC
@@ -2438,7 +2491,7 @@ public void AddAnnotation(object annotation)
///
/// The type of the annotation to retrieve.
/// The first annotation object that matches the specified type, or null if no annotation is of the specified type.
- public T Annotation() where T : class
+ public T? Annotation() where T : class
{
if (_annotations != null)
{
@@ -2469,7 +2522,7 @@ public T Annotation() where T : class
///
/// The of the annotation to retrieve.
/// The first annotation object that matches the specified type, or null if no annotation is of the specified type.
- public object Annotation(Type type)
+ public object? Annotation(Type type)
{
if (type == null)
{
@@ -2595,7 +2648,7 @@ public void RemoveAnnotations() where T : class
{
if (_annotations != null)
{
- if (!(_annotations is object[] annotations))
+ if (!(_annotations is object?[] annotations))
{
if (_annotations is T)
{
@@ -2608,7 +2661,7 @@ public void RemoveAnnotations() where T : class
int keepCount = 0;
while (index < annotations.Length)
{
- object obj2 = annotations[index];
+ object? obj2 = annotations[index];
if (obj2 == null)
{
break;
@@ -2650,7 +2703,7 @@ public void RemoveAnnotations(Type type)
if (_annotations != null)
{
- if (!(_annotations is object[] annotations))
+ if (!(_annotations is object?[] annotations))
{
if (type.IsInstanceOfType(_annotations))
{
@@ -2663,7 +2716,7 @@ public void RemoveAnnotations(Type type)
int keepCount = 0;
while (index < annotations.Length)
{
- object o = annotations[index];
+ object? o = annotations[index];
if (o == null)
{
break;
@@ -2691,5 +2744,19 @@ public void RemoveAnnotations(Type type)
}
}
}
+
+ internal void CopyAnnotations(JToken target, JToken source)
+ {
+ if (source._annotations is object[] annotations)
+ {
+ target._annotations = annotations.ToArray();
+ }
+ else
+ {
+ target._annotations = source._annotations;
+ }
+ }
}
-}
\ No newline at end of file
+#nullable disable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenEqualityComparer.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenEqualityComparer.cs
index 374057668f..85095b9691 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenEqualityComparer.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenEqualityComparer.cs
@@ -27,6 +27,7 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Compares tokens to determine whether they are equal.
///
@@ -40,7 +41,7 @@ internal class JTokenEqualityComparer : IEqualityComparer
///
/// true if the specified objects are equal; otherwise, false.
///
- public bool Equals(JToken x, JToken y)
+ public bool Equals(JToken? x, JToken? y)
{
return JToken.DeepEquals(x, y);
}
@@ -61,4 +62,5 @@ public int GetHashCode(JToken obj)
return obj.GetDeepHashCode();
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenReader.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenReader.cs
index 2927f6dc9b..2b4b6fabb8 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenReader.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenReader.cs
@@ -28,20 +28,21 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
///
/// Represents a reader that provides fast, non-cached, forward-only access to serialized JSON data.
///
internal class JTokenReader : JsonReader, IJsonLineInfo
{
private readonly JToken _root;
- private string _initialPath;
- private JToken _parent;
- private JToken _current;
+ private string? _initialPath;
+ private JToken? _parent;
+ private JToken? _current;
///
/// Gets the at the reader's current position.
///
- public JToken CurrentToken => _current;
+ public JToken? CurrentToken => _current;
///
/// Initializes a new instance of the class.
@@ -54,8 +55,12 @@ public JTokenReader(JToken token)
_root = token;
}
- // this is used by json.net schema
- internal JTokenReader(JToken token, string initialPath)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The token to read from.
+ /// The initial path of the token. It is prepended to the returned .
+ public JTokenReader(JToken token, string initialPath)
: this(token)
{
_initialPath = initialPath;
@@ -86,6 +91,12 @@ public override bool Read()
}
}
+ // The current value could already be the root value if it is a comment
+ if (_current == _root)
+ {
+ return false;
+ }
+
_current = _root;
SetToken(_current);
return true;
@@ -98,8 +109,8 @@ private bool ReadOver(JToken t)
return ReadToEnd();
}
- JToken next = t.Next;
- if ((next == null || next == t) || t == t.Parent.Last)
+ JToken? next = t.Next;
+ if ((next == null || next == t) || t == t.Parent!.Last)
{
if (t.Parent == null)
{
@@ -142,7 +153,7 @@ private bool ReadToEnd()
private bool ReadInto(JContainer c)
{
- JToken firstChild = c.First;
+ JToken? firstChild = c.First;
if (firstChild == null)
{
return SetEnd(c);
@@ -211,7 +222,7 @@ private void SetToken(JToken token)
break;
case JTokenType.Date:
{
- object v = ((JValue)token).Value;
+ object? v = ((JValue)token).Value;
if (v is DateTime dt)
{
v = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
@@ -231,7 +242,7 @@ private void SetToken(JToken token)
break;
case JTokenType.Uri:
{
- object v = ((JValue)token).Value;
+ object? v = ((JValue)token).Value;
SetToken(JsonToken.String, v is Uri uri ? uri.OriginalString : SafeToString(v));
break;
}
@@ -243,7 +254,7 @@ private void SetToken(JToken token)
}
}
- private string SafeToString(object value)
+ private string? SafeToString(object? value)
{
return value?.ToString();
}
@@ -255,7 +266,7 @@ bool IJsonLineInfo.HasLineInfo()
return false;
}
- IJsonLineInfo info = _current;
+ IJsonLineInfo? info = _current;
return (info != null && info.HasLineInfo());
}
@@ -268,7 +279,7 @@ int IJsonLineInfo.LineNumber
return 0;
}
- IJsonLineInfo info = _current;
+ IJsonLineInfo? info = _current;
if (info != null)
{
return info.LineNumber;
@@ -287,7 +298,7 @@ int IJsonLineInfo.LinePosition
return 0;
}
- IJsonLineInfo info = _current;
+ IJsonLineInfo? info = _current;
if (info != null)
{
return info.LinePosition;
@@ -298,7 +309,7 @@ int IJsonLineInfo.LinePosition
}
///
- /// Gets the path of the current JSON token.
+ /// Gets the path of the current JSON token.
///
public override string Path
{
@@ -311,9 +322,9 @@ public override string Path
_initialPath = _root.Path;
}
- if (!string.IsNullOrEmpty(_initialPath))
+ if (!StringUtils.IsNullOrEmpty(_initialPath))
{
- if (string.IsNullOrEmpty(path))
+ if (StringUtils.IsNullOrEmpty(path))
{
return _initialPath;
}
@@ -332,4 +343,5 @@ public override string Path
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenType.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenType.cs
index efa6679ed5..bea656dd77 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenType.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenType.cs
@@ -120,4 +120,4 @@ internal enum JTokenType
///
TimeSpan = 17
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.Async.cs
index 4508380ccf..07b8f0bb72 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.Async.cs
@@ -50,4 +50,4 @@ internal override Task WriteTokenAsync(JsonReader reader, bool writeChildren, bo
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.cs
index 7376dd303c..941ff14a6e 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JTokenWriter.cs
@@ -24,6 +24,7 @@
#endregion
using System;
+using System.Diagnostics;
using System.Globalization;
#if HAVE_BIG_INTEGER
using System.Numerics;
@@ -32,27 +33,29 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
///
/// Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data.
///
internal partial class JTokenWriter : JsonWriter
{
- private JContainer _token;
- private JContainer _parent;
+ private JContainer? _token;
+ private JContainer? _parent;
// used when writer is writing single value and the value has no containing parent
- private JValue _value;
- private JToken _current;
+ private JValue? _value;
+ private JToken? _current;
///
/// Gets the at the writer's current position.
///
- public JToken CurrentToken => _current;
+ public JToken? CurrentToken => _current;
///
/// Gets the token being written.
///
/// The token being written.
- public JToken Token
+ public JToken? Token
{
get
{
@@ -131,7 +134,7 @@ private void AddParent(JContainer container)
private void RemoveParent()
{
_current = _parent;
- _parent = _parent.Parent;
+ _parent = _parent!.Parent;
if (_parent != null && _parent.Type == JTokenType.Property)
{
@@ -186,21 +189,26 @@ public override void WritePropertyName(string name)
base.WritePropertyName(name);
}
- private void AddValue(object value, JsonToken token)
+ private void AddRawValue(object? value, JTokenType type, JsonToken token)
{
- AddValue(new JValue(value), token);
+ AddJValue(new JValue(value, type), token);
}
- internal void AddValue(JValue value, JsonToken token)
+ internal void AddJValue(JValue? value, JsonToken token)
{
if (_parent != null)
{
- _parent.Add(value);
- _current = _parent.Last;
-
- if (_parent.Type == JTokenType.Property)
+ // TryAdd will return false if an invalid JToken type is added.
+ // For example, a JComment can't be added to a JObject.
+ // If there is an invalid JToken type then skip it.
+ if (_parent.TryAdd(value))
{
- _parent = _parent.Parent;
+ _current = _parent.Last;
+
+ if (_parent.Type == JTokenType.Property)
+ {
+ _parent = _parent.Parent;
+ }
}
}
else
@@ -216,13 +224,13 @@ internal void AddValue(JValue value, JsonToken token)
/// An error will be raised if the value cannot be written as a single JSON token.
///
/// The value to write.
- public override void WriteValue(object value)
+ public override void WriteValue(object? value)
{
#if HAVE_BIG_INTEGER
if (value is BigInteger)
{
InternalWriteValue(JsonToken.Integer);
- AddValue(value, JsonToken.Integer);
+ AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
else
#endif
@@ -237,7 +245,7 @@ public override void WriteValue(object value)
public override void WriteNull()
{
base.WriteNull();
- AddValue(null, JsonToken.Null);
+ AddJValue(JValue.CreateNull(), JsonToken.Null);
}
///
@@ -246,37 +254,37 @@ public override void WriteNull()
public override void WriteUndefined()
{
base.WriteUndefined();
- AddValue(null, JsonToken.Undefined);
+ AddJValue(JValue.CreateUndefined(), JsonToken.Undefined);
}
///
/// Writes raw JSON.
///
/// The raw JSON to write.
- public override void WriteRaw(string json)
+ public override void WriteRaw(string? json)
{
base.WriteRaw(json);
- AddValue(new JRaw(json), JsonToken.Raw);
+ AddJValue(new JRaw(json), JsonToken.Raw);
}
///
/// Writes a comment /*...*/ containing the specified text.
///
/// Text to place inside the comment.
- public override void WriteComment(string text)
+ public override void WriteComment(string? text)
{
base.WriteComment(text);
- AddValue(JValue.CreateComment(text), JsonToken.Comment);
+ AddJValue(JValue.CreateComment(text), JsonToken.Comment);
}
///
/// Writes a value.
///
/// The value to write.
- public override void WriteValue(string value)
+ public override void WriteValue(string? value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.String);
+ AddJValue(new JValue(value), JsonToken.String);
}
///
@@ -286,18 +294,18 @@ public override void WriteValue(string value)
public override void WriteValue(int value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
///
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(uint value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
///
@@ -307,18 +315,18 @@ public override void WriteValue(uint value)
public override void WriteValue(long value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddJValue(new JValue(value), JsonToken.Integer);
}
///
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(ulong value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddJValue(new JValue(value), JsonToken.Integer);
}
///
@@ -328,7 +336,7 @@ public override void WriteValue(ulong value)
public override void WriteValue(float value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Float);
+ AddJValue(new JValue(value), JsonToken.Float);
}
///
@@ -338,7 +346,7 @@ public override void WriteValue(float value)
public override void WriteValue(double value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Float);
+ AddJValue(new JValue(value), JsonToken.Float);
}
///
@@ -348,7 +356,7 @@ public override void WriteValue(double value)
public override void WriteValue(bool value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Boolean);
+ AddJValue(new JValue(value), JsonToken.Boolean);
}
///
@@ -358,18 +366,18 @@ public override void WriteValue(bool value)
public override void WriteValue(short value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
///
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(ushort value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
///
@@ -383,11 +391,9 @@ public override void WriteValue(char value)
#if HAVE_CHAR_TO_STRING_WITH_CULTURE
s = value.ToString(CultureInfo.InvariantCulture);
#else
-#pragma warning disable CA1305 // Specify IFormatProvider
s = value.ToString();
-#pragma warning restore CA1305 // Specify IFormatProvider
#endif
- AddValue(s, JsonToken.String);
+ AddJValue(new JValue(s), JsonToken.String);
}
///
@@ -397,18 +403,18 @@ public override void WriteValue(char value)
public override void WriteValue(byte value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
///
/// Writes a value.
///
/// The value to write.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public override void WriteValue(sbyte value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Integer);
+ AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
///
@@ -418,7 +424,7 @@ public override void WriteValue(sbyte value)
public override void WriteValue(decimal value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Float);
+ AddJValue(new JValue(value), JsonToken.Float);
}
///
@@ -429,7 +435,7 @@ public override void WriteValue(DateTime value)
{
base.WriteValue(value);
value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling);
- AddValue(value, JsonToken.Date);
+ AddJValue(new JValue(value), JsonToken.Date);
}
#if HAVE_DATE_TIME_OFFSET
@@ -440,7 +446,7 @@ public override void WriteValue(DateTime value)
public override void WriteValue(DateTimeOffset value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Date);
+ AddJValue(new JValue(value), JsonToken.Date);
}
#endif
@@ -448,10 +454,10 @@ public override void WriteValue(DateTimeOffset value)
/// Writes a [] value.
///
/// The [] value to write.
- public override void WriteValue(byte[] value)
+ public override void WriteValue(byte[]? value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.Bytes);
+ AddJValue(new JValue(value, JTokenType.Bytes), JsonToken.Bytes);
}
///
@@ -461,7 +467,7 @@ public override void WriteValue(byte[] value)
public override void WriteValue(TimeSpan value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.String);
+ AddJValue(new JValue(value), JsonToken.String);
}
///
@@ -471,17 +477,17 @@ public override void WriteValue(TimeSpan value)
public override void WriteValue(Guid value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.String);
+ AddJValue(new JValue(value), JsonToken.String);
}
///
/// Writes a value.
///
/// The value to write.
- public override void WriteValue(Uri value)
+ public override void WriteValue(Uri? value)
{
base.WriteValue(value);
- AddValue(value, JsonToken.String);
+ AddJValue(new JValue(value), JsonToken.String);
}
#endregion
@@ -498,7 +504,7 @@ internal override void WriteToken(JsonReader reader, bool writeChildren, bool wr
}
}
- JToken value = tokenReader.CurrentToken.CloneToken();
+ JToken value = tokenReader.CurrentToken!.CloneToken();
if (_parent != null)
{
@@ -531,4 +537,6 @@ internal override void WriteToken(JsonReader reader, bool writeChildren, bool wr
}
}
}
-}
\ No newline at end of file
+#nullable disable
+#pragma warning restore CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.Async.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.Async.cs
index 97db26b2ba..b49d4a23f6 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.Async.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.Async.cs
@@ -36,9 +36,8 @@
namespace Microsoft.IdentityModel.Json.Linq
{
-#pragma warning disable CA1036 // Should define operators since implements IComparable
+#nullable enable
internal partial class JValue
-#pragma warning restore CA1036 // Should define operators since implements IComparable
{
///
/// Writes this token to a asynchronously.
@@ -51,7 +50,7 @@ public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellat
{
if (converters != null && converters.Length > 0 && _value != null)
{
- JsonConverter matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType());
+ JsonConverter? matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType());
if (matchingConverter != null && matchingConverter.CanWrite)
{
// TODO: Call WriteJsonAsync when it exists.
@@ -123,18 +122,19 @@ public override Task WriteToAsync(JsonWriter writer, CancellationToken cancellat
return writer.WriteValueAsync(Convert.ToDateTime(_value, CultureInfo.InvariantCulture), cancellationToken);
case JTokenType.Bytes:
- return writer.WriteValueAsync((byte[])_value, cancellationToken);
+ return writer.WriteValueAsync((byte[]?)_value, cancellationToken);
case JTokenType.Guid:
return writer.WriteValueAsync(_value != null ? (Guid?)_value : null, cancellationToken);
case JTokenType.TimeSpan:
return writer.WriteValueAsync(_value != null ? (TimeSpan?)_value : null, cancellationToken);
case JTokenType.Uri:
- return writer.WriteValueAsync((Uri)_value, cancellationToken);
+ return writer.WriteValueAsync((Uri?)_value, cancellationToken);
}
throw MiscellaneousUtils.CreateArgumentOutOfRangeException(nameof(Type), _valueType, "Unexpected token type.");
}
}
+#nullable disable
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.cs
index 28dd87fcdd..811e3136dc 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JValue.cs
@@ -28,6 +28,8 @@
using System.Diagnostics;
using Microsoft.IdentityModel.Json.Utilities;
using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if HAVE_DYNAMIC
using System.Dynamic;
using System.Linq.Expressions;
@@ -38,6 +40,8 @@
namespace Microsoft.IdentityModel.Json.Linq
{
+#nullable enable
+#pragma warning disable CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
///
/// Represents a value in JSON (string, integer, date, etc).
///
@@ -47,9 +51,9 @@ internal partial class JValue : JToken, IEquatable, IFormattable, ICompa
#endif
{
private JTokenType _valueType;
- private object _value;
+ private object? _value;
- internal JValue(object value, JTokenType type)
+ internal JValue(object? value, JTokenType type)
{
_value = value;
_valueType = type;
@@ -62,6 +66,7 @@ internal JValue(object value, JTokenType type)
public JValue(JValue other)
: this(other.Value, other.Type)
{
+ CopyAnnotations(this, other);
}
///
@@ -69,7 +74,7 @@ public JValue(JValue other)
///
/// The value.
public JValue(long value)
- : this(value, JTokenType.Integer)
+ : this(BoxedPrimitives.Get(value), JTokenType.Integer)
{
}
@@ -78,7 +83,7 @@ public JValue(long value)
///
/// The value.
public JValue(decimal value)
- : this(value, JTokenType.Float)
+ : this(BoxedPrimitives.Get(value), JTokenType.Float)
{
}
@@ -95,7 +100,7 @@ public JValue(char value)
/// Initializes a new instance of the class with the given value.
///
/// The value.
- // [ClsCompliant(false)]
+ [CLSCompliant(false)]
public JValue(ulong value)
: this(value, JTokenType.Integer)
{
@@ -106,7 +111,7 @@ public JValue(ulong value)
///
/// The value.
public JValue(double value)
- : this(value, JTokenType.Float)
+ : this(BoxedPrimitives.Get(value), JTokenType.Float)
{
}
@@ -144,7 +149,7 @@ public JValue(DateTimeOffset value)
///
/// The value.
public JValue(bool value)
- : this(value, JTokenType.Boolean)
+ : this(BoxedPrimitives.Get(value), JTokenType.Boolean)
{
}
@@ -152,7 +157,7 @@ public JValue(bool value)
/// Initializes a new instance of the class with the given value.
///
/// The value.
- public JValue(string value)
+ public JValue(string? value)
: this(value, JTokenType.String)
{
}
@@ -170,7 +175,7 @@ public JValue(Guid value)
/// Initializes a new instance of the class with the given value.
///
/// The value.
- public JValue(Uri value)
+ public JValue(Uri? value)
: this(value, (value != null) ? JTokenType.Uri : JTokenType.Null)
{
}
@@ -188,7 +193,7 @@ public JValue(TimeSpan value)
/// Initializes a new instance of the class with the given value.
///
/// The value.
- public JValue(object value)
+ public JValue(object? value)
: this(value, GetValueType(null, value))
{
}
@@ -241,7 +246,7 @@ private static int CompareBigInteger(BigInteger i1, object i2)
}
#endif
- internal static int Compare(JTokenType valueType, object objA, object objB)
+ internal static int Compare(JTokenType valueType, object? objA, object? objB)
{
if (objA == objB)
{
@@ -267,8 +272,8 @@ internal static int Compare(JTokenType valueType, object objA, object objB)
}
if (objB is BigInteger integerB)
{
- return -CompareBigInteger(integerB, objA);
- }
+ return -CompareBigInteger(integerB, objA);
+ }
#endif
if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
{
@@ -300,12 +305,12 @@ internal static int Compare(JTokenType valueType, object objA, object objB)
return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture));
}
return CompareFloat(objA, objB);
- }
+ }
case JTokenType.Comment:
case JTokenType.String:
case JTokenType.Raw:
- string s1 = Convert.ToString(objA, CultureInfo.InvariantCulture);
- string s2 = Convert.ToString(objB, CultureInfo.InvariantCulture);
+ string? s1 = Convert.ToString(objA, CultureInfo.InvariantCulture);
+ string? s2 = Convert.ToString(objB, CultureInfo.InvariantCulture);
return string.CompareOrdinal(s1, s2);
case JTokenType.Boolean:
@@ -353,10 +358,10 @@ internal static int Compare(JTokenType valueType, object objA, object objB)
throw new ArgumentException("Object must be of type byte[].");
}
- byte[] bytesA = objA as byte[];
- Debug.Assert(bytesA != null);
+ byte[]? bytesA = objA as byte[];
+ MiscellaneousUtils.Assert(bytesA != null);
- return MiscellaneousUtils.ByteArrayCompare(bytesA, bytesB);
+ return MiscellaneousUtils.ByteArrayCompare(bytesA!, bytesB);
case JTokenType.Guid:
if (!(objB is Guid))
{
@@ -368,7 +373,7 @@ internal static int Compare(JTokenType valueType, object objA, object objB)
return guid1.CompareTo(guid2);
case JTokenType.Uri:
- Uri uri2 = objB as Uri;
+ Uri? uri2 = objB as Uri;
if (uri2 == null)
{
throw new ArgumentException("Object must be of type Uri.");
@@ -407,7 +412,7 @@ private static int CompareFloat(object objA, object objB)
}
#if HAVE_EXPRESSIONS
- private static bool Operation(ExpressionType operation, object objA, object objB, out object result)
+ private static bool Operation(ExpressionType operation, object? objA, object? objB, out object? result)
{
if (objA is string || objB is string)
{
@@ -564,7 +569,7 @@ internal override JToken CloneToken()
///
/// The value.
/// A comment with the given value.
- public static JValue CreateComment(string value)
+ public static JValue CreateComment(string? value)
{
return new JValue(value, JTokenType.Comment);
}
@@ -574,7 +579,7 @@ public static JValue CreateComment(string value)
///
/// The value.
/// A string with the given value.
- public static JValue CreateString(string value)
+ public static JValue CreateString(string? value)
{
return new JValue(value, JTokenType.String);
}
@@ -597,7 +602,7 @@ public static JValue CreateUndefined()
return new JValue(null, JTokenType.Undefined);
}
- private static JTokenType GetValueType(JTokenType? current, object value)
+ private static JTokenType GetValueType(JTokenType? current, object? value)
{
if (value == null)
{
@@ -694,13 +699,13 @@ private static JTokenType GetStringValueType(JTokenType? current)
/// Gets or sets the underlying token value.
///
/// The underlying token value.
- public object Value
+ public object? Value
{
get => _value;
set
{
- Type currentType = _value?.GetType();
- Type newType = value?.GetType();
+ Type? currentType = _value?.GetType();
+ Type? newType = value?.GetType();
if (currentType != newType)
{
@@ -720,7 +725,7 @@ public override void WriteTo(JsonWriter writer, params JsonConverter[] converter
{
if (converters != null && converters.Length > 0 && _value != null)
{
- JsonConverter matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType());
+ JsonConverter? matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType());
if (matchingConverter != null && matchingConverter.CanWrite)
{
matchingConverter.WriteJson(writer, _value, JsonSerializer.CreateDefault());
@@ -803,7 +808,7 @@ public override void WriteTo(JsonWriter writer, params JsonConverter[] converter
}
return;
case JTokenType.Bytes:
- writer.WriteValue((byte[])_value);
+ writer.WriteValue((byte[]?)_value);
return;
case JTokenType.Guid:
writer.WriteValue((_value != null) ? (Guid?)_value : null);
@@ -812,7 +817,7 @@ public override void WriteTo(JsonWriter writer, params JsonConverter[] converter
writer.WriteValue((_value != null) ? (TimeSpan?)_value : null);
return;
case JTokenType.Uri:
- writer.WriteValue((Uri)_value);
+ writer.WriteValue((Uri?)_value);
return;
}
@@ -839,7 +844,7 @@ private static bool ValuesEquals(JValue v1, JValue v2)
/// true if the current object is equal to the parameter; otherwise, false.
///
/// An object to compare with this object.
- public bool Equals(JValue other)
+ public bool Equals(JValue? other)
{
if (other == null)
{
@@ -856,9 +861,14 @@ public bool Equals(JValue other)
///
/// true if the specified is equal to the current ; otherwise, false.
///
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
- return Equals(obj as JValue);
+ if (obj is JValue v)
+ {
+ return Equals(v);
+ }
+
+ return false;
}
///
@@ -880,6 +890,10 @@ public override int GetHashCode()
///
/// Returns a that represents this instance.
///
+ ///
+ /// ToString() returns a non-JSON string value for tokens with a type of .
+ /// If you want the JSON for all token types then you should use .
+ ///
///
/// A that represents this instance.
///
@@ -890,7 +904,7 @@ public override string ToString()
return string.Empty;
}
- return _value.ToString();
+ return _value.ToString()!;
}
///
@@ -912,7 +926,7 @@ public string ToString(string format)
///
/// A that represents this instance.
///
- public string ToString(IFormatProvider formatProvider)
+ public string ToString(IFormatProvider? formatProvider)
{
return ToString(null, formatProvider);
}
@@ -925,7 +939,7 @@ public string ToString(IFormatProvider formatProvider)
///
/// A that represents this instance.
///
- public string ToString(string format, IFormatProvider formatProvider)
+ public string ToString(string? format, IFormatProvider? formatProvider)
{
if (_value == null)
{
@@ -938,7 +952,7 @@ public string ToString(string format, IFormatProvider formatProvider)
}
else
{
- return _value.ToString();
+ return _value.ToString()!;
}
}
@@ -957,7 +971,7 @@ protected override DynamicMetaObject GetMetaObject(Expression parameter)
private class JValueDynamicProxy : DynamicProxy
{
- public override bool TryConvert(JValue instance, ConvertBinder binder, out object result)
+ public override bool TryConvert(JValue instance, ConvertBinder binder, [NotNullWhen(true)]out object? result)
{
if (binder.Type == typeof(JValue) || binder.Type == typeof(JToken))
{
@@ -965,7 +979,7 @@ public override bool TryConvert(JValue instance, ConvertBinder binder, out objec
return true;
}
- object value = instance.Value;
+ object? value = instance.Value;
if (value == null)
{
@@ -977,9 +991,9 @@ public override bool TryConvert(JValue instance, ConvertBinder binder, out objec
return true;
}
- public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder binder, object arg, out object result)
+ public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder binder, object arg, [NotNullWhen(true)]out object? result)
{
- object compareValue = arg is JValue value ? value.Value : arg;
+ object? compareValue = arg is JValue value ? value.Value : arg;
switch (binder.Operation)
{
@@ -1023,7 +1037,7 @@ public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder b
}
#endif
- int IComparable.CompareTo(object obj)
+ int IComparable.CompareTo(object? obj)
{
if (obj == null)
{
@@ -1031,7 +1045,7 @@ int IComparable.CompareTo(object obj)
}
JTokenType comparisonType;
- object otherValue;
+ object? otherValue;
if (obj is JValue value)
{
otherValue = value.Value;
@@ -1066,7 +1080,7 @@ int IComparable.CompareTo(object obj)
///
/// is not of the same type as this instance.
///
- public int CompareTo(JValue obj)
+ public int CompareTo(JValue? obj)
{
if (obj == null)
{
@@ -1096,80 +1110,82 @@ TypeCode IConvertible.GetTypeCode()
return TypeCode.Object;
}
- bool IConvertible.ToBoolean(IFormatProvider provider)
+ bool IConvertible.ToBoolean(IFormatProvider? provider)
{
return (bool)this;
}
- char IConvertible.ToChar(IFormatProvider provider)
+ char IConvertible.ToChar(IFormatProvider? provider)
{
return (char)this;
}
- sbyte IConvertible.ToSByte(IFormatProvider provider)
+ sbyte IConvertible.ToSByte(IFormatProvider? provider)
{
return (sbyte)this;
}
- byte IConvertible.ToByte(IFormatProvider provider)
+ byte IConvertible.ToByte(IFormatProvider? provider)
{
return (byte)this;
}
- short IConvertible.ToInt16(IFormatProvider provider)
+ short IConvertible.ToInt16(IFormatProvider? provider)
{
return (short)this;
}
- ushort IConvertible.ToUInt16(IFormatProvider provider)
+ ushort IConvertible.ToUInt16(IFormatProvider? provider)
{
return (ushort)this;
}
- int IConvertible.ToInt32(IFormatProvider provider)
+ int IConvertible.ToInt32(IFormatProvider? provider)
{
return (int)this;
}
- uint IConvertible.ToUInt32(IFormatProvider provider)
+ uint IConvertible.ToUInt32(IFormatProvider? provider)
{
return (uint)this;
}
- long IConvertible.ToInt64(IFormatProvider provider)
+ long IConvertible.ToInt64(IFormatProvider? provider)
{
return (long)this;
}
- ulong IConvertible.ToUInt64(IFormatProvider provider)
+ ulong IConvertible.ToUInt64(IFormatProvider? provider)
{
return (ulong)this;
}
- float IConvertible.ToSingle(IFormatProvider provider)
+ float IConvertible.ToSingle(IFormatProvider? provider)
{
return (float)this;
}
- double IConvertible.ToDouble(IFormatProvider provider)
+ double IConvertible.ToDouble(IFormatProvider? provider)
{
return (double)this;
}
- decimal IConvertible.ToDecimal(IFormatProvider provider)
+ decimal IConvertible.ToDecimal(IFormatProvider? provider)
{
return (decimal)this;
}
- DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ DateTime IConvertible.ToDateTime(IFormatProvider? provider)
{
return (DateTime)this;
}
- object IConvertible.ToType(Type conversionType, IFormatProvider provider)
+ object IConvertible.ToType(Type conversionType, IFormatProvider? provider)
{
- return ToObject(conversionType);
+ return ToObject(conversionType)!;
}
#endif
}
+#nullable disable
+#pragma warning restore CS3019 // CLS compliance checking will not be performed because it is not visible from outside this assembly
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonLoadSettings.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonLoadSettings.cs
index e9ef1c1805..e0bde4290a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonLoadSettings.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonLoadSettings.cs
@@ -9,6 +9,7 @@ internal class JsonLoadSettings
{
private CommentHandling _commentHandling;
private LineInfoHandling _lineInfoHandling;
+ private DuplicatePropertyNameHandling _duplicatePropertyNameHandling;
///
/// Initializes a new instance of the class.
@@ -17,10 +18,12 @@ public JsonLoadSettings()
{
_lineInfoHandling = LineInfoHandling.Load;
_commentHandling = CommentHandling.Ignore;
+ _duplicatePropertyNameHandling = DuplicatePropertyNameHandling.Replace;
}
///
/// Gets or sets how JSON comments are handled when loading JSON.
+ /// The default value is .
///
/// The JSON comment handling.
public CommentHandling CommentHandling
@@ -39,6 +42,7 @@ public CommentHandling CommentHandling
///
/// Gets or sets how JSON line info is handled when loading JSON.
+ /// The default value is .
///
/// The JSON line info handling.
public LineInfoHandling LineInfoHandling
@@ -54,5 +58,24 @@ public LineInfoHandling LineInfoHandling
_lineInfoHandling = value;
}
}
+
+ ///
+ /// Gets or sets how duplicate property names in JSON objects are handled when loading JSON.
+ /// The default value is .
+ ///
+ /// The JSON duplicate property name handling.
+ public DuplicatePropertyNameHandling DuplicatePropertyNameHandling
+ {
+ get => _duplicatePropertyNameHandling;
+ set
+ {
+ if (value < DuplicatePropertyNameHandling.Replace || value > DuplicatePropertyNameHandling.Error)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value));
+ }
+
+ _duplicatePropertyNameHandling = value;
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonMergeSettings.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonMergeSettings.cs
index 83875c0df3..c25b88d7e4 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonMergeSettings.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonMergeSettings.cs
@@ -100,4 +100,4 @@ public StringComparison PropertyNameComparison
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ArrayIndexFilter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ArrayIndexFilter.cs
index e63422dfd7..d4aa95842f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ArrayIndexFilter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ArrayIndexFilter.cs
@@ -4,17 +4,18 @@
namespace Microsoft.IdentityModel.Json.Linq.JsonPath
{
+#nullable enable
internal class ArrayIndexFilter : PathFilter
{
public int? Index { get; set; }
- public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken t in current)
{
if (Index != null)
{
- JToken v = GetTokenIndex(t, errorWhenNoMatch, Index.GetValueOrDefault());
+ JToken? v = GetTokenIndex(t, settings, Index.GetValueOrDefault());
if (v != null)
{
@@ -32,7 +33,7 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable Indexes { get; set; }
+ internal List Indexes;
- public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public ArrayMultipleIndexFilter(List indexes)
+ {
+ Indexes = indexes;
+ }
+
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken t in current)
{
foreach (int i in Indexes)
{
- JToken v = GetTokenIndex(t, errorWhenNoMatch, i);
+ JToken? v = GetTokenIndex(t, settings, i);
if (v != null)
{
@@ -22,4 +28,5 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
if (Step == 0)
{
@@ -56,7 +57,7 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable stopIndex);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/FieldFilter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/FieldFilter.cs
index b9a0db062f..0f6ad2ccd6 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/FieldFilter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/FieldFilter.cs
@@ -4,11 +4,17 @@
namespace Microsoft.IdentityModel.Json.Linq.JsonPath
{
+#nullable enable
internal class FieldFilter : PathFilter
{
- public string Name { get; set; }
+ internal string? Name;
- public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public FieldFilter(string? name)
+ {
+ Name = name;
+ }
+
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken t in current)
{
@@ -16,28 +22,28 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable p in o)
+ foreach (KeyValuePair p in o)
{
- yield return p.Value;
+ yield return p.Value!;
}
}
}
else
{
- if (errorWhenNoMatch)
+ if (settings?.ErrorWhenNoMatch ?? false)
{
throw new JsonException("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, Name ?? "*", t.GetType().Name));
}
@@ -45,4 +51,5 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable Names { get; set; }
+ internal List Names;
- public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public FieldMultipleFilter(List names)
+ {
+ Names = names;
+ }
+
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken t in current)
{
@@ -21,14 +27,14 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable "'" + n + "'")
#if !HAVE_STRING_JOIN_WITH_ENUMERABLE
@@ -48,4 +54,5 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable filters, int currentPartStartIndex, bool
case '(':
if (_currentIndex > currentPartStartIndex)
{
- string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+ string? member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
if (member == "*")
{
member = null;
@@ -118,6 +119,8 @@ private bool ParsePath(List filters, int currentPartStartIndex, bool
}
filters.Add(ParseIndexer(currentChar, scan));
+ scan = false;
+
_currentIndex++;
currentPartStartIndex = _currentIndex;
followingIndexer = true;
@@ -136,7 +139,7 @@ private bool ParsePath(List filters, int currentPartStartIndex, bool
case '.':
if (_currentIndex > currentPartStartIndex)
{
- string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+ string? member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
if (member == "*")
{
member = null;
@@ -177,7 +180,7 @@ private bool ParsePath(List filters, int currentPartStartIndex, bool
if (_currentIndex > currentPartStartIndex)
{
- string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex).TrimEnd();
+ string? member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex).TrimEnd();
if (member == "*")
{
member = null;
@@ -196,9 +199,9 @@ private bool ParsePath(List filters, int currentPartStartIndex, bool
return atPathEnd;
}
- private static PathFilter CreatePathFilter(string member, bool scan)
+ private static PathFilter CreatePathFilter(string? member, bool scan)
{
- PathFilter filter = (scan) ? (PathFilter)new ScanFilter {Name = member} : new FieldFilter {Name = member};
+ PathFilter filter = (scan) ? (PathFilter)new ScanFilter(member) : new FieldFilter(member);
return filter;
}
@@ -230,7 +233,7 @@ private PathFilter ParseArrayIndexer(char indexerCloseChar)
{
int start = _currentIndex;
int? end = null;
- List indexes = null;
+ List? indexes = null;
int colonCount = 0;
int? startIndex = null;
int? endIndex = null;
@@ -262,7 +265,7 @@ private PathFilter ParseArrayIndexer(char indexerCloseChar)
int index = Convert.ToInt32(indexer, CultureInfo.InvariantCulture);
indexes.Add(index);
- return new ArrayMultipleIndexFilter { Indexes = indexes };
+ return new ArrayMultipleIndexFilter(indexes);
}
else if (colonCount > 0)
{
@@ -421,26 +424,19 @@ private PathFilter ParseQuery(char indexerCloseChar, bool scan)
if (!scan)
{
- return new QueryFilter
- {
- Expression = expression
- };
+ return new QueryFilter(expression);
}
else
{
- return new QueryScanFilter
- {
- Expression = expression
- };
+ return new QueryScanFilter(expression);
}
}
- private bool TryParseExpression(out List expressionPath)
+ private bool TryParseExpression(out List? expressionPath)
{
if (_expression[_currentIndex] == '$')
{
- expressionPath = new List();
- expressionPath.Add(RootFilter.Instance);
+ expressionPath = new List { RootFilter.Instance };
}
else if (_expression[_currentIndex] == '@')
{
@@ -454,7 +450,7 @@ private bool TryParseExpression(out List expressionPath)
_currentIndex++;
- if (ParsePath(expressionPath, _currentIndex, true))
+ if (ParsePath(expressionPath!, _currentIndex, true))
{
throw new JsonException("Path ended with open query.");
}
@@ -471,12 +467,12 @@ private object ParseSide()
{
EatWhitespace();
- if (TryParseExpression(out var expressionPath))
+ if (TryParseExpression(out List? expressionPath))
{
EatWhitespace();
EnsureLength("Path ended with open query.");
- return expressionPath;
+ return expressionPath!;
}
if (TryParseValue(out var value))
@@ -492,13 +488,13 @@ private object ParseSide()
private QueryExpression ParseExpression()
{
- QueryExpression rootExpression = null;
- CompositeExpression parentExpression = null;
+ QueryExpression? rootExpression = null;
+ CompositeExpression? parentExpression = null;
while (_currentIndex < _expression.Length)
{
object left = ParseSide();
- object right = null;
+ object? right = null;
QueryOperator op;
if (_expression[_currentIndex] == ')'
@@ -514,19 +510,14 @@ private QueryExpression ParseExpression()
right = ParseSide();
}
- BooleanQueryExpression booleanExpression = new BooleanQueryExpression
- {
- Left = left,
- Operator = op,
- Right = right
- };
+ BooleanQueryExpression booleanExpression = new BooleanQueryExpression(op, left, right);
if (_expression[_currentIndex] == ')')
{
if (parentExpression != null)
{
parentExpression.Expressions.Add(booleanExpression);
- return rootExpression;
+ return rootExpression!;
}
return booleanExpression;
@@ -540,7 +531,7 @@ private QueryExpression ParseExpression()
if (parentExpression == null || parentExpression.Operator != QueryOperator.And)
{
- CompositeExpression andExpression = new CompositeExpression { Operator = QueryOperator.And };
+ CompositeExpression andExpression = new CompositeExpression(QueryOperator.And);
parentExpression?.Expressions.Add(andExpression);
@@ -563,7 +554,7 @@ private QueryExpression ParseExpression()
if (parentExpression == null || parentExpression.Operator != QueryOperator.Or)
{
- CompositeExpression orExpression = new CompositeExpression { Operator = QueryOperator.Or };
+ CompositeExpression orExpression = new CompositeExpression(QueryOperator.Or);
parentExpression?.Expressions.Add(orExpression);
@@ -582,7 +573,7 @@ private QueryExpression ParseExpression()
throw new JsonException("Path ended with open query.");
}
- private bool TryParseValue(out object value)
+ private bool TryParseValue(out object? value)
{
char currentChar = _expression[_currentIndex];
if (currentChar == '\'')
@@ -763,9 +754,9 @@ private string ReadRegexString()
private bool Match(string s)
{
int currentPosition = _currentIndex;
- foreach (char c in s)
+ for (int i = 0; i < s.Length; i++)
{
- if (currentPosition < _expression.Length && _expression[currentPosition] == c)
+ if (currentPosition < _expression.Length && _expression[currentPosition] == s[i])
{
currentPosition++;
}
@@ -832,7 +823,7 @@ private QueryOperator ParseOperator()
private PathFilter ParseQuotedField(char indexerCloseChar, bool scan)
{
- List fields = null;
+ List? fields = null;
while (_currentIndex < _expression.Length)
{
@@ -847,8 +838,8 @@ private PathFilter ParseQuotedField(char indexerCloseChar, bool scan)
{
fields.Add(field);
return (scan)
- ? (PathFilter)new ScanMultipleFilter { Names = fields }
- : (PathFilter)new FieldMultipleFilter { Names = fields };
+ ? (PathFilter)new ScanMultipleFilter(fields)
+ : (PathFilter)new FieldMultipleFilter(fields);
}
else
{
@@ -884,20 +875,21 @@ private void EnsureLength(string message)
}
}
- internal IEnumerable Evaluate(JToken root, JToken t, bool errorWhenNoMatch)
+ internal IEnumerable Evaluate(JToken root, JToken t, JsonSelectSettings? settings)
{
- return Evaluate(Filters, root, t, errorWhenNoMatch);
+ return Evaluate(Filters, root, t, settings);
}
- internal static IEnumerable Evaluate(List filters, JToken root, JToken t, bool errorWhenNoMatch)
+ internal static IEnumerable Evaluate(List filters, JToken root, JToken t, JsonSelectSettings? settings)
{
IEnumerable current = new[] { t };
foreach (PathFilter filter in filters)
{
- current = filter.ExecuteFilter(root, current, errorWhenNoMatch);
+ current = filter.ExecuteFilter(root, current, settings);
}
return current;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/PathFilter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/PathFilter.cs
index 66432e0ccc..4495a67ece 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/PathFilter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/PathFilter.cs
@@ -4,18 +4,18 @@
namespace Microsoft.IdentityModel.Json.Linq.JsonPath
{
+#nullable enable
internal abstract class PathFilter
{
- public abstract IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch);
+ public abstract IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings);
- protected static JToken GetTokenIndex(JToken t, bool errorWhenNoMatch, int index)
+ protected static JToken? GetTokenIndex(JToken t, JsonSelectSettings? settings, int index)
{
-
if (t is JArray a)
{
if (a.Count <= index)
{
- if (errorWhenNoMatch)
+ if (settings?.ErrorWhenNoMatch ?? false)
{
throw new JsonException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index));
}
@@ -29,7 +29,7 @@ protected static JToken GetTokenIndex(JToken t, bool errorWhenNoMatch, int index
{
if (c.Count <= index)
{
- if (errorWhenNoMatch)
+ if (settings?.ErrorWhenNoMatch ?? false)
{
throw new JsonException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index));
}
@@ -41,7 +41,7 @@ protected static JToken GetTokenIndex(JToken t, bool errorWhenNoMatch, int index
}
else
{
- if (errorWhenNoMatch)
+ if (settings?.ErrorWhenNoMatch ?? false)
{
throw new JsonException("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, t.GetType().Name));
}
@@ -50,7 +50,7 @@ protected static JToken GetTokenIndex(JToken t, bool errorWhenNoMatch, int index
}
}
- protected static JToken GetNextScanValue(JToken originalParent, JToken container, JToken value)
+ protected static JToken? GetNextScanValue(JToken originalParent, JToken? container, JToken? value)
{
// step into container's values
if (container != null && container.HasValues)
@@ -60,7 +60,7 @@ protected static JToken GetNextScanValue(JToken originalParent, JToken container
else
{
// finished container, move to parent
- while (value != null && value != originalParent && value == value.Parent.Last)
+ while (value != null && value != originalParent && value == value.Parent!.Last)
{
value = value.Parent;
}
@@ -78,4 +78,5 @@ protected static JToken GetNextScanValue(JToken originalParent, JToken container
return value;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryExpression.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryExpression.cs
index 5d0c1f0cad..1cbbb82229 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryExpression.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryExpression.cs
@@ -13,6 +13,7 @@
namespace Microsoft.IdentityModel.Json.Linq.JsonPath
{
+#nullable enable
internal enum QueryOperator
{
None = 0,
@@ -32,28 +33,39 @@ internal enum QueryOperator
internal abstract class QueryExpression
{
- public QueryOperator Operator { get; set; }
+ internal QueryOperator Operator;
- public abstract bool IsMatch(JToken root, JToken t);
+ public QueryExpression(QueryOperator @operator)
+ {
+ Operator = @operator;
+ }
+
+ // For unit tests
+ public bool IsMatch(JToken root, JToken t)
+ {
+ return IsMatch(root, t, null);
+ }
+
+ public abstract bool IsMatch(JToken root, JToken t, JsonSelectSettings? settings);
}
internal class CompositeExpression : QueryExpression
{
public List Expressions { get; set; }
- public CompositeExpression()
+ public CompositeExpression(QueryOperator @operator) : base(@operator)
{
Expressions = new List();
}
- public override bool IsMatch(JToken root, JToken t)
+ public override bool IsMatch(JToken root, JToken t, JsonSelectSettings? settings)
{
switch (Operator)
{
case QueryOperator.And:
foreach (QueryExpression e in Expressions)
{
- if (!e.IsMatch(root, t))
+ if (!e.IsMatch(root, t, settings))
{
return false;
}
@@ -62,7 +74,7 @@ public override bool IsMatch(JToken root, JToken t)
case QueryOperator.Or:
foreach (QueryExpression e in Expressions)
{
- if (e.IsMatch(root, t))
+ if (e.IsMatch(root, t, settings))
{
return true;
}
@@ -76,10 +88,16 @@ public override bool IsMatch(JToken root, JToken t)
internal class BooleanQueryExpression : QueryExpression
{
- public object Left { get; set; }
- public object Right { get; set; }
+ public readonly object Left;
+ public readonly object? Right;
- private IEnumerable GetResult(JToken root, JToken t, object o)
+ public BooleanQueryExpression(QueryOperator @operator, object left, object? right) : base(@operator)
+ {
+ Left = left;
+ Right = right;
+ }
+
+ private IEnumerable GetResult(JToken root, JToken t, object? o)
{
if (o is JToken resultToken)
{
@@ -88,13 +106,13 @@ private IEnumerable GetResult(JToken root, JToken t, object o)
if (o is List pathFilters)
{
- return JPath.Evaluate(pathFilters, root, t, false);
+ return JPath.Evaluate(pathFilters, root, t, null);
}
return CollectionUtils.ArrayEmpty();
}
- public override bool IsMatch(JToken root, JToken t)
+ public override bool IsMatch(JToken root, JToken t, JsonSelectSettings? settings)
{
if (Operator == QueryOperator.Exists)
{
@@ -113,7 +131,7 @@ public override bool IsMatch(JToken root, JToken t)
JToken leftResult = leftResults.Current;
foreach (JToken rightResult in rightResults)
{
- if (MatchTokens(leftResult, rightResult))
+ if (MatchTokens(leftResult, rightResult, settings))
{
return true;
}
@@ -125,14 +143,14 @@ public override bool IsMatch(JToken root, JToken t)
return false;
}
- private bool MatchTokens(JToken leftResult, JToken rightResult)
+ private bool MatchTokens(JToken leftResult, JToken rightResult, JsonSelectSettings? settings)
{
if (leftResult is JValue leftValue && rightResult is JValue rightValue)
{
switch (Operator)
{
case QueryOperator.RegexEquals:
- if (RegexEquals(leftValue, rightValue))
+ if (RegexEquals(leftValue, rightValue, settings))
{
return true;
}
@@ -204,20 +222,25 @@ private bool MatchTokens(JToken leftResult, JToken rightResult)
return false;
}
- private static bool RegexEquals(JValue input, JValue pattern)
+ private static bool RegexEquals(JValue input, JValue pattern, JsonSelectSettings? settings)
{
if (input.Type != JTokenType.String || pattern.Type != JTokenType.String)
{
return false;
}
- string regexText = (string)pattern.Value;
+ string regexText = (string)pattern.Value!;
int patternOptionDelimiterIndex = regexText.LastIndexOf('/');
string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1);
string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1);
- return Regex.IsMatch((string)input.Value, patternText, MiscellaneousUtils.GetRegexOptions(optionsText));
+#if HAVE_REGEX_TIMEOUTS
+ TimeSpan timeout = settings?.RegexMatchTimeout ?? Regex.InfiniteMatchTimeout;
+ return Regex.IsMatch((string)input.Value!, patternText, MiscellaneousUtils.GetRegexOptions(optionsText), timeout);
+#else
+ return Regex.IsMatch((string)input.Value!, patternText, MiscellaneousUtils.GetRegexOptions(optionsText));
+#endif
}
internal static bool EqualsWithStringCoercion(JValue value, JValue queryValue)
@@ -240,7 +263,7 @@ internal static bool EqualsWithStringCoercion(JValue value, JValue queryValue)
return false;
}
- string queryValueString = (string)queryValue.Value;
+ string queryValueString = (string)queryValue.Value!;
string currentValueString;
@@ -258,21 +281,21 @@ internal static bool EqualsWithStringCoercion(JValue value, JValue queryValue)
else
#endif
{
- DateTimeUtils.WriteDateTimeString(writer, (DateTime)value.Value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
+ DateTimeUtils.WriteDateTimeString(writer, (DateTime)value.Value!, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
}
currentValueString = writer.ToString();
}
break;
case JTokenType.Bytes:
- currentValueString = Convert.ToBase64String((byte[])value.Value);
+ currentValueString = Convert.ToBase64String((byte[])value.Value!);
break;
case JTokenType.Guid:
case JTokenType.TimeSpan:
- currentValueString = value.Value.ToString();
+ currentValueString = value.Value!.ToString()!;
break;
case JTokenType.Uri:
- currentValueString = ((Uri)value.Value).OriginalString;
+ currentValueString = ((Uri)value.Value!).OriginalString;
break;
default:
return false;
@@ -283,8 +306,8 @@ internal static bool EqualsWithStringCoercion(JValue value, JValue queryValue)
internal static bool EqualsWithStrictMatch(JValue value, JValue queryValue)
{
- Debug.Assert(value != null);
- Debug.Assert(queryValue != null);
+ MiscellaneousUtils.Assert(value != null);
+ MiscellaneousUtils.Assert(queryValue != null);
// Handle comparing an integer with a float
// e.g. Comparing 1 and 1.0
@@ -303,4 +326,5 @@ internal static bool EqualsWithStrictMatch(JValue value, JValue queryValue)
return value.Equals(queryValue);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryFilter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryFilter.cs
index cf7ae0136c..a03d8bf11b 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryFilter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/QueryFilter.cs
@@ -3,17 +3,23 @@
namespace Microsoft.IdentityModel.Json.Linq.JsonPath
{
+#nullable enable
internal class QueryFilter : PathFilter
{
- public QueryExpression Expression { get; set; }
+ internal QueryExpression Expression;
- public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public QueryFilter(QueryExpression expression)
+ {
+ Expression = expression;
+ }
+
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken t in current)
{
foreach (JToken v in t)
{
- if (Expression.IsMatch(root, v))
+ if (Expression.IsMatch(root, v, settings))
{
yield return v;
}
@@ -21,4 +27,5 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public QueryScanFilter(QueryExpression expression)
+ {
+ Expression = expression;
+ }
+
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken t in current)
{
@@ -15,7 +21,7 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
return new[] { root };
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ScanFilter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ScanFilter.cs
index eeefc2c6aa..edf4c4879c 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ScanFilter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/JsonPath/ScanFilter.cs
@@ -2,11 +2,17 @@
namespace Microsoft.IdentityModel.Json.Linq.JsonPath
{
+#nullable enable
internal class ScanFilter : PathFilter
{
- public string Name { get; set; }
+ internal string? Name;
- public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public ScanFilter(string? name)
+ {
+ Name = name;
+ }
+
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken c in current)
{
@@ -15,11 +21,11 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable Names { get; set; }
+ private List _names;
- public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, bool errorWhenNoMatch)
+ public ScanMultipleFilter(List names)
+ {
+ _names = names;
+ }
+
+ public override IEnumerable ExecuteFilter(JToken root, IEnumerable current, JsonSelectSettings? settings)
{
foreach (JToken c in current)
{
- JToken value = c;
+ JToken? value = c;
while (true)
{
- JContainer container = value as JContainer;
+ JContainer? container = value as JContainer;
value = GetNextScanValue(c, container, value);
if (value == null)
@@ -24,7 +30,7 @@ public override IEnumerable ExecuteFilter(JToken root, IEnumerable ExecuteFilter(JToken root, IEnumerable
+ /// Specifies the settings used when selecting JSON.
+ ///
+ internal class JsonSelectSettings
+ {
+#if HAVE_REGEX_TIMEOUTS
+ ///
+ /// Gets or sets a timeout that will be used when executing regular expressions.
+ ///
+ /// The timeout that will be used when executing regular expressions.
+ public TimeSpan? RegexMatchTimeout { get; set; }
+#endif
+
+ ///
+ /// Gets or sets a flag that indicates whether an error should be thrown if
+ /// no tokens are found when evaluating part of the expression.
+ ///
+ ///
+ /// A flag that indicates whether an error should be thrown if
+ /// no tokens are found when evaluating part of the expression.
+ ///
+ public bool ErrorWhenNoMatch { get; set; }
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/LineInfoHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/LineInfoHandling.cs
index 80e045aef6..cf895f0f5c 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/LineInfoHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/LineInfoHandling.cs
@@ -40,4 +40,4 @@ internal enum LineInfoHandling
///
Load = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeArrayHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeArrayHandling.cs
index cde4ac9fee..cb642100a0 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeArrayHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeArrayHandling.cs
@@ -17,4 +17,4 @@ internal enum MergeArrayHandling
/// Merge array items together, matched by index.
Merge = 3
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeNullValueHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeNullValueHandling.cs
index de1ca2c55b..096e60007f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeNullValueHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Linq/MergeNullValueHandling.cs
@@ -8,12 +8,10 @@ namespace Microsoft.IdentityModel.Json.Linq
[Flags]
internal enum MergeNullValueHandling
{
-#pragma warning disable CA1008 // Enums should have zero value
- ///
- /// The content's null value properties will be ignored during merging.
- ///
+ ///
+ /// The content's null value properties will be ignored during merging.
+ ///
Ignore = 0,
-#pragma warning restore CA1008 // Enums should have zero value
///
/// The content's null value properties will be merged.
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/MetadataPropertyHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/MetadataPropertyHandling.cs
index 7c33fd45d3..3b9449ec7a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/MetadataPropertyHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/MetadataPropertyHandling.cs
@@ -49,4 +49,4 @@ internal enum MetadataPropertyHandling
///
Ignore = 2
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/MissingMemberHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/MissingMemberHandling.cs
index 358ff4618d..a7aff0c596 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/MissingMemberHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/MissingMemberHandling.cs
@@ -44,4 +44,4 @@ internal enum MissingMemberHandling
///
Error = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/NullValueHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/NullValueHandling.cs
index 640dcb4fe6..9b4684b179 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/NullValueHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/NullValueHandling.cs
@@ -44,4 +44,4 @@ internal enum NullValueHandling
///
Ignore = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/ObjectCreationHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/ObjectCreationHandling.cs
index c01a4edb98..764eddb649 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/ObjectCreationHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/ObjectCreationHandling.cs
@@ -45,4 +45,4 @@ internal enum ObjectCreationHandling
///
Replace = 2
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/PreserveReferencesHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/PreserveReferencesHandling.cs
index 132bee45b0..6bc7584676 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/PreserveReferencesHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/PreserveReferencesHandling.cs
@@ -34,7 +34,7 @@ namespace Microsoft.IdentityModel.Json
/// Note that references cannot be preserved when a value is set via a non-default constructor such as types that implement .
///
///
- ///
+ ///
///
[Flags]
internal enum PreserveReferencesHandling
@@ -59,4 +59,4 @@ internal enum PreserveReferencesHandling
///
All = Objects | Arrays
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/ReferenceLoopHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/ReferenceLoopHandling.cs
index b7e0c5bf3d..a032a3bec8 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/ReferenceLoopHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/ReferenceLoopHandling.cs
@@ -49,4 +49,4 @@ internal enum ReferenceLoopHandling
///
Serialize = 2
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Required.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Required.cs
index 933f1470fc..f293cab186 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Required.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Required.cs
@@ -50,4 +50,4 @@ internal enum Required
///
DisallowNull = 3
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/Extensions.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/Extensions.cs
index f86e2aa711..f724f1ff35 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/Extensions.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/Extensions.cs
@@ -28,6 +28,8 @@
using Microsoft.IdentityModel.Json.Linq;
using Microsoft.IdentityModel.Json.Utilities;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -134,4 +136,4 @@ public static void Validate(this JToken source, JsonSchema schema, ValidationEve
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchema.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchema.cs
index b86c54f66d..b8917101a4 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchema.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchema.cs
@@ -30,8 +30,10 @@
using Microsoft.IdentityModel.Json.Utilities;
using System.Globalization;
+
namespace Microsoft.IdentityModel.Json.Schema
{
+#nullable disable
///
///
/// An in-memory representation of a JSON Schema.
@@ -241,9 +243,7 @@ internal class JsonSchema
internal string Location { get; set; }
-#pragma warning disable CA1305 // Specify IFormatProvider
private readonly string _internalId = Guid.NewGuid().ToString("N");
-#pragma warning restore CA1305 // Specify IFormatProvider
internal string InternalId => _internalId;
@@ -352,4 +352,4 @@ public override string ToString()
return writer.ToString();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaBuilder.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaBuilder.cs
index cd862a1feb..c296ec0249 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaBuilder.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaBuilder.cs
@@ -35,6 +35,8 @@
using Microsoft.IdentityModel.Json.Utilities;
using Microsoft.IdentityModel.Json.Linq;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
@@ -87,7 +89,10 @@ internal JsonSchema Read(JsonReader reader)
private string UnescapeReference(string reference)
{
- return Uri.UnescapeDataString(reference).Replace("~1", "/").Replace("~0", "~");
+ string unescapedReference = Uri.UnescapeDataString(reference);
+ unescapedReference = StringUtils.Replace(unescapedReference, "~1", "/");
+ unescapedReference = StringUtils.Replace(unescapedReference, "~0", "~");
+ return unescapedReference;
}
private JsonSchema ResolveReferences(JsonSchema schema)
@@ -218,8 +223,12 @@ private JsonSchema BuildSchema(JToken token)
return deferredSchema;
}
- string location = token.Path.Replace(".", "/").Replace("[", "/").Replace("]", string.Empty);
- if (!string.IsNullOrEmpty(location))
+ string location = token.Path;
+ location = StringUtils.Replace(location, ".", "/");
+ location = StringUtils.Replace(location, "[", "/");
+ location = StringUtils.Replace(location, "]", string.Empty);
+
+ if (!StringUtils.IsNullOrEmpty(location))
{
location = "/" + location;
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaConstants.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaConstants.cs
index f980d5074e..131078095a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaConstants.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaConstants.cs
@@ -26,6 +26,8 @@
using System;
using System.Collections.Generic;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaException.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaException.cs
index 7338c10e18..6d92dbdc49 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaException.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaException.cs
@@ -26,6 +26,7 @@
using System;
using System.Runtime.Serialization;
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -110,4 +111,4 @@ internal JsonSchemaException(string message, Exception innerException, string pa
LinePosition = linePosition;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaGenerator.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaGenerator.cs
index 1f3a2ff83a..8758bf2d52 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaGenerator.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaGenerator.cs
@@ -37,6 +37,8 @@
#endif
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -173,7 +175,7 @@ private string GetTitle(Type type)
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetCachedAttribute(type);
- if (!string.IsNullOrEmpty(containerAttribute?.Title))
+ if (!StringUtils.IsNullOrEmpty(containerAttribute?.Title))
{
return containerAttribute.Title;
}
@@ -185,7 +187,7 @@ private string GetDescription(Type type)
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetCachedAttribute(type);
- if (!string.IsNullOrEmpty(containerAttribute?.Description))
+ if (!StringUtils.IsNullOrEmpty(containerAttribute?.Description))
{
return containerAttribute.Description;
}
@@ -202,7 +204,7 @@ private string GetTypeId(Type type, bool explicitOnly)
{
JsonContainerAttribute containerAttribute = JsonTypeReflector.GetCachedAttribute(type);
- if (!string.IsNullOrEmpty(containerAttribute?.Id))
+ if (!StringUtils.IsNullOrEmpty(containerAttribute?.Id))
{
return containerAttribute.Id;
}
@@ -230,7 +232,7 @@ private JsonSchema GenerateInternal(Type type, Required valueRequired, bool requ
string resolvedId = GetTypeId(type, false);
string explicitId = GetTypeId(type, true);
- if (!string.IsNullOrEmpty(resolvedId))
+ if (!StringUtils.IsNullOrEmpty(resolvedId))
{
JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
if (resolvedSchema != null)
@@ -499,4 +501,4 @@ private JsonSchemaType GetJsonSchemaType(Type type, Required valueRequired)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModel.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModel.cs
index 6c6835e7b5..ef99ac232a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModel.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModel.cs
@@ -28,6 +28,8 @@
using Microsoft.IdentityModel.Json.Linq;
using Microsoft.IdentityModel.Json.Utilities;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
@@ -122,4 +124,4 @@ private static void Combine(JsonSchemaModel model, JsonSchema schema)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModelBuilder.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModelBuilder.cs
index dfdc9feac9..7cddf8a57c 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModelBuilder.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaModelBuilder.cs
@@ -32,6 +32,8 @@
#endif
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNode.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNode.cs
index 717553e0b1..f9012b914e 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNode.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNode.cs
@@ -33,6 +33,8 @@
#endif
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNodeCollection.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNodeCollection.cs
index 5b9ad8754b..f15a78e73e 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNodeCollection.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaNodeCollection.cs
@@ -26,6 +26,8 @@
using System;
using System.Collections.ObjectModel;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaResolver.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaResolver.cs
index 6b8d22935b..01a5524132 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaResolver.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaResolver.cs
@@ -32,6 +32,8 @@
#endif
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -76,4 +78,4 @@ public virtual JsonSchema GetSchema(string reference)
return schema;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaType.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaType.cs
index bb49312eeb..23b07bd958 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaType.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaType.cs
@@ -25,6 +25,7 @@
using System;
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -84,4 +85,4 @@ internal enum JsonSchemaType
///
Any = String | Float | Integer | Boolean | Object | Array | Null
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaWriter.cs
index 30193874ce..d44174f5e8 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/JsonSchemaWriter.cs
@@ -35,6 +35,8 @@
#endif
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/UndefinedSchemaIdHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/UndefinedSchemaIdHandling.cs
index c685eb50c6..d9ca4a57ff 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/UndefinedSchemaIdHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/UndefinedSchemaIdHandling.cs
@@ -25,6 +25,8 @@
using System;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -53,4 +55,4 @@ internal enum UndefinedSchemaIdHandling
///
UseAssemblyQualifiedName = 2,
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventArgs.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventArgs.cs
index da4e90345d..2e54596202 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventArgs.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventArgs.cs
@@ -26,6 +26,8 @@
using System;
using Microsoft.IdentityModel.Json.Utilities;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -65,4 +67,4 @@ internal ValidationEventArgs(JsonSchemaException ex)
/// The text description.
public string Message => _ex.Message;
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventHandler.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventHandler.cs
index 96fdf6f96f..4ff9c7ace0 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventHandler.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Schema/ValidationEventHandler.cs
@@ -25,6 +25,8 @@
using System;
+#nullable disable
+
namespace Microsoft.IdentityModel.Json.Schema
{
///
@@ -37,4 +39,4 @@ namespace Microsoft.IdentityModel.Json.Schema
///
[Obsolete("JSON Schema validation has been moved to its own package. See https://www.newtonsoft.com/jsonschema for more details.")]
internal delegate void ValidationEventHandler(object sender, ValidationEventArgs e);
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CachedAttributeGetter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CachedAttributeGetter.cs
index 3430f80109..e6d28713dc 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CachedAttributeGetter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CachedAttributeGetter.cs
@@ -29,13 +29,15 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal static class CachedAttributeGetter where T : Attribute
{
- private static readonly ThreadSafeStore TypeAttributeCache = new ThreadSafeStore(JsonTypeReflector.GetAttribute);
+ private static readonly ThreadSafeStore TypeAttributeCache = new ThreadSafeStore(JsonTypeReflector.GetAttribute);
- public static T GetAttribute(object type)
+ public static T? GetAttribute(object type)
{
return TypeAttributeCache.Get(type);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCaseNamingStrategy.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCaseNamingStrategy.cs
index 937b79475c..7e1c37f31c 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCaseNamingStrategy.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCaseNamingStrategy.cs
@@ -84,4 +84,4 @@ protected override string ResolvePropertyName(string name)
return StringUtils.ToCamelCase(name);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCasePropertyNamesContractResolver.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCasePropertyNamesContractResolver.cs
index 147ad06556..4142165c4f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCasePropertyNamesContractResolver.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/CamelCasePropertyNamesContractResolver.cs
@@ -30,6 +30,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Resolves member mappings for a type, camel casing property names.
///
@@ -37,7 +38,7 @@ internal class CamelCasePropertyNamesContractResolver : DefaultContractResolver
{
private static readonly object TypeContractCacheLock = new object();
private static readonly DefaultJsonNameTable NameTable = new DefaultJsonNameTable();
- private static Dictionary, JsonContract> _contractCache;
+ private static Dictionary, JsonContract>? _contractCache;
///
/// Initializes a new instance of the class.
@@ -65,8 +66,8 @@ public override JsonContract ResolveContract(Type type)
// for backwards compadibility the CamelCasePropertyNamesContractResolver shares contracts between instances
StructMultiKey key = new StructMultiKey(GetType(), type);
- Dictionary, JsonContract> cache = _contractCache;
- if (cache == null || !cache.TryGetValue(key, out JsonContract contract))
+ Dictionary, JsonContract>? cache = _contractCache;
+ if (cache == null || !cache.TryGetValue(key, out JsonContract? contract))
{
contract = CreateContract(type);
@@ -91,4 +92,5 @@ internal override DefaultJsonNameTable GetNameTable()
return NameTable;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultContractResolver.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultContractResolver.cs
index 6043d096e9..7fefdb40b6 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultContractResolver.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultContractResolver.cs
@@ -55,6 +55,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Used by to resolve a for a given .
///
@@ -168,7 +169,7 @@ internal class DefaultContractResolver : IContractResolver
/// Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized.
///
/// The naming strategy used to resolve how property names and dictionary keys are serialized.
- public NamingStrategy NamingStrategy { get; set; }
+ public NamingStrategy? NamingStrategy { get; set; }
///
/// Initializes a new instance of the class.
@@ -198,6 +199,25 @@ public virtual JsonContract ResolveContract(Type type)
return _contractCache.Get(type);
}
+ private static bool FilterMembers(MemberInfo member)
+ {
+ if (member is PropertyInfo property)
+ {
+ if (ReflectionUtils.IsIndexedProperty(property))
+ {
+ return false;
+ }
+
+ return !ReflectionUtils.IsByRefLikeType(property.PropertyType);
+ }
+ else if (member is FieldInfo field)
+ {
+ return !ReflectionUtils.IsByRefLikeType(field.FieldType);
+ }
+
+ return true;
+ }
+
///
/// Gets the serializable members for the type.
///
@@ -214,20 +234,23 @@ protected virtual List GetSerializableMembers(Type objectType)
MemberSerialization memberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType, ignoreSerializableAttribute);
+ // Exclude index properties
+ // Do not filter ByRef types here because accessing FieldType/PropertyType can trigger additonal assembly loads
IEnumerable allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
- .Where(m => !ReflectionUtils.IsIndexedProperty(m));
+ .Where(m => m is PropertyInfo p ? !ReflectionUtils.IsIndexedProperty(p) : true);
List serializableMembers = new List();
if (memberSerialization != MemberSerialization.Fields)
{
#if HAVE_DATA_CONTRACTS
- DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType);
+ DataContractAttribute? dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType);
#endif
#pragma warning disable 618
+ // Exclude index properties and ByRef types
List defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags)
- .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();
+ .Where(FilterMembers).ToList();
#pragma warning restore 618
foreach (MemberInfo member in allMembers)
@@ -330,17 +353,18 @@ protected virtual JsonObjectContract CreateObjectContract(Type objectType)
contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(contract.NonNullableUnderlyingType, ignoreSerializableAttribute);
contract.Properties.AddRange(CreateProperties(contract.NonNullableUnderlyingType, contract.MemberSerialization));
- Func extensionDataNameResolver = null;
+ Func? extensionDataNameResolver = null;
- JsonObjectAttribute attribute = JsonTypeReflector.GetCachedAttribute(contract.NonNullableUnderlyingType);
+ JsonObjectAttribute? attribute = JsonTypeReflector.GetCachedAttribute(contract.NonNullableUnderlyingType);
if (attribute != null)
{
contract.ItemRequired = attribute._itemRequired;
contract.ItemNullValueHandling = attribute._itemNullValueHandling;
+ contract.MissingMemberHandling = attribute._missingMemberHandling;
if (attribute.NamingStrategyType != null)
{
- NamingStrategy namingStrategy = JsonTypeReflector.GetContainerNamingStrategy(attribute);
+ NamingStrategy namingStrategy = JsonTypeReflector.GetContainerNamingStrategy(attribute)!;
extensionDataNameResolver = s => namingStrategy.GetDictionaryKey(s);
}
}
@@ -354,7 +378,7 @@ protected virtual JsonObjectContract CreateObjectContract(Type objectType)
if (contract.IsInstantiable)
{
- ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
+ ConstructorInfo? overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
// check if a JsonConstructorAttribute has been defined and use that
if (overrideConstructor != null)
@@ -375,7 +399,7 @@ protected virtual JsonObjectContract CreateObjectContract(Type objectType)
}
else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
{
- ConstructorInfo constructor = GetParameterizedConstructor(contract.NonNullableUnderlyingType);
+ ConstructorInfo? constructor = GetParameterizedConstructor(contract.NonNullableUnderlyingType);
if (constructor != null)
{
contract.ParameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(constructor);
@@ -386,7 +410,7 @@ protected virtual JsonObjectContract CreateObjectContract(Type objectType)
{
// value types always have default constructor
// check whether there is a constructor that matches with non-writable properties on value type
- ConstructorInfo constructor = GetImmutableConstructor(contract.NonNullableUnderlyingType, contract.Properties);
+ ConstructorInfo? constructor = GetImmutableConstructor(contract.NonNullableUnderlyingType, contract.Properties);
if (constructor != null)
{
contract.OverrideCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(constructor);
@@ -395,14 +419,14 @@ protected virtual JsonObjectContract CreateObjectContract(Type objectType)
}
}
- MemberInfo extensionDataMember = GetExtensionDataMemberForType(contract.NonNullableUnderlyingType);
+ MemberInfo? extensionDataMember = GetExtensionDataMemberForType(contract.NonNullableUnderlyingType);
if (extensionDataMember != null)
{
SetExtensionDataDelegates(contract, extensionDataMember);
}
// serializing DirectoryInfo without ISerializable will stackoverflow
- // https://github.com/JamesNK/Microsoft.IdentityModel.Json/issues/1541
+ // https://github.com/JamesNK/Newtonsoft.Json/issues/1541
if (Array.IndexOf(BlacklistedTypeNames, objectType.FullName) != -1)
{
contract.OnSerializingCallbacks.Add(ThrowUnableToSerializeError);
@@ -416,7 +440,7 @@ private static void ThrowUnableToSerializeError(object o, StreamingContext conte
throw new JsonSerializationException("Unable to serialize instance of '{0}'.".FormatWith(CultureInfo.InvariantCulture, o.GetType()));
}
- private MemberInfo GetExtensionDataMemberForType(Type type)
+ private MemberInfo? GetExtensionDataMemberForType(Type type)
{
IEnumerable members = GetClassHierarchyForType(type).SelectMany(baseType =>
{
@@ -427,7 +451,7 @@ private MemberInfo GetExtensionDataMemberForType(Type type)
return m;
});
- MemberInfo extensionDataMember = members.LastOrDefault(m =>
+ MemberInfo? extensionDataMember = members.LastOrDefault(m =>
{
MemberTypes memberType = m.MemberType();
if (memberType != MemberTypes.Property && memberType != MemberTypes.Field)
@@ -443,12 +467,12 @@ private MemberInfo GetExtensionDataMemberForType(Type type)
if (!ReflectionUtils.CanReadMemberValue(m, true))
{
- throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' must have a getter.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType), m.Name));
+ throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' must have a getter.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType!), m.Name));
}
Type t = ReflectionUtils.GetMemberUnderlyingType(m);
- if (ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out Type dictionaryType))
+ if (ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out Type? dictionaryType))
{
Type keyType = dictionaryType.GetGenericArguments()[0];
Type valueType = dictionaryType.GetGenericArguments()[1];
@@ -459,7 +483,7 @@ private MemberInfo GetExtensionDataMemberForType(Type type)
}
}
- throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' type must implement IDictionary.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType), m.Name));
+ throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' type must implement IDictionary.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType!), m.Name));
});
return extensionDataMember;
@@ -467,7 +491,7 @@ private MemberInfo GetExtensionDataMemberForType(Type type)
private static void SetExtensionDataDelegates(JsonObjectContract contract, MemberInfo member)
{
- JsonExtensionDataAttribute extensionDataAttribute = ReflectionUtils.GetAttribute(member);
+ JsonExtensionDataAttribute? extensionDataAttribute = ReflectionUtils.GetAttribute(member);
if (extensionDataAttribute == null)
{
return;
@@ -475,10 +499,10 @@ private static void SetExtensionDataDelegates(JsonObjectContract contract, Membe
Type t = ReflectionUtils.GetMemberUnderlyingType(member);
- ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out Type dictionaryType);
+ ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out Type? dictionaryType);
- Type keyType = dictionaryType.GetGenericArguments()[0];
- Type valueType = dictionaryType.GetGenericArguments()[1];
+ Type keyType = dictionaryType!.GetGenericArguments()[0];
+ Type valueType = dictionaryType!.GetGenericArguments()[1];
Type createdType;
@@ -492,27 +516,27 @@ private static void SetExtensionDataDelegates(JsonObjectContract contract, Membe
createdType = t;
}
- Func getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(member);
+ Func getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(member);
if (extensionDataAttribute.ReadData)
{
- Action setExtensionDataDictionary = (ReflectionUtils.CanSetMemberValue(member, true, false))
+ Action? setExtensionDataDictionary = (ReflectionUtils.CanSetMemberValue(member, true, false))
? JsonTypeReflector.ReflectionDelegateFactory.CreateSet(member)
: null;
Func createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(createdType);
- MethodInfo setMethod = t.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, valueType, new[] { keyType }, null)?.GetSetMethod();
+ MethodInfo? setMethod = t.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, valueType, new[] { keyType }, null)?.GetSetMethod();
if (setMethod == null)
{
// Item is explicitly implemented and non-public
// get from dictionary interface
- setMethod = dictionaryType.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, valueType, new[] { keyType }, null)?.GetSetMethod();
+ setMethod = dictionaryType!.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, valueType, new[] { keyType }, null)?.GetSetMethod();
}
- MethodCall setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(setMethod);
+ MethodCall setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(setMethod!);
ExtensionDataSetter extensionDataSetter = (o, key, value) =>
{
- object dictionary = getExtensionDataDictionary(o);
+ object? dictionary = getExtensionDataDictionary(o);
if (dictionary == null)
{
if (setExtensionDataDictionary == null)
@@ -538,7 +562,7 @@ private static void SetExtensionDataDelegates(JsonObjectContract contract, Membe
ExtensionDataGetter extensionDataGetter = o =>
{
- object dictionary = getExtensionDataDictionary(o);
+ object? dictionary = getExtensionDataDictionary(o);
if (dictionary == null)
{
return null;
@@ -569,7 +593,7 @@ public IEnumerator> GetEnumerator()
{
foreach (KeyValuePair item in _e)
{
- yield return new KeyValuePair(item.Key, item.Value);
+ yield return new KeyValuePair(item.Key!, item.Value!);
}
}
@@ -579,7 +603,7 @@ IEnumerator IEnumerable.GetEnumerator()
}
}
- private ConstructorInfo GetAttributeConstructor(Type objectType)
+ private ConstructorInfo? GetAttributeConstructor(Type objectType)
{
IEnumerator en = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(c => c.IsDefined(typeof(JsonConstructorAttribute), true)).GetEnumerator();
@@ -603,7 +627,7 @@ private ConstructorInfo GetAttributeConstructor(Type objectType)
return null;
}
- private ConstructorInfo GetImmutableConstructor(Type objectType, JsonPropertyCollection memberProperties)
+ private ConstructorInfo? GetImmutableConstructor(Type objectType, JsonPropertyCollection memberProperties)
{
IEnumerable constructors = objectType.GetConstructors();
IEnumerator en = constructors.GetEnumerator();
@@ -617,7 +641,7 @@ private ConstructorInfo GetImmutableConstructor(Type objectType, JsonPropertyCol
{
foreach (ParameterInfo parameterInfo in parameters)
{
- JsonProperty memberProperty = MatchProperty(memberProperties, parameterInfo.Name, parameterInfo.ParameterType);
+ JsonProperty? memberProperty = MatchProperty(memberProperties, parameterInfo.Name!, parameterInfo.ParameterType);
if (memberProperty == null || memberProperty.Writable)
{
return null;
@@ -632,7 +656,7 @@ private ConstructorInfo GetImmutableConstructor(Type objectType, JsonPropertyCol
return null;
}
- private ConstructorInfo GetParameterizedConstructor(Type objectType)
+ private ConstructorInfo? GetParameterizedConstructor(Type objectType)
{
#if PORTABLE
IEnumerable constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
@@ -665,11 +689,16 @@ protected virtual IList CreateConstructorParameters(ConstructorInf
{
ParameterInfo[] constructorParameters = constructor.GetParameters();
- JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType);
+ JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType!);
foreach (ParameterInfo parameterInfo in constructorParameters)
{
- JsonProperty matchingMemberProperty = MatchProperty(memberProperties, parameterInfo.Name, parameterInfo.ParameterType);
+ if (parameterInfo.Name == null)
+ {
+ continue;
+ }
+
+ JsonProperty? matchingMemberProperty = MatchProperty(memberProperties, parameterInfo.Name, parameterInfo.ParameterType);
// ensure that property will have a name from matching property or from parameterinfo
// parameterinfo could have no name if generated by a proxy (I'm looking at you Castle)
@@ -687,7 +716,7 @@ protected virtual IList CreateConstructorParameters(ConstructorInf
return parameterCollection;
}
- private JsonProperty MatchProperty(JsonPropertyCollection properties, string name, Type type)
+ private JsonProperty? MatchProperty(JsonPropertyCollection properties, string name, Type type)
{
// it is possible to generate a member with a null name using Reflection.Emit
// protect against an ArgumentNullException from GetClosestMatchProperty by testing for null here
@@ -696,7 +725,7 @@ private JsonProperty MatchProperty(JsonPropertyCollection properties, string nam
return null;
}
- JsonProperty property = properties.GetClosestMatchProperty(name);
+ JsonProperty? property = properties.GetClosestMatchProperty(name);
// must match type as well as name
if (property == null || property.PropertyType != type)
{
@@ -712,13 +741,13 @@ private JsonProperty MatchProperty(JsonPropertyCollection properties, string nam
/// The matching member property.
/// The constructor parameter.
/// A created for the given .
- protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo)
+ protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty? matchingMemberProperty, ParameterInfo parameterInfo)
{
JsonProperty property = new JsonProperty();
property.PropertyType = parameterInfo.ParameterType;
property.AttributeProvider = new ReflectionAttributeProvider(parameterInfo);
- SetPropertySettingsFromAttributes(property, parameterInfo, parameterInfo.Name, parameterInfo.Member.DeclaringType, MemberSerialization.OptOut, out _);
+ SetPropertySettingsFromAttributes(property, parameterInfo, parameterInfo.Name!, parameterInfo.Member.DeclaringType!, MemberSerialization.OptOut, out _);
property.Readable = false;
property.Writable = true;
@@ -751,7 +780,7 @@ protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProper
///
/// Type of the object.
/// The contract's default .
- protected virtual JsonConverter ResolveContractConverter(Type objectType)
+ protected virtual JsonConverter? ResolveContractConverter(Type objectType)
{
return JsonTypeReflector.GetJsonConverter(objectType);
}
@@ -766,7 +795,7 @@ private Func GetDefaultCreator(Type createdType)
#endif
private void InitializeContract(JsonContract contract)
{
- JsonContainerAttribute containerAttribute = JsonTypeReflector.GetCachedAttribute(contract.NonNullableUnderlyingType);
+ JsonContainerAttribute? containerAttribute = JsonTypeReflector.GetCachedAttribute(contract.NonNullableUnderlyingType);
if (containerAttribute != null)
{
contract.IsReference = containerAttribute._isReference;
@@ -774,7 +803,7 @@ private void InitializeContract(JsonContract contract)
#if HAVE_DATA_CONTRACTS
else
{
- DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.NonNullableUnderlyingType);
+ DataContractAttribute? dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.NonNullableUnderlyingType);
// doesn't have a null value
if (dataContractAttribute != null && dataContractAttribute.IsReference)
{
@@ -804,11 +833,11 @@ private void ResolveCallbackMethods(JsonContract contract, Type t)
{
GetCallbackMethodsForType(
t,
- out List onSerializing,
- out List onSerialized,
- out List onDeserializing,
- out List onDeserialized,
- out List onError);
+ out List? onSerializing,
+ out List? onSerialized,
+ out List? onDeserializing,
+ out List? onDeserialized,
+ out List? onError);
if (onSerializing != null)
{
@@ -836,7 +865,7 @@ private void ResolveCallbackMethods(JsonContract contract, Type t)
}
}
- private void GetCallbackMethodsForType(Type type, out List onSerializing, out List onSerialized, out List onDeserializing, out List onDeserialized, out List onError)
+ private void GetCallbackMethodsForType(Type type, out List? onSerializing, out List? onSerialized, out List? onDeserializing, out List? onDeserialized, out List? onError)
{
onSerializing = null;
onSerialized = null;
@@ -847,11 +876,11 @@ private void GetCallbackMethodsForType(Type type, out List GetClassHierarchyForType(Type type)
{
List ret = new List();
- Type current = type;
+ Type? current = type;
while (current != null && current != typeof(object))
{
ret.Add(current);
@@ -983,10 +1012,10 @@ protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectTyp
JsonDictionaryContract contract = new JsonDictionaryContract(objectType);
InitializeContract(contract);
- JsonContainerAttribute containerAttribute = JsonTypeReflector.GetAttribute(objectType);
+ JsonContainerAttribute? containerAttribute = JsonTypeReflector.GetAttribute(objectType);
if (containerAttribute?.NamingStrategyType != null)
{
- NamingStrategy namingStrategy = JsonTypeReflector.GetContainerNamingStrategy(containerAttribute);
+ NamingStrategy namingStrategy = JsonTypeReflector.GetContainerNamingStrategy(containerAttribute)!;
contract.DictionaryKeyResolver = s => namingStrategy.GetDictionaryKey(s);
}
else
@@ -994,7 +1023,7 @@ protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectTyp
contract.DictionaryKeyResolver = ResolveDictionaryKey;
}
- ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
+ ConstructorInfo? overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
if (overrideConstructor != null)
{
@@ -1032,7 +1061,7 @@ protected virtual JsonArrayContract CreateArrayContract(Type objectType)
JsonArrayContract contract = new JsonArrayContract(objectType);
InitializeContract(contract);
- ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
+ ConstructorInfo? overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
if (overrideConstructor != null)
{
@@ -1099,7 +1128,7 @@ protected virtual JsonISerializableContract CreateISerializableContract(Type obj
if (contract.IsInstantiable)
{
- ConstructorInfo constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] {typeof(SerializationInfo), typeof(StreamingContext)}, null);
+ ConstructorInfo? constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] {typeof(SerializationInfo), typeof(StreamingContext)}, null);
if (constructorInfo != null)
{
ObjectConstructor creator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(constructorInfo);
@@ -1123,10 +1152,10 @@ protected virtual JsonDynamicContract CreateDynamicContract(Type objectType)
JsonDynamicContract contract = new JsonDynamicContract(objectType);
InitializeContract(contract);
- JsonContainerAttribute containerAttribute = JsonTypeReflector.GetAttribute(objectType);
+ JsonContainerAttribute? containerAttribute = JsonTypeReflector.GetAttribute(objectType);
if (containerAttribute?.NamingStrategyType != null)
{
- NamingStrategy namingStrategy = JsonTypeReflector.GetContainerNamingStrategy(containerAttribute);
+ NamingStrategy namingStrategy = JsonTypeReflector.GetContainerNamingStrategy(containerAttribute)!;
contract.PropertyNameResolver = s => namingStrategy.GetDictionaryKey(s);
}
else
@@ -1168,7 +1197,7 @@ protected virtual JsonContract CreateContract(Type objectType)
}
t = ReflectionUtils.EnsureNotNullableType(t);
- JsonContainerAttribute containerAttribute = JsonTypeReflector.GetCachedAttribute(t);
+ JsonContainerAttribute? containerAttribute = JsonTypeReflector.GetCachedAttribute(t);
if (containerAttribute is JsonObjectAttribute)
{
@@ -1197,7 +1226,7 @@ protected virtual JsonContract CreateContract(Type objectType)
if (typeof(IEnumerable).IsAssignableFrom(t))
{
- return CreateArrayContract(t);
+ return CreateArrayContract(objectType);
}
if (CanConvertToString(t))
@@ -1264,10 +1293,17 @@ internal static bool CanConvertToString(Type type)
return true;
}
+#if HAVE_DATE_ONLY
+ if (type == typeof(DateOnly) || type == typeof(TimeOnly))
+ {
+ return true;
+ }
+#endif
+
return false;
}
- private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType)
+ private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo? currentCallback, ref Type? prevAttributeType)
{
if (!method.IsDefined(attributeType, false))
{
@@ -1276,36 +1312,36 @@ private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameter
if (currentCallback != null)
{
- throw new JsonException("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType));
+ throw new JsonException("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType!), attributeType));
}
if (prevAttributeType != null)
{
- throw new JsonException("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method));
+ throw new JsonException("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType!), method));
}
if (method.IsVirtual)
{
- throw new JsonException("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType));
+ throw new JsonException("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType!), attributeType));
}
if (method.ReturnType != typeof(void))
{
- throw new JsonException("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method));
+ throw new JsonException("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType!), method));
}
if (attributeType == typeof(OnErrorAttribute))
{
if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext))
{
- throw new JsonException("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext), typeof(ErrorContext)));
+ throw new JsonException("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType!), method, typeof(StreamingContext), typeof(ErrorContext)));
}
}
else
{
if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext))
{
- throw new JsonException("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext)));
+ throw new JsonException("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType!), method, typeof(StreamingContext)));
}
}
@@ -1318,7 +1354,7 @@ internal static string GetClrTypeFullName(Type type)
{
if (type.IsGenericTypeDefinition() || !type.ContainsGenericParameters())
{
- return type.FullName;
+ return type.FullName!;
}
return "{0}.{1}".FormatWith(CultureInfo.InvariantCulture, type.Namespace, type.Name);
@@ -1351,7 +1387,7 @@ protected virtual IList CreateProperties(Type type, MemberSerializ
// nametable is not thread-safe for multiple writers
lock (nameTable)
{
- property.PropertyName = nameTable.Add(property.PropertyName);
+ property.PropertyName = nameTable.Add(property.PropertyName!);
}
properties.AddProperty(property);
@@ -1377,7 +1413,7 @@ protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member)
// warning - this method use to cause errors with Intellitrace. Retest in VS Ultimate after changes
IValueProvider valueProvider;
-#if !(PORTABLE40 || PORTABLE || DOTNET || NETSTANDARD2_0)
+#if !(PORTABLE40 || PORTABLE || DOTNET || NETSTANDARD2_0 || NET6_0_OR_GREATER)
if (DynamicCodeGeneration)
{
valueProvider = new DynamicValueProvider(member);
@@ -1409,7 +1445,7 @@ protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerializa
property.ValueProvider = CreateMemberValueProvider(member);
property.AttributeProvider = new ReflectionAttributeProvider(member);
- SetPropertySettingsFromAttributes(property, member, member.Name, member.DeclaringType, memberSerialization, out bool allowNonPublicAccess);
+ SetPropertySettingsFromAttributes(property, member, member.Name, member.DeclaringType!, memberSerialization, out bool allowNonPublicAccess);
if (memberSerialization != MemberSerialization.Fields)
{
@@ -1439,11 +1475,11 @@ protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerializa
private void SetPropertySettingsFromAttributes(JsonProperty property, object attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess)
{
#if HAVE_DATA_CONTRACTS
- DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType);
+ DataContractAttribute? dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType);
- MemberInfo memberInfo = attributeProvider as MemberInfo;
+ MemberInfo? memberInfo = attributeProvider as MemberInfo;
- DataMemberAttribute dataMemberAttribute;
+ DataMemberAttribute? dataMemberAttribute;
if (dataContractAttribute != null && memberInfo != null)
{
dataMemberAttribute = JsonTypeReflector.GetDataMemberAttribute((MemberInfo)memberInfo);
@@ -1454,8 +1490,8 @@ private void SetPropertySettingsFromAttributes(JsonProperty property, object att
}
#endif
- JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute(attributeProvider);
- JsonRequiredAttribute requiredAttribute = JsonTypeReflector.GetAttribute(attributeProvider);
+ JsonPropertyAttribute? propertyAttribute = JsonTypeReflector.GetAttribute(attributeProvider);
+ JsonRequiredAttribute? requiredAttribute = JsonTypeReflector.GetAttribute(attributeProvider);
string mappedName;
bool hasSpecifiedName;
@@ -1477,9 +1513,9 @@ private void SetPropertySettingsFromAttributes(JsonProperty property, object att
hasSpecifiedName = false;
}
- JsonContainerAttribute containerAttribute = JsonTypeReflector.GetAttribute(declaringType);
+ JsonContainerAttribute? containerAttribute = JsonTypeReflector.GetAttribute(declaringType);
- NamingStrategy namingStrategy;
+ NamingStrategy? namingStrategy;
if (propertyAttribute?.NamingStrategyType != null)
{
namingStrategy = JsonTypeReflector.CreateNamingStrategyInstance(propertyAttribute.NamingStrategyType, propertyAttribute.NamingStrategyParameters);
@@ -1501,7 +1537,7 @@ private void SetPropertySettingsFromAttributes(JsonProperty property, object att
{
property.PropertyName = ResolvePropertyName(mappedName);
}
-
+
property.UnderlyingName = name;
bool hasMemberAttribute = false;
@@ -1582,7 +1618,7 @@ private void SetPropertySettingsFromAttributes(JsonProperty property, object att
// the class type might have a converter but the property converter takes precedence
property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider);
- DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute(attributeProvider);
+ DefaultValueAttribute? defaultValueAttribute = JsonTypeReflector.GetAttribute(attributeProvider);
if (defaultValueAttribute != null)
{
property.DefaultValue = defaultValueAttribute.Value;
@@ -1605,24 +1641,24 @@ private void SetPropertySettingsFromAttributes(JsonProperty property, object att
}
}
- private Predicate CreateShouldSerializeTest(MemberInfo member)
+ private Predicate? CreateShouldSerializeTest(MemberInfo member)
{
- MethodInfo shouldSerializeMethod = member.DeclaringType.GetMethod(JsonTypeReflector.ShouldSerializePrefix + member.Name, ReflectionUtils.EmptyTypes);
+ MethodInfo? shouldSerializeMethod = member.DeclaringType!.GetMethod(JsonTypeReflector.ShouldSerializePrefix + member.Name, ReflectionUtils.EmptyTypes);
if (shouldSerializeMethod == null || shouldSerializeMethod.ReturnType != typeof(bool))
{
return null;
}
- MethodCall shouldSerializeCall =
+ MethodCall shouldSerializeCall =
JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(shouldSerializeMethod);
- return o => (bool)shouldSerializeCall(o);
+ return o => (bool)shouldSerializeCall(o)!;
}
private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member, bool allowNonPublicAccess)
{
- MemberInfo specifiedMember = member.DeclaringType.GetProperty(member.Name + JsonTypeReflector.SpecifiedPostfix, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ MemberInfo? specifiedMember = member.DeclaringType!.GetProperty(member.Name + JsonTypeReflector.SpecifiedPostfix, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (specifiedMember == null)
{
specifiedMember = member.DeclaringType.GetField(member.Name + JsonTypeReflector.SpecifiedPostfix, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
@@ -1633,7 +1669,7 @@ private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member, boo
return;
}
- Func specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(specifiedMember);
+ Func specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(specifiedMember)!;
property.GetIsSpecified = o => (bool)specifiedPropertyGet(o);
@@ -1700,4 +1736,5 @@ public string GetResolvedPropertyName(string propertyName)
return ResolvePropertyName(propertyName);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultNamingStrategy.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultNamingStrategy.cs
index f5420206af..db416138da 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultNamingStrategy.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultNamingStrategy.cs
@@ -15,4 +15,4 @@ protected override string ResolvePropertyName(string name)
return name;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultReferenceResolver.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultReferenceResolver.cs
index a856c72636..7a1e0ddc93 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultReferenceResolver.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultReferenceResolver.cs
@@ -29,6 +29,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class DefaultReferenceResolver : IReferenceResolver
{
private int _referenceCount;
@@ -52,15 +53,15 @@ private BidirectionalDictionary GetMappings(object context)
public object ResolveReference(object context, string reference)
{
- GetMappings(context).TryGetByFirst(reference, out object value);
- return value;
+ GetMappings(context).TryGetByFirst(reference, out object? value);
+ return value!;
}
public string GetReference(object context, object value)
{
BidirectionalDictionary mappings = GetMappings(context);
- if (!mappings.TryGetBySecond(value, out string reference))
+ if (!mappings.TryGetBySecond(value, out string? reference))
{
_referenceCount++;
reference = _referenceCount.ToString(CultureInfo.InvariantCulture);
@@ -80,4 +81,5 @@ public bool IsReferenced(object context, object value)
return GetMappings(context).TryGetBySecond(value, out _);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultSerializationBinder.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultSerializationBinder.cs
index 22c80eabc7..91c41b7b7f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultSerializationBinder.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DefaultSerializationBinder.cs
@@ -29,10 +29,10 @@
using System.Globalization;
using Microsoft.IdentityModel.Json.Utilities;
using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// The default serialization binder used when resolving and loading classes from type names.
///
@@ -44,32 +44,31 @@ internal class DefaultSerializationBinder :
{
internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder();
- private readonly ThreadSafeStore, Type> _typeCache;
+ private readonly ThreadSafeStore, Type> _typeCache;
///
/// Initializes a new instance of the class.
///
public DefaultSerializationBinder()
{
- _typeCache = new ThreadSafeStore, Type>(GetTypeFromTypeNameKey);
+ _typeCache = new ThreadSafeStore, Type>(GetTypeFromTypeNameKey);
}
- [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId="Assembly.LoadWithPartialName")]
- private Type GetTypeFromTypeNameKey(StructMultiKey typeNameKey)
+ private Type GetTypeFromTypeNameKey(StructMultiKey typeNameKey)
{
- string assemblyName = typeNameKey.Value1;
+ string? assemblyName = typeNameKey.Value1;
string typeName = typeNameKey.Value2;
if (assemblyName != null)
{
- Assembly assembly = null;
+ Assembly? assembly;
#if !(DOTNET || PORTABLE40 || PORTABLE)
// look, I don't like using obsolete methods as much as you do but this is the only way
// Assembly.Load won't check the GAC for a partial name
-#pragma warning disable 618,612,2001
- // assembly = Assembly.LoadWithPartialName(assemblyName);
-#pragma warning restore 618,612,2001
+#pragma warning disable 618,612
+ assembly = Assembly.LoadWithPartialName(assemblyName);
+#pragma warning restore 618,612
#elif DOTNET || PORTABLE
assembly = Assembly.Load(new AssemblyName(assemblyName));
#else
@@ -98,12 +97,12 @@ private Type GetTypeFromTypeNameKey(StructMultiKey typeNameKey)
throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName));
}
- Type type = assembly.GetType(typeName);
+ Type? type = assembly.GetType(typeName);
if (type == null)
{
// if generic type, try manually parsing the type arguments for the case of dynamically loaded assemblies
// example generic typeName format: System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
- if (typeName.IndexOf('`') >= 0)
+ if (StringUtils.IndexOf(typeName, '`') >= 0)
{
try
{
@@ -125,18 +124,18 @@ private Type GetTypeFromTypeNameKey(StructMultiKey typeNameKey)
}
else
{
- return Type.GetType(typeName);
+ return Type.GetType(typeName)!;
}
}
- private Type GetGenericTypeFromTypeName(string typeName, Assembly assembly)
+ private Type? GetGenericTypeFromTypeName(string typeName, Assembly assembly)
{
- Type type = null;
- int openBracketIndex = typeName.IndexOf('[');
+ Type? type = null;
+ int openBracketIndex = StringUtils.IndexOf(typeName, '[');
if (openBracketIndex >= 0)
{
string genericTypeDefName = typeName.Substring(0, openBracketIndex);
- Type genericTypeDef = assembly.GetType(genericTypeDefName);
+ Type? genericTypeDef = assembly.GetType(genericTypeDefName);
if (genericTypeDef != null)
{
List genericTypeArguments = new List();
@@ -161,7 +160,7 @@ private Type GetGenericTypeFromTypeName(string typeName, Assembly assembly)
{
string typeArgAssemblyQualifiedName = typeName.Substring(typeArgStartIndex, i - typeArgStartIndex);
- StructMultiKey typeNameKey = ReflectionUtils.SplitFullyQualifiedTypeName(typeArgAssemblyQualifiedName);
+ StructMultiKey typeNameKey = ReflectionUtils.SplitFullyQualifiedTypeName(typeArgAssemblyQualifiedName);
genericTypeArguments.Add(GetTypeByName(typeNameKey));
}
break;
@@ -175,7 +174,7 @@ private Type GetGenericTypeFromTypeName(string typeName, Assembly assembly)
return type;
}
- private Type GetTypeByName(StructMultiKey typeNameKey)
+ private Type GetTypeByName(StructMultiKey typeNameKey)
{
return _typeCache.Get(typeNameKey);
}
@@ -188,9 +187,9 @@ private Type GetTypeByName(StructMultiKey typeNameKey)
///
/// The type of the object the formatter creates a new instance of.
///
- public override Type BindToType(string assemblyName, string typeName)
+ public override Type BindToType(string? assemblyName, string typeName)
{
- return GetTypeByName(new StructMultiKey(assemblyName, typeName));
+ return GetTypeByName(new StructMultiKey(assemblyName, typeName));
}
///
@@ -203,7 +202,7 @@ public override Type BindToType(string assemblyName, string typeName)
#if HAVE_SERIALIZATION_BINDER_BIND_TO_NAME
override
#endif
- void BindToName(Type serializedType, out string assemblyName, out string typeName)
+ void BindToName(Type serializedType, out string? assemblyName, out string? typeName)
{
#if !HAVE_FULL_REFLECTION
assemblyName = serializedType.GetTypeInfo().Assembly.FullName;
@@ -214,4 +213,5 @@ void BindToName(Type serializedType, out string assemblyName, out string typeNam
#endif
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DiagnosticsTraceWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DiagnosticsTraceWriter.cs
index 5a8627880e..6e1c0006d4 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DiagnosticsTraceWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DiagnosticsTraceWriter.cs
@@ -5,6 +5,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Represents a trace writer that writes to the application's instances.
///
@@ -43,7 +44,7 @@ private TraceEventType GetTraceEventType(TraceLevel level)
/// The at which to write this trace.
/// The trace message.
/// The trace exception. This parameter is optional.
- public void Trace(TraceLevel level, string message, Exception ex)
+ public void Trace(TraceLevel level, string message, Exception? ex)
{
if (level == TraceLevel.Off)
{
@@ -59,12 +60,12 @@ public void Trace(TraceLevel level, string message, Exception ex)
{
lock (listener)
{
- listener.TraceEvent(eventCache, "Microsoft.IdentityModel.Json", traceEventType, 0, message);
+ listener.TraceEvent(eventCache, "Newtonsoft.Json", traceEventType, 0, message);
}
}
else
{
- listener.TraceEvent(eventCache, "Microsoft.IdentityModel.Json", traceEventType, 0, message);
+ listener.TraceEvent(eventCache, "Newtonsoft.Json", traceEventType, 0, message);
}
if (DiagnosticsTrace.AutoFlush)
@@ -74,6 +75,7 @@ public void Trace(TraceLevel level, string message, Exception ex)
}
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DynamicValueProvider.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DynamicValueProvider.cs
index 498d4bfbe2..e60628248f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DynamicValueProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/DynamicValueProvider.cs
@@ -36,14 +36,15 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Get and set values for a using dynamic methods.
///
internal class DynamicValueProvider : IValueProvider
{
private readonly MemberInfo _memberInfo;
- private Func _getter;
- private Action _setter;
+ private Func? _getter;
+ private Action? _setter;
///
/// Initializes a new instance of the class.
@@ -60,7 +61,7 @@ public DynamicValueProvider(MemberInfo memberInfo)
///
/// The target to set the value on.
/// The value to set on the target.
- public void SetValue(object target, object value)
+ public void SetValue(object target, object? value)
{
try
{
@@ -98,7 +99,7 @@ public void SetValue(object target, object value)
///
/// The target to get the value from.
/// The value.
- public object GetValue(object target)
+ public object? GetValue(object target)
{
try
{
@@ -115,6 +116,7 @@ public object GetValue(object target)
}
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorContext.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorContext.cs
index ce6bab1b17..e2ae565444 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorContext.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorContext.cs
@@ -27,12 +27,13 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Provides information surrounding an error.
///
internal class ErrorContext
{
- internal ErrorContext(object originalObject, object member, string path, Exception error)
+ internal ErrorContext(object? originalObject, object? member, string path, Exception error)
{
OriginalObject = originalObject;
Member = member;
@@ -52,13 +53,13 @@ internal ErrorContext(object originalObject, object member, string path, Excepti
/// Gets the original object that caused the error.
///
/// The original object that caused the error.
- public object OriginalObject { get; }
+ public object? OriginalObject { get; }
///
/// Gets the member that caused the error.
///
/// The member that caused the error.
- public object Member { get; }
+ public object? Member { get; }
///
/// Gets the path of the JSON location where the error occurred.
@@ -72,4 +73,5 @@ internal ErrorContext(object originalObject, object member, string path, Excepti
/// true if handled; otherwise, false.
public bool Handled { get; set; }
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorEventArgs.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorEventArgs.cs
index d4421f47fb..915c32d6f2 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorEventArgs.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ErrorEventArgs.cs
@@ -27,6 +27,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Provides data for the Error event.
///
@@ -36,7 +37,7 @@ internal class ErrorEventArgs : EventArgs
/// Gets the current object the error event is being raised against.
///
/// The current object the error event is being raised against.
- public object CurrentObject { get; }
+ public object? CurrentObject { get; }
///
/// Gets the error context.
@@ -49,10 +50,11 @@ internal class ErrorEventArgs : EventArgs
///
/// The current object.
/// The error context.
- public ErrorEventArgs(object currentObject, ErrorContext errorContext)
+ public ErrorEventArgs(object? currentObject, ErrorContext errorContext)
{
CurrentObject = currentObject;
ErrorContext = errorContext;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ExpressionValueProvider.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ExpressionValueProvider.cs
index e3188b1abd..97315b4979 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ExpressionValueProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ExpressionValueProvider.cs
@@ -37,14 +37,15 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Get and set values for a using dynamic methods.
///
internal class ExpressionValueProvider : IValueProvider
{
private readonly MemberInfo _memberInfo;
- private Func _getter;
- private Action _setter;
+ private Func? _getter;
+ private Action? _setter;
///
/// Initializes a new instance of the class.
@@ -61,7 +62,7 @@ public ExpressionValueProvider(MemberInfo memberInfo)
///
/// The target to set the value on.
/// The value to set on the target.
- public void SetValue(object target, object value)
+ public void SetValue(object target, object? value)
{
try
{
@@ -99,7 +100,7 @@ public void SetValue(object target, object value)
///
/// The target to get the value from.
/// The value.
- public object GetValue(object target)
+ public object? GetValue(object target)
{
try
{
@@ -116,6 +117,7 @@ public object GetValue(object target)
}
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IAttributeProvider.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IAttributeProvider.cs
index 255891d936..a28b6ad36d 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IAttributeProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IAttributeProvider.cs
@@ -48,4 +48,4 @@ internal interface IAttributeProvider
/// A collection of s, or an empty collection.
IList GetAttributes(Type attributeType, bool inherit);
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IContractResolver.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IContractResolver.cs
index 88e725baff..15276c2536 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IContractResolver.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IContractResolver.cs
@@ -43,4 +43,4 @@ internal interface IContractResolver
/// The contract for a given type.
JsonContract ResolveContract(Type type);
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IReferenceResolver.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IReferenceResolver.cs
index ce435d3207..4a027e335a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IReferenceResolver.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IReferenceResolver.cs
@@ -64,4 +64,4 @@ internal interface IReferenceResolver
/// The object to reference.
void AddReference(object context, string reference, object value);
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ISerializationBinder.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ISerializationBinder.cs
index 066de56a34..99f77c1830 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ISerializationBinder.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ISerializationBinder.cs
@@ -29,6 +29,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Allows users to control class loading and mandate what class to load.
///
@@ -40,7 +41,7 @@ internal interface ISerializationBinder
/// Specifies the name of the serialized object.
/// Specifies the name of the serialized object
/// The type of the object the formatter creates a new instance of.
- Type BindToType(string assemblyName, string typeName);
+ Type BindToType(string? assemblyName, string typeName);
///
/// When implemented, controls the binding of a serialized object to a type.
@@ -48,6 +49,7 @@ internal interface ISerializationBinder
/// The type of the object the formatter creates a new instance of.
/// Specifies the name of the serialized object.
/// Specifies the name of the serialized object.
- void BindToName(Type serializedType, out string assemblyName, out string typeName);
+ void BindToName(Type serializedType, out string? assemblyName, out string? typeName);
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ITraceWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ITraceWriter.cs
index f63c87f6bb..b0c94c9285 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ITraceWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ITraceWriter.cs
@@ -4,6 +4,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Represents a trace writer.
///
@@ -23,6 +24,7 @@ internal interface ITraceWriter
/// The at which to write this trace.
/// The trace message.
/// The trace exception. This parameter is optional.
- void Trace(TraceLevel level, string message, Exception ex);
+ void Trace(TraceLevel level, string message, Exception? ex);
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IValueProvider.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IValueProvider.cs
index 5f285dfe9f..75a476da03 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IValueProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/IValueProvider.cs
@@ -25,6 +25,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Provides methods to get and set values.
///
@@ -35,13 +36,14 @@ internal interface IValueProvider
///
/// The target to set the value on.
/// The value to set on the target.
- void SetValue(object target, object value);
+ void SetValue(object target, object? value);
///
/// Gets the value.
///
/// The target to get the value from.
/// The value.
- object GetValue(object target);
+ object? GetValue(object target);
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonArrayContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonArrayContract.cs
index c848b6f21b..15f70caf69 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonArrayContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonArrayContract.cs
@@ -31,6 +31,7 @@
using System.Reflection;
using Microsoft.IdentityModel.Json.Utilities;
using System.Collections;
+using System.Diagnostics;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
@@ -40,6 +41,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Contract details for a used by the .
///
@@ -49,7 +51,7 @@ internal class JsonArrayContract : JsonContainerContract
/// Gets the of the collection items.
///
/// The of the collection items.
- public Type CollectionItemType { get; }
+ public Type? CollectionItemType { get; }
///
/// Gets a value indicating whether the collection type is a multidimensional array.
@@ -57,26 +59,26 @@ internal class JsonArrayContract : JsonContainerContract
/// true if the collection type is a multidimensional array; otherwise, false.
public bool IsMultidimensionalArray { get; }
- private readonly Type _genericCollectionDefinitionType;
+ private readonly Type? _genericCollectionDefinitionType;
- private Type _genericWrapperType;
- private ObjectConstructor _genericWrapperCreator;
- private Func _genericTemporaryCollectionCreator;
+ private Type? _genericWrapperType;
+ private ObjectConstructor? _genericWrapperCreator;
+ private Func? _genericTemporaryCollectionCreator;
internal bool IsArray { get; }
internal bool ShouldCreateWrapper { get; }
internal bool CanDeserialize { get; private set; }
- private readonly ConstructorInfo _parameterizedConstructor;
+ private readonly ConstructorInfo? _parameterizedConstructor;
- private ObjectConstructor _parameterizedCreator;
- private ObjectConstructor _overrideCreator;
+ private ObjectConstructor? _parameterizedCreator;
+ private ObjectConstructor? _overrideCreator;
- internal ObjectConstructor ParameterizedCreator
+ internal ObjectConstructor? ParameterizedCreator
{
get
{
- if (_parameterizedCreator == null)
+ if (_parameterizedCreator == null && _parameterizedConstructor != null)
{
_parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(_parameterizedConstructor);
}
@@ -89,7 +91,7 @@ internal ObjectConstructor ParameterizedCreator
/// Gets or sets the function used to create the object. When set this function will override .
///
/// The function used to create the object.
- public ObjectConstructor OverrideCreator
+ public ObjectConstructor? OverrideCreator
{
get => _overrideCreator;
set
@@ -116,72 +118,75 @@ public JsonArrayContract(Type underlyingType)
: base(underlyingType)
{
ContractType = JsonContractType.Array;
- IsArray = CreatedType.IsArray;
+
+ // netcoreapp3.0 uses EmptyPartition for empty enumerable. Treat as an empty array.
+ IsArray = CreatedType.IsArray ||
+ (NonNullableUnderlyingType.IsGenericType() && NonNullableUnderlyingType.GetGenericTypeDefinition().FullName == "System.Linq.EmptyPartition`1");
bool canDeserialize;
- Type tempCollectionType;
+ Type? tempCollectionType;
if (IsArray)
{
- CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
+ CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType)!;
IsReadOnlyOrFixedSize = true;
_genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType);
canDeserialize = true;
- IsMultidimensionalArray = (IsArray && UnderlyingType.GetArrayRank() > 1);
+ IsMultidimensionalArray = (CreatedType.IsArray && UnderlyingType.GetArrayRank() > 1);
}
- else if (typeof(IList).IsAssignableFrom(underlyingType))
+ else if (typeof(IList).IsAssignableFrom(NonNullableUnderlyingType))
{
- if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
+ if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
{
CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
}
else
{
- CollectionItemType = ReflectionUtils.GetCollectionItemType(underlyingType);
+ CollectionItemType = ReflectionUtils.GetCollectionItemType(NonNullableUnderlyingType);
}
- if (underlyingType == typeof(IList))
+ if (NonNullableUnderlyingType == typeof(IList))
{
CreatedType = typeof(List);
}
if (CollectionItemType != null)
{
- _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
+ _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(NonNullableUnderlyingType, CollectionItemType);
}
- IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyCollection<>));
+ IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(NonNullableUnderlyingType, typeof(ReadOnlyCollection<>));
canDeserialize = true;
}
- else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
+ else if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
{
CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
- if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(ICollection<>))
- || ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IList<>)))
+ if (ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(ICollection<>))
+ || ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(IList<>)))
{
CreatedType = typeof(List<>).MakeGenericType(CollectionItemType);
}
#if HAVE_ISET
- if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(ISet<>)))
+ if (ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(ISet<>)))
{
CreatedType = typeof(HashSet<>).MakeGenericType(CollectionItemType);
}
#endif
- _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
+ _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(NonNullableUnderlyingType, CollectionItemType);
canDeserialize = true;
ShouldCreateWrapper = true;
}
#if HAVE_READ_ONLY_COLLECTIONS
- else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IReadOnlyCollection<>), out tempCollectionType))
+ else if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(IReadOnlyCollection<>), out tempCollectionType))
{
CollectionItemType = tempCollectionType.GetGenericArguments()[0];
- if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IReadOnlyCollection<>))
- || ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IReadOnlyList<>)))
+ if (ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(IReadOnlyCollection<>))
+ || ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(IReadOnlyList<>)))
{
CreatedType = typeof(ReadOnlyCollection<>).MakeGenericType(CollectionItemType);
}
@@ -190,14 +195,14 @@ public JsonArrayContract(Type underlyingType)
_parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, CollectionItemType);
#if HAVE_FSHARP_TYPES
- StoreFSharpListCreatorIfNecessary(underlyingType);
+ StoreFSharpListCreatorIfNecessary(NonNullableUnderlyingType);
#endif
IsReadOnlyOrFixedSize = true;
canDeserialize = HasParameterizedCreatorInternal;
}
#endif
- else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IEnumerable<>), out tempCollectionType))
+ else if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(IEnumerable<>), out tempCollectionType))
{
CollectionItemType = tempCollectionType.GetGenericArguments()[0];
@@ -206,13 +211,13 @@ public JsonArrayContract(Type underlyingType)
CreatedType = typeof(List<>).MakeGenericType(CollectionItemType);
}
- _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
+ _parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(NonNullableUnderlyingType, CollectionItemType);
#if HAVE_FSHARP_TYPES
- StoreFSharpListCreatorIfNecessary(underlyingType);
+ StoreFSharpListCreatorIfNecessary(NonNullableUnderlyingType);
#endif
- if (underlyingType.IsGenericType() && underlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
+ if (NonNullableUnderlyingType.IsGenericType() && NonNullableUnderlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
_genericCollectionDefinitionType = tempCollectionType;
@@ -251,11 +256,12 @@ public JsonArrayContract(Type underlyingType)
}
#endif
- if (ImmutableCollectionsUtils.TryBuildImmutableForArrayContract(
- underlyingType,
+ if (CollectionItemType != null &&
+ ImmutableCollectionsUtils.TryBuildImmutableForArrayContract(
+ NonNullableUnderlyingType,
CollectionItemType,
- out Type immutableCreatedType,
- out ObjectConstructor immutableParameterizedCreator))
+ out Type? immutableCreatedType,
+ out ObjectConstructor? immutableParameterizedCreator))
{
CreatedType = immutableCreatedType;
_parameterizedCreator = immutableParameterizedCreator;
@@ -268,6 +274,9 @@ internal IWrappedCollection CreateWrapper(object list)
{
if (_genericWrapperCreator == null)
{
+ MiscellaneousUtils.Assert(_genericCollectionDefinitionType != null);
+ MiscellaneousUtils.Assert(CollectionItemType != null);
+
_genericWrapperType = typeof(CollectionWrapper<>).MakeGenericType(CollectionItemType);
Type constructorArgument;
@@ -282,7 +291,7 @@ internal IWrappedCollection CreateWrapper(object list)
constructorArgument = _genericCollectionDefinitionType;
}
- ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument });
+ ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument })!;
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(genericWrapperConstructor);
}
@@ -311,9 +320,10 @@ private void StoreFSharpListCreatorIfNecessary(Type underlyingType)
if (!HasParameterizedCreatorInternal && underlyingType.Name == FSharpUtils.FSharpListTypeName)
{
FSharpUtils.EnsureInitialized(underlyingType.Assembly());
- _parameterizedCreator = FSharpUtils.CreateSeq(CollectionItemType);
+ _parameterizedCreator = FSharpUtils.Instance.CreateSeq(CollectionItemType!);
}
}
#endif
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContainerContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContainerContract.cs
index f057f10a48..fcdb40c79b 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContainerContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContainerContract.cs
@@ -37,16 +37,17 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Contract details for a used by the .
///
internal class JsonContainerContract : JsonContract
{
- private JsonContract _itemContract;
- private JsonContract _finalItemContract;
+ private JsonContract? _itemContract;
+ private JsonContract? _finalItemContract;
// will be null for containers that don't have an item type (e.g. IList) or for complex objects
- internal JsonContract ItemContract
+ internal JsonContract? ItemContract
{
get => _itemContract;
set
@@ -64,13 +65,13 @@ internal JsonContract ItemContract
}
// the final (i.e. can't be inherited from like a sealed class or valuetype) item contract
- internal JsonContract FinalItemContract => _finalItemContract;
+ internal JsonContract? FinalItemContract => _finalItemContract;
///
/// Gets or sets the default collection items .
///
/// The converter.
- public JsonConverter ItemConverter { get; set; }
+ public JsonConverter? ItemConverter { get; set; }
///
/// Gets or sets a value indicating whether the collection items preserve object references.
@@ -97,7 +98,7 @@ internal JsonContract ItemContract
internal JsonContainerContract(Type underlyingType)
: base(underlyingType)
{
- JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetCachedAttribute(underlyingType);
+ JsonContainerAttribute? jsonContainerAttribute = JsonTypeReflector.GetCachedAttribute(underlyingType);
if (jsonContainerAttribute != null)
{
@@ -114,4 +115,5 @@ internal JsonContainerContract(Type underlyingType)
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContract.cs
index 44be7c841e..f6c5e2cde3 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonContract.cs
@@ -33,6 +33,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal enum JsonContractType
{
None = 0,
@@ -67,13 +68,13 @@ internal enum JsonContractType
/// The object to set extension data on.
/// The extension data key.
/// The extension data value.
- internal delegate void ExtensionDataSetter(object o, string key, object value);
+ internal delegate void ExtensionDataSetter(object o, string key, object? value);
///
/// Gets extension data for an object during serialization.
///
/// The object to set extension data on.
- internal delegate IEnumerable> ExtensionDataGetter(object o);
+ internal delegate IEnumerable>? ExtensionDataGetter(object o);
///
/// Contract details for a used by the .
@@ -90,11 +91,11 @@ internal abstract class JsonContract
internal bool IsSealed;
internal bool IsInstantiable;
- private List _onDeserializedCallbacks;
- private IList _onDeserializingCallbacks;
- private IList _onSerializedCallbacks;
- private IList _onSerializingCallbacks;
- private IList _onErrorCallbacks;
+ private List? _onDeserializedCallbacks;
+ private List? _onDeserializingCallbacks;
+ private List? _onSerializedCallbacks;
+ private List? _onSerializingCallbacks;
+ private List? _onErrorCallbacks;
private Type _createdType;
///
@@ -112,6 +113,7 @@ public Type CreatedType
get => _createdType;
set
{
+ ValidationUtils.ArgumentNotNull(value, nameof(value));
_createdType = value;
IsSealed = _createdType.IsSealed();
@@ -129,11 +131,14 @@ public Type CreatedType
/// Gets or sets the default for this contract.
///
/// The converter.
- public JsonConverter Converter { get; set; }
+ public JsonConverter? Converter { get; set; }
- // internally specified JsonConverter's to override default behavour
- // checked for after passed in converters and attribute specified converters
- internal JsonConverter InternalConverter { get; set; }
+ ///
+ /// Gets the internally resolved for the contract's type.
+ /// This converter is used as a fallback converter when no other converter is resolved.
+ /// Setting will always override this converter.
+ ///
+ public JsonConverter? InternalConverter { get; internal set; }
///
/// Gets or sets all methods called immediately after deserialization of the object.
@@ -224,7 +229,7 @@ public IList OnErrorCallbacks
/// Gets or sets the default creator method used to create the object.
///
/// The default creator method used to create the object.
- public Func DefaultCreator { get; set; }
+ public Func? DefaultCreator { get; set; }
///
/// Gets or sets a value indicating whether the default creator is non-public.
@@ -243,10 +248,10 @@ internal JsonContract(Type underlyingType)
underlyingType = ReflectionUtils.EnsureNotByRefType(underlyingType);
IsNullable = ReflectionUtils.IsNullable(underlyingType);
+
+ NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType)! : underlyingType;
- NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType;
-
- CreatedType = NonNullableUnderlyingType;
+ _createdType = CreatedType = NonNullableUnderlyingType;
IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType);
IsEnum = NonNullableUnderlyingType.IsEnum();
@@ -319,4 +324,5 @@ internal static SerializationErrorCallback CreateSerializationErrorCallback(Meth
return (o, context, econtext) => callbackMethodInfo.Invoke(o, new object[] { context, econtext });
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDictionaryContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDictionaryContract.cs
index dec3cb8a66..fbb6827a70 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDictionaryContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDictionaryContract.cs
@@ -36,6 +36,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Contract details for a used by the .
///
@@ -45,41 +46,41 @@ internal class JsonDictionaryContract : JsonContainerContract
/// Gets or sets the dictionary key resolver.
///
/// The dictionary key resolver.
- public Func DictionaryKeyResolver { get; set; }
+ public Func? DictionaryKeyResolver { get; set; }
///
/// Gets the of the dictionary keys.
///
/// The of the dictionary keys.
- public Type DictionaryKeyType { get; }
+ public Type? DictionaryKeyType { get; }
///
/// Gets the of the dictionary values.
///
/// The of the dictionary values.
- public Type DictionaryValueType { get; }
+ public Type? DictionaryValueType { get; }
- internal JsonContract KeyContract { get; set; }
+ internal JsonContract? KeyContract { get; set; }
- private readonly Type _genericCollectionDefinitionType;
+ private readonly Type? _genericCollectionDefinitionType;
- private Type _genericWrapperType;
- private ObjectConstructor _genericWrapperCreator;
+ private Type? _genericWrapperType;
+ private ObjectConstructor? _genericWrapperCreator;
- private Func _genericTemporaryDictionaryCreator;
+ private Func? _genericTemporaryDictionaryCreator;
internal bool ShouldCreateWrapper { get; }
- private readonly ConstructorInfo _parameterizedConstructor;
+ private readonly ConstructorInfo? _parameterizedConstructor;
- private ObjectConstructor _overrideCreator;
- private ObjectConstructor _parameterizedCreator;
+ private ObjectConstructor? _overrideCreator;
+ private ObjectConstructor? _parameterizedCreator;
- internal ObjectConstructor ParameterizedCreator
+ internal ObjectConstructor? ParameterizedCreator
{
get
{
- if (_parameterizedCreator == null)
+ if (_parameterizedCreator == null && _parameterizedConstructor != null)
{
_parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(_parameterizedConstructor);
}
@@ -92,7 +93,7 @@ internal ObjectConstructor ParameterizedCreator
/// Gets or sets the function used to create the object. When set this function will override .
///
/// The function used to create the object.
- public ObjectConstructor OverrideCreator
+ public ObjectConstructor? OverrideCreator
{
get => _overrideCreator;
set => _overrideCreator = value;
@@ -115,24 +116,24 @@ public JsonDictionaryContract(Type underlyingType)
{
ContractType = JsonContractType.Dictionary;
- Type keyType;
- Type valueType;
+ Type? keyType;
+ Type? valueType;
- if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType))
+ if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType))
{
keyType = _genericCollectionDefinitionType.GetGenericArguments()[0];
valueType = _genericCollectionDefinitionType.GetGenericArguments()[1];
- if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IDictionary<,>)))
+ if (ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(IDictionary<,>)))
{
CreatedType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
}
- else if (underlyingType.IsGenericType())
+ else if (NonNullableUnderlyingType.IsGenericType())
{
// ConcurrentDictionary<,> + IDictionary setter + null value = error
// wrap to use generic setter
- // https://github.com/JamesNK/Microsoft.IdentityModel.Json/issues/1582
- Type typeDefinition = underlyingType.GetGenericTypeDefinition();
+ // https://github.com/JamesNK/Newtonsoft.Json/issues/1582
+ Type typeDefinition = NonNullableUnderlyingType.GetGenericTypeDefinition();
if (typeDefinition.FullName == JsonTypeReflector.ConcurrentDictionaryTypeName)
{
ShouldCreateWrapper = true;
@@ -140,17 +141,17 @@ public JsonDictionaryContract(Type underlyingType)
}
#if HAVE_READ_ONLY_COLLECTIONS
- IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyDictionary<,>));
+ IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(NonNullableUnderlyingType, typeof(ReadOnlyDictionary<,>));
#endif
}
#if HAVE_READ_ONLY_COLLECTIONS
- else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IReadOnlyDictionary<,>), out _genericCollectionDefinitionType))
+ else if (ReflectionUtils.ImplementsGenericDefinition(NonNullableUnderlyingType, typeof(IReadOnlyDictionary<,>), out _genericCollectionDefinitionType))
{
keyType = _genericCollectionDefinitionType.GetGenericArguments()[0];
valueType = _genericCollectionDefinitionType.GetGenericArguments()[1];
- if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IReadOnlyDictionary<,>)))
+ if (ReflectionUtils.IsGenericDefinition(NonNullableUnderlyingType, typeof(IReadOnlyDictionary<,>)))
{
CreatedType = typeof(ReadOnlyDictionary<,>).MakeGenericType(keyType, valueType);
}
@@ -160,9 +161,9 @@ public JsonDictionaryContract(Type underlyingType)
#endif
else
{
- ReflectionUtils.GetDictionaryKeyValueTypes(UnderlyingType, out keyType, out valueType);
+ ReflectionUtils.GetDictionaryKeyValueTypes(NonNullableUnderlyingType, out keyType, out valueType);
- if (UnderlyingType == typeof(IDictionary))
+ if (NonNullableUnderlyingType == typeof(IDictionary))
{
CreatedType = typeof(Dictionary);
}
@@ -176,10 +177,10 @@ public JsonDictionaryContract(Type underlyingType)
typeof(IDictionary<,>).MakeGenericType(keyType, valueType));
#if HAVE_FSHARP_TYPES
- if (!HasParameterizedCreatorInternal && underlyingType.Name == FSharpUtils.FSharpMapTypeName)
+ if (!HasParameterizedCreatorInternal && NonNullableUnderlyingType.Name == FSharpUtils.FSharpMapTypeName)
{
- FSharpUtils.EnsureInitialized(underlyingType.Assembly());
- _parameterizedCreator = FSharpUtils.CreateMap(keyType, valueType);
+ FSharpUtils.EnsureInitialized(NonNullableUnderlyingType.Assembly());
+ _parameterizedCreator = FSharpUtils.Instance.CreateMap(keyType, valueType);
}
#endif
}
@@ -204,12 +205,14 @@ public JsonDictionaryContract(Type underlyingType)
}
#endif
- if (ImmutableCollectionsUtils.TryBuildImmutableForDictionaryContract(
- underlyingType,
- DictionaryKeyType,
- DictionaryValueType,
- out Type immutableCreatedType,
- out ObjectConstructor immutableParameterizedCreator))
+ if (DictionaryKeyType != null &&
+ DictionaryValueType != null &&
+ ImmutableCollectionsUtils.TryBuildImmutableForDictionaryContract(
+ NonNullableUnderlyingType,
+ DictionaryKeyType,
+ DictionaryValueType,
+ out Type? immutableCreatedType,
+ out ObjectConstructor? immutableParameterizedCreator))
{
CreatedType = immutableCreatedType;
_parameterizedCreator = immutableParameterizedCreator;
@@ -221,9 +224,9 @@ internal IWrappedDictionary CreateWrapper(object dictionary)
{
if (_genericWrapperCreator == null)
{
- _genericWrapperType = typeof(DictionaryWrapper<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType);
+ _genericWrapperType = typeof(DictionaryWrapper<,>).MakeGenericType(DictionaryKeyType!, DictionaryValueType!);
- ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
+ ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType! })!;
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(genericWrapperConstructor);
}
@@ -242,4 +245,5 @@ internal IDictionary CreateTemporaryDictionary()
return (IDictionary)_genericTemporaryDictionaryCreator();
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDynamicContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDynamicContract.cs
index 55b7b0133d..c438d0384d 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDynamicContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonDynamicContract.cs
@@ -31,6 +31,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Contract details for a used by the .
///
@@ -46,13 +47,13 @@ internal class JsonDynamicContract : JsonContainerContract
/// Gets or sets the property name resolver.
///
/// The property name resolver.
- public Func PropertyNameResolver { get; set; }
+ public Func? PropertyNameResolver { get; set; }
private readonly ThreadSafeStore>> _callSiteGetters =
new ThreadSafeStore>>(CreateCallSiteGetter);
- private readonly ThreadSafeStore>> _callSiteSetters =
- new ThreadSafeStore>>(CreateCallSiteSetter);
+ private readonly ThreadSafeStore>> _callSiteSetters =
+ new ThreadSafeStore>>(CreateCallSiteSetter);
private static CallSite> CreateCallSiteGetter(string name)
{
@@ -61,11 +62,11 @@ private static CallSite> CreateCallSiteGetter(str
return CallSite>.Create(new NoThrowGetBinderMember(getMemberBinder));
}
- private static CallSite> CreateCallSiteSetter(string name)
+ private static CallSite> CreateCallSiteSetter(string name)
{
SetMemberBinder binder = (SetMemberBinder)DynamicUtils.BinderWrapper.SetMember(name, typeof(DynamicUtils));
- return CallSite>.Create(new NoThrowSetBinderMember(binder));
+ return CallSite>.Create(new NoThrowSetBinderMember(binder));
}
///
@@ -80,7 +81,7 @@ public JsonDynamicContract(Type underlyingType)
Properties = new JsonPropertyCollection(UnderlyingType);
}
- internal bool TryGetMember(IDynamicMetaObjectProvider dynamicProvider, string name, out object value)
+ internal bool TryGetMember(IDynamicMetaObjectProvider dynamicProvider, string name, out object? value)
{
ValidationUtils.ArgumentNotNull(dynamicProvider, nameof(dynamicProvider));
@@ -100,17 +101,18 @@ internal bool TryGetMember(IDynamicMetaObjectProvider dynamicProvider, string na
}
}
- internal bool TrySetMember(IDynamicMetaObjectProvider dynamicProvider, string name, object value)
+ internal bool TrySetMember(IDynamicMetaObjectProvider dynamicProvider, string name, object? value)
{
ValidationUtils.ArgumentNotNull(dynamicProvider, nameof(dynamicProvider));
- CallSite> callSite = _callSiteSetters.Get(name);
+ CallSite> callSite = _callSiteSetters.Get(name);
object result = callSite.Target(callSite, dynamicProvider, value);
return !ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult);
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonFormatterConverter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonFormatterConverter.cs
index b8b879fd70..4e6858a865 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonFormatterConverter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonFormatterConverter.cs
@@ -32,13 +32,14 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class JsonFormatterConverter : IFormatterConverter
{
private readonly JsonSerializerInternalReader _reader;
private readonly JsonISerializableContract _contract;
- private readonly JsonProperty _member;
+ private readonly JsonProperty? _member;
- public JsonFormatterConverter(JsonSerializerInternalReader reader, JsonISerializableContract contract, JsonProperty member)
+ public JsonFormatterConverter(JsonSerializerInternalReader reader, JsonISerializableContract contract, JsonProperty? member)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
ValidationUtils.ArgumentNotNull(contract, nameof(contract));
@@ -53,7 +54,7 @@ private T GetTokenValue(object value)
ValidationUtils.ArgumentNotNull(value, nameof(value));
JValue v = (JValue)value;
- return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture);
+ return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture)!;
}
public object Convert(object value, Type type)
@@ -65,19 +66,16 @@ public object Convert(object value, Type type)
throw new ArgumentException("Value is not a JToken.", nameof(value));
}
- return _reader.CreateISerializableItem(token, type, _contract, _member);
+ return _reader.CreateISerializableItem(token, type, _contract, _member)!;
}
public object Convert(object value, TypeCode typeCode)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
- if (value is JValue v)
- {
- value = v.Value;
- }
+ object? resolvedValue = (value is JValue v) ? v.Value : value;
- return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
+ return System.Convert.ChangeType(resolvedValue, typeCode, CultureInfo.InvariantCulture)!;
}
public bool ToBoolean(object value)
@@ -155,6 +153,7 @@ public ulong ToUInt64(object value)
return GetTokenValue(value);
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonISerializableContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonISerializableContract.cs
index e086f06036..29870f42b1 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonISerializableContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonISerializableContract.cs
@@ -29,6 +29,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Contract details for a used by the .
///
@@ -38,7 +39,7 @@ internal class JsonISerializableContract : JsonContainerContract
/// Gets or sets the object constructor.
///
/// The object constructor.
- public ObjectConstructor ISerializableCreator { get; set; }
+ public ObjectConstructor? ISerializableCreator { get; set; }
///
/// Initializes a new instance of the class.
@@ -50,6 +51,7 @@ public JsonISerializableContract(Type underlyingType)
ContractType = JsonContractType.Serializable;
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonLinqContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonLinqContract.cs
index 46484f91cb..b69d856acb 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonLinqContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonLinqContract.cs
@@ -42,4 +42,4 @@ public JsonLinqContract(Type underlyingType)
ContractType = JsonContractType.Linq;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonObjectContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonObjectContract.cs
index e8a0b593e1..082f09307f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonObjectContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonObjectContract.cs
@@ -33,6 +33,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Contract details for a used by the .
///
@@ -44,6 +45,12 @@ internal class JsonObjectContract : JsonContainerContract
/// The member object serialization.
public MemberSerialization MemberSerialization { get; set; }
+ ///
+ /// Gets or sets the missing member handling used when deserializing this object.
+ ///
+ /// The missing member handling.
+ public MissingMemberHandling? MissingMemberHandling { get; set; }
+
///
/// Gets or sets a value that indicates whether the object's properties are required.
///
@@ -85,13 +92,13 @@ public JsonPropertyCollection CreatorParameters
/// This function is called with a collection of arguments which are defined by the collection.
///
/// The function used to create the object.
- public ObjectConstructor OverrideCreator
+ public ObjectConstructor? OverrideCreator
{
get => _overrideCreator;
set => _overrideCreator = value;
}
- internal ObjectConstructor ParameterizedCreator
+ internal ObjectConstructor? ParameterizedCreator
{
get => _parameterizedCreator;
set => _parameterizedCreator = value;
@@ -100,17 +107,17 @@ internal ObjectConstructor ParameterizedCreator
///
/// Gets or sets the extension data setter.
///
- public ExtensionDataSetter ExtensionDataSetter { get; set; }
+ public ExtensionDataSetter? ExtensionDataSetter { get; set; }
///
/// Gets or sets the extension data getter.
///
- public ExtensionDataGetter ExtensionDataGetter { get; set; }
+ public ExtensionDataGetter? ExtensionDataGetter { get; set; }
///
/// Gets or sets the extension data value type.
///
- public Type ExtensionDataValueType
+ public Type? ExtensionDataValueType
{
get => _extensionDataValueType;
set
@@ -124,14 +131,14 @@ public Type ExtensionDataValueType
/// Gets or sets the extension data name resolver.
///
/// The extension data name resolver.
- public Func ExtensionDataNameResolver { get; set; }
+ public Func? ExtensionDataNameResolver { get; set; }
internal bool ExtensionDataIsJToken;
private bool? _hasRequiredOrDefaultValueProperties;
- private ObjectConstructor _overrideCreator;
- private ObjectConstructor _parameterizedCreator;
- private JsonPropertyCollection _creatorParameters;
- private Type _extensionDataValueType;
+ private ObjectConstructor? _overrideCreator;
+ private ObjectConstructor? _parameterizedCreator;
+ private JsonPropertyCollection? _creatorParameters;
+ private Type? _extensionDataValueType;
internal bool HasRequiredOrDefaultValueProperties
{
@@ -190,4 +197,5 @@ internal object GetUninitializedObject()
}
#endif
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPrimitiveContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPrimitiveContract.cs
index 1a15e7935d..df0219dbf9 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPrimitiveContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPrimitiveContract.cs
@@ -72,4 +72,4 @@ public JsonPrimitiveContract(Type underlyingType)
[typeof(long)] = ReadType.ReadAsInt64
};
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonProperty.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonProperty.cs
index eb1c9b59d3..05a690c64b 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonProperty.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonProperty.cs
@@ -24,6 +24,7 @@
#endregion
using System;
+using System.Diagnostics;
using System.Reflection;
using Microsoft.IdentityModel.Json.Utilities;
@@ -33,6 +34,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Maps a JSON property to a .NET member or constructor parameter.
///
@@ -41,20 +43,20 @@ internal class JsonProperty
internal Required? _required;
internal bool _hasExplicitDefaultValue;
- private object _defaultValue;
+ private object? _defaultValue;
private bool _hasGeneratedDefaultValue;
- private string _propertyName;
+ private string? _propertyName;
internal bool _skipPropertyNameEscape;
- private Type _propertyType;
+ private Type? _propertyType;
// use to cache contract during deserialization
- internal JsonContract PropertyContract { get; set; }
+ internal JsonContract? PropertyContract { get; set; }
///
/// Gets or sets the name of the property.
///
/// The name of the property.
- public string PropertyName
+ public string? PropertyName
{
get => _propertyName;
set
@@ -68,7 +70,7 @@ public string PropertyName
/// Gets or sets the type that declared this property.
///
/// The type that declared this property.
- public Type DeclaringType { get; set; }
+ public Type? DeclaringType { get; set; }
///
/// Gets or sets the order of serialization of a member.
@@ -80,25 +82,25 @@ public string PropertyName
/// Gets or sets the name of the underlying member or parameter.
///
/// The name of the underlying member or parameter.
- public string UnderlyingName { get; set; }
+ public string? UnderlyingName { get; set; }
///
/// Gets the that will get and set the during serialization.
///
/// The that will get and set the during serialization.
- public IValueProvider ValueProvider { get; set; }
+ public IValueProvider? ValueProvider { get; set; }
///
/// Gets or sets the for this property.
///
/// The for this property.
- public IAttributeProvider AttributeProvider { get; set; }
+ public IAttributeProvider? AttributeProvider { get; set; }
///
/// Gets or sets the type of the property.
///
/// The type of the property.
- public Type PropertyType
+ public Type? PropertyType
{
get => _propertyType;
set
@@ -116,14 +118,14 @@ public Type PropertyType
/// If set this converter takes precedence over the contract converter for the property type.
///
/// The converter.
- public JsonConverter Converter { get; set; }
+ public JsonConverter? Converter { get; set; }
///
/// Gets or sets the member converter.
///
/// The member converter.
[Obsolete("MemberConverter is obsolete. Use Converter instead.")]
- public JsonConverter MemberConverter
+ public JsonConverter? MemberConverter
{
get => Converter;
set => Converter = value;
@@ -157,7 +159,7 @@ public JsonConverter MemberConverter
/// Gets the default value.
///
/// The default value.
- public object DefaultValue
+ public object? DefaultValue
{
get
{
@@ -175,7 +177,7 @@ public object DefaultValue
}
}
- internal object GetResolvedDefaultValue()
+ internal object? GetResolvedDefaultValue()
{
if (_propertyType == null)
{
@@ -184,7 +186,7 @@ internal object GetResolvedDefaultValue()
if (!_hasExplicitDefaultValue && !_hasGeneratedDefaultValue)
{
- _defaultValue = ReflectionUtils.GetDefaultValue(PropertyType);
+ _defaultValue = ReflectionUtils.GetDefaultValue(_propertyType);
_hasGeneratedDefaultValue = true;
}
@@ -201,6 +203,11 @@ public Required Required
set => _required = value;
}
+ ///
+ /// Gets a value indicating whether has a value specified.
+ ///
+ public bool IsRequiredSpecified => _required != null;
+
///
/// Gets or sets a value indicating whether this property preserves object references.
///
@@ -243,25 +250,25 @@ public Required Required
/// Gets or sets a predicate used to determine whether the property should be serialized.
///
/// A predicate used to determine whether the property should be serialized.
- public Predicate ShouldSerialize { get; set; }
+ public Predicate? ShouldSerialize { get; set; }
///
/// Gets or sets a predicate used to determine whether the property should be deserialized.
///
/// A predicate used to determine whether the property should be deserialized.
- public Predicate ShouldDeserialize { get; set; }
+ public Predicate? ShouldDeserialize { get; set; }
///
/// Gets or sets a predicate used to determine whether the property should be serialized.
///
/// A predicate used to determine whether the property should be serialized.
- public Predicate GetIsSpecified { get; set; }
+ public Predicate? GetIsSpecified { get; set; }
///
/// Gets or sets an action used to set whether the property has been deserialized.
///
/// An action used to set whether the property has been deserialized.
- public Action SetIsSpecified { get; set; }
+ public Action? SetIsSpecified { get; set; }
///
/// Returns a that represents this instance.
@@ -271,14 +278,14 @@ public Required Required
///
public override string ToString()
{
- return PropertyName;
+ return PropertyName ?? string.Empty;
}
///
/// Gets or sets the converter used when serializing the property's collection items.
///
/// The collection's items converter.
- public JsonConverter ItemConverter { get; set; }
+ public JsonConverter? ItemConverter { get; set; }
///
/// Gets or sets whether this property's collection items are serialized as a reference.
@@ -300,14 +307,18 @@ public override string ToString()
internal void WritePropertyName(JsonWriter writer)
{
+ string? propertyName = PropertyName;
+ MiscellaneousUtils.Assert(propertyName != null);
+
if (_skipPropertyNameEscape)
{
- writer.WritePropertyName(PropertyName, false);
+ writer.WritePropertyName(propertyName, false);
}
else
{
- writer.WritePropertyName(PropertyName);
+ writer.WritePropertyName(propertyName);
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPropertyCollection.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPropertyCollection.cs
index 3ae224054e..23853c9de4 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPropertyCollection.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonPropertyCollection.cs
@@ -29,9 +29,13 @@
using System.Collections.ObjectModel;
using Microsoft.IdentityModel.Json.Utilities;
using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// A collection of objects.
///
@@ -61,7 +65,7 @@ public JsonPropertyCollection(Type type)
/// The key for the specified element.
protected override string GetKeyForItem(JsonProperty item)
{
- return item.PropertyName;
+ return item.PropertyName!;
}
///
@@ -70,6 +74,8 @@ protected override string GetKeyForItem(JsonProperty item)
/// The property to add to the collection.
public void AddProperty(JsonProperty property)
{
+ MiscellaneousUtils.Assert(property.PropertyName != null);
+
if (Contains(property.PropertyName))
{
// don't overwrite existing property with ignored property
@@ -104,7 +110,7 @@ public void AddProperty(JsonProperty property)
// current property is hidden by the existing so don't add it
return;
}
-
+
if (_type.ImplementInterface(existingProperty.DeclaringType) && _type.ImplementInterface(property.DeclaringType))
{
// current property was already defined on another interface
@@ -129,9 +135,9 @@ public void AddProperty(JsonProperty property)
///
/// Name of the property.
/// A matching property if found.
- public JsonProperty GetClosestMatchProperty(string propertyName)
+ public JsonProperty? GetClosestMatchProperty(string propertyName)
{
- JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal);
+ JsonProperty? property = GetProperty(propertyName, StringComparison.Ordinal);
if (property == null)
{
property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase);
@@ -140,9 +146,7 @@ public JsonProperty GetClosestMatchProperty(string propertyName)
return property;
}
-#pragma warning disable CS0108 // Member hides inherited member; missing new keyword
- private bool TryGetValue(string key, out JsonProperty item)
-#pragma warning restore CS0108 // Member hides inherited member; missing new keyword
+ private bool TryGetProperty(string key, [NotNullWhen(true)]out JsonProperty? item)
{
if (Dictionary == null)
{
@@ -159,12 +163,12 @@ private bool TryGetValue(string key, out JsonProperty item)
/// The name of the property to get.
/// Type property name string comparison.
/// A matching property if found.
- public JsonProperty GetProperty(string propertyName, StringComparison comparisonType)
+ public JsonProperty? GetProperty(string propertyName, StringComparison comparisonType)
{
// KeyedCollection has an ordinal comparer
if (comparisonType == StringComparison.Ordinal)
{
- if (TryGetValue(propertyName, out JsonProperty property))
+ if (TryGetProperty(propertyName, out JsonProperty? property))
{
return property;
}
@@ -184,4 +188,5 @@ public JsonProperty GetProperty(string propertyName, StringComparison comparison
return null;
}
}
+#nullable disable
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalBase.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalBase.cs
index e216a23f7c..6529804f4c 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalBase.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalBase.cs
@@ -31,11 +31,12 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal abstract class JsonSerializerInternalBase
{
private class ReferenceEqualsEqualityComparer : IEqualityComparer
{
- bool IEqualityComparer.Equals(object x, object y)
+ bool IEqualityComparer.Equals(object? x, object? y)
{
return ReferenceEquals(x, y);
}
@@ -47,12 +48,12 @@ int IEqualityComparer.GetHashCode(object obj)
}
}
- private ErrorContext _currentErrorContext;
- private BidirectionalDictionary _mappings;
+ private ErrorContext? _currentErrorContext;
+ private BidirectionalDictionary? _mappings;
internal readonly JsonSerializer Serializer;
- internal readonly ITraceWriter TraceWriter;
- protected JsonSerializerProxy InternalSerializer;
+ internal readonly ITraceWriter? TraceWriter;
+ protected JsonSerializerProxy? InternalSerializer;
protected JsonSerializerInternalBase(JsonSerializer serializer)
{
@@ -81,7 +82,7 @@ internal BidirectionalDictionary DefaultReferenceMappings
}
}
- protected NullValueHandling ResolvedNullValueHandling(JsonObjectContract containerContract, JsonProperty property)
+ protected NullValueHandling ResolvedNullValueHandling(JsonObjectContract? containerContract, JsonProperty property)
{
NullValueHandling resolvedNullValueHandling =
property.NullValueHandling
@@ -91,7 +92,7 @@ protected NullValueHandling ResolvedNullValueHandling(JsonObjectContract contain
return resolvedNullValueHandling;
}
- private ErrorContext GetErrorContext(object currentObject, object member, string path, Exception error)
+ private ErrorContext GetErrorContext(object? currentObject, object? member, string path, Exception error)
{
if (_currentErrorContext == null)
{
@@ -116,7 +117,7 @@ protected void ClearErrorContext()
_currentErrorContext = null;
}
- protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, IJsonLineInfo lineInfo, string path, Exception ex)
+ protected bool IsErrorHandled(object? currentObject, JsonContract? contract, object? keyValue, IJsonLineInfo? lineInfo, string path, Exception ex)
{
ErrorContext errorContext = GetErrorContext(currentObject, keyValue, path, ex);
@@ -156,4 +157,5 @@ protected bool IsErrorHandled(object currentObject, JsonContract contract, objec
return errorContext.Handled;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalReader.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalReader.cs
index fdd27afe63..3b48c63fe6 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalReader.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalReader.cs
@@ -40,15 +40,17 @@
using System.Runtime.Serialization;
using Microsoft.IdentityModel.Json.Linq;
using Microsoft.IdentityModel.Json.Utilities;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
using System.Linq;
-
#endif
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class JsonSerializerInternalReader : JsonSerializerInternalBase
{
internal enum PropertyPresence
@@ -93,10 +95,10 @@ public void Populate(JsonReader reader, object target)
{
reader.ReadAndAssert();
- string id = null;
+ string? id = null;
if (Serializer.MetadataPropertyHandling != MetadataPropertyHandling.Ignore
&& reader.TokenType == JsonToken.PropertyName
- && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
+ && string.Equals(reader.Value!.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
{
reader.ReadAndAssert();
id = reader.Value?.ToString();
@@ -123,28 +125,33 @@ public void Populate(JsonReader reader, object target)
}
}
- private JsonContract GetContractSafe(Type type)
+ private JsonContract? GetContractSafe(Type? type)
{
if (type == null)
{
return null;
}
+ return GetContract(type);
+ }
+
+ private JsonContract GetContract(Type type)
+ {
return Serializer._contractResolver.ResolveContract(type);
}
- public object Deserialize(JsonReader reader, Type objectType, bool checkAdditionalContent)
+ public object? Deserialize(JsonReader reader, Type? objectType, bool checkAdditionalContent)
{
if (reader == null)
{
throw new ArgumentNullException(nameof(reader));
}
- JsonContract contract = GetContractSafe(objectType);
+ JsonContract? contract = GetContractSafe(objectType);
try
{
- JsonConverter converter = GetConverter(contract, null, null, null);
+ JsonConverter? converter = GetConverter(contract, null, null, null);
if (reader.TokenType == JsonToken.None && !reader.ReadForType(contract, converter != null))
{
@@ -156,11 +163,11 @@ public object Deserialize(JsonReader reader, Type objectType, bool checkAddition
return null;
}
- object deserializedValue;
+ object? deserializedValue;
if (converter != null && converter.CanRead)
{
- deserializedValue = DeserializeConvertable(converter, reader, objectType, null);
+ deserializedValue = DeserializeConvertable(converter, reader, objectType!, null);
}
else
{
@@ -208,7 +215,7 @@ private JsonSerializerProxy GetInternalSerializer()
return InternalSerializer;
}
- private JToken CreateJToken(JsonReader reader, JsonContract contract)
+ private JToken? CreateJToken(JsonReader reader, JsonContract? contract)
{
ValidationUtils.ArgumentNotNull(reader, nameof(reader));
@@ -225,13 +232,22 @@ private JToken CreateJToken(JsonReader reader, JsonContract contract)
}
}
- JToken token;
+ JToken? token;
using (JTokenWriter writer = new JTokenWriter())
{
writer.WriteToken(reader);
token = writer.Token;
}
+ if (contract != null && token != null)
+ {
+ if (!contract.UnderlyingType.IsAssignableFrom(token.GetType()))
+ {
+ throw JsonSerializationException.Create(reader, "Deserialized JSON type '{0}' is not compatible with expected type '{1}'."
+ .FormatWith(CultureInfo.InvariantCulture, token.GetType().FullName, contract.UnderlyingType.FullName));
+ }
+ }
+
return token;
}
@@ -248,7 +264,7 @@ private JToken CreateJObject(JsonReader reader)
{
if (reader.TokenType == JsonToken.PropertyName)
{
- string propertyName = (string)reader.Value;
+ string propertyName = (string)reader.Value!;
if (!reader.ReadAndMoveToContent())
{
break;
@@ -269,7 +285,7 @@ private JToken CreateJObject(JsonReader reader)
else
{
writer.WriteEndObject();
- return writer.Token;
+ return writer.Token!;
}
} while (reader.Read());
@@ -277,7 +293,7 @@ private JToken CreateJObject(JsonReader reader)
}
}
- private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
+ private object? CreateValueInternal(JsonReader reader, Type? objectType, JsonContract? contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerMember, object? existingValue)
{
if (contract != null && contract.ContractType == JsonContractType.Linq)
{
@@ -301,7 +317,7 @@ private object CreateValueInternal(JsonReader reader, Type objectType, JsonContr
case JsonToken.Bytes:
return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.String:
- string s = (string)reader.Value;
+ string s = (string)reader.Value!;
// string that needs to be returned as a byte array should be base 64 decoded
if (objectType == typeof(byte[]))
@@ -317,7 +333,7 @@ private object CreateValueInternal(JsonReader reader, Type objectType, JsonContr
return EnsureType(reader, s, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.StartConstructor:
- string constructorName = reader.Value.ToString();
+ string constructorName = reader.Value!.ToString()!;
return EnsureType(reader, constructorName, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.Null:
@@ -331,7 +347,7 @@ private object CreateValueInternal(JsonReader reader, Type objectType, JsonContr
return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType);
case JsonToken.Raw:
- return new JRaw((string)reader.Value);
+ return new JRaw((string?)reader.Value);
case JsonToken.Comment:
// ignore
break;
@@ -343,9 +359,9 @@ private object CreateValueInternal(JsonReader reader, Type objectType, JsonContr
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
- private static bool CoerceEmptyStringToNull(Type objectType, JsonContract contract, string s)
+ private static bool CoerceEmptyStringToNull(Type? objectType, JsonContract? contract, string s)
{
- return string.IsNullOrEmpty(s) && objectType != null && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable;
+ return StringUtils.IsNullOrEmpty(s) && objectType != null && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable;
}
internal string GetExpectedDescription(JsonContract contract)
@@ -372,9 +388,9 @@ internal string GetExpectedDescription(JsonContract contract)
}
}
- private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract, JsonProperty containerProperty)
+ private JsonConverter? GetConverter(JsonContract? contract, JsonConverter? memberConverter, JsonContainerContract? containerContract, JsonProperty? containerProperty)
{
- JsonConverter converter = null;
+ JsonConverter? converter = null;
if (memberConverter != null)
{
// member attribute converter
@@ -390,13 +406,12 @@ private JsonConverter GetConverter(JsonContract contract, JsonConverter memberCo
}
else if (contract != null)
{
- JsonConverter matchingConverter;
if (contract.Converter != null)
{
// class attribute converter
converter = contract.Converter;
}
- else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
+ else if (Serializer.GetMatchingConverter(contract.UnderlyingType) is JsonConverter matchingConverter)
{
// passed in converters
converter = matchingConverter;
@@ -410,10 +425,10 @@ private JsonConverter GetConverter(JsonContract contract, JsonConverter memberCo
return converter;
}
- private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
+ private object? CreateObject(JsonReader reader, Type? objectType, JsonContract? contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerMember, object? existingValue)
{
- string id;
- Type resolvedObjectType = objectType;
+ string? id;
+ Type? resolvedObjectType = objectType;
if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.Ignore)
{
@@ -440,7 +455,7 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
reader = tokenReader;
}
- if (ReadMetadataPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out object newValue, out id))
+ if (ReadMetadataPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out object? newValue, out id))
{
return newValue;
}
@@ -448,7 +463,7 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
else
{
reader.ReadAndAssert();
- if (ReadMetadataProperties(reader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out object newValue, out id))
+ if (ReadMetadataProperties(reader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out object? newValue, out id))
{
return newValue;
}
@@ -459,6 +474,9 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
return CreateJObject(reader);
}
+ MiscellaneousUtils.Assert(resolvedObjectType != null);
+ MiscellaneousUtils.Assert(contract != null);
+
switch (contract.ContractType)
{
case JsonContractType.Object:
@@ -490,7 +508,7 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
// if the content is inside $value then read past it
if (Serializer.MetadataPropertyHandling != MetadataPropertyHandling.Ignore
&& reader.TokenType == JsonToken.PropertyName
- && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal))
+ && string.Equals(reader.Value!.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal))
{
reader.ReadAndAssert();
@@ -501,7 +519,7 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing primitive value: " + reader.TokenType);
}
- object value = CreateValueInternal(reader, resolvedObjectType, primitiveContract, member, null, null, existingValue);
+ object? value = CreateValueInternal(reader, resolvedObjectType, primitiveContract, member, null, null, existingValue);
reader.ReadAndAssert();
return value;
@@ -544,7 +562,7 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
if (createdFromNonDefaultCreator)
{
- ObjectConstructor creator = dictionaryContract.OverrideCreator ?? dictionaryContract.ParameterizedCreator;
+ ObjectConstructor creator = (dictionaryContract.OverrideCreator ?? dictionaryContract.ParameterizedCreator)!;
return creator(dictionary);
}
@@ -553,8 +571,8 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
return wrappedDictionary.UnderlyingDictionary;
}
- targetDictionary = dictionary;
- }
+ targetDictionary = dictionary;
+ }
else
{
targetDictionary = PopulateDictionary(dictionaryContract.ShouldCreateWrapper || !(existingValue is IDictionary) ? dictionaryContract.CreateWrapper(existingValue) : (IDictionary)existingValue, reader, dictionaryContract, member, id);
@@ -581,38 +599,29 @@ private object CreateObject(JsonReader reader, Type objectType, JsonContract con
throw JsonSerializationException.Create(reader, message);
}
- private bool ReadMetadataPropertiesToken(JTokenReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id)
+ private bool ReadMetadataPropertiesToken(JTokenReader reader, ref Type? objectType, ref JsonContract? contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerMember, object? existingValue, out object? newValue, out string? id)
{
id = null;
newValue = null;
if (reader.TokenType == JsonToken.StartObject)
{
- JObject current = (JObject)reader.CurrentToken;
+ JObject current = (JObject)reader.CurrentToken!;
- JToken refToken = current[JsonTypeReflector.RefPropertyName];
- if (refToken != null)
+ JProperty? refProperty = current.Property(JsonTypeReflector.RefPropertyName, StringComparison.Ordinal);
+ if (refProperty != null)
{
+ JToken refToken = refProperty.Value;
if (refToken.Type != JTokenType.String && refToken.Type != JTokenType.Null)
{
throw JsonSerializationException.Create(refToken, refToken.Path, "JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName), null);
}
- JToken property = refToken.Parent;
- JToken additionalContent = null;
- if (property.Next != null)
- {
- additionalContent = property.Next;
- }
- else if (property.Previous != null)
- {
- additionalContent = property.Previous;
- }
-
- string reference = (string)refToken;
+ string? reference = (string?)refProperty;
if (reference != null)
{
+ JToken? additionalContent = refProperty.Next ?? refProperty.Previous;
if (additionalContent != null)
{
throw JsonSerializationException.Create(additionalContent, additionalContent.Path, "Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName), null);
@@ -629,15 +638,15 @@ private bool ReadMetadataPropertiesToken(JTokenReader reader, ref Type objectTyp
return true;
}
}
- JToken typeToken = current[JsonTypeReflector.TypePropertyName];
+ JToken? typeToken = current[JsonTypeReflector.TypePropertyName];
if (typeToken != null)
{
- string qualifiedTypeName = (string)typeToken;
+ string? qualifiedTypeName = (string?)typeToken;
JsonReader typeTokenReader = typeToken.CreateReader();
typeTokenReader.ReadAndAssert();
- ResolveTypeName(typeTokenReader, ref objectType, ref contract, member, containerContract, containerMember, qualifiedTypeName);
+ ResolveTypeName(typeTokenReader, ref objectType, ref contract, member, containerContract, containerMember, qualifiedTypeName!);
- JToken valueToken = current[JsonTypeReflector.ValuePropertyName];
+ JToken? valueToken = current[JsonTypeReflector.ValuePropertyName];
if (valueToken != null)
{
while (true)
@@ -645,7 +654,7 @@ private bool ReadMetadataPropertiesToken(JTokenReader reader, ref Type objectTyp
reader.ReadAndAssert();
if (reader.TokenType == JsonToken.PropertyName)
{
- if ((string)reader.Value == JsonTypeReflector.ValuePropertyName)
+ if ((string)reader.Value! == JsonTypeReflector.ValuePropertyName)
{
return false;
}
@@ -656,12 +665,12 @@ private bool ReadMetadataPropertiesToken(JTokenReader reader, ref Type objectTyp
}
}
}
- JToken idToken = current[JsonTypeReflector.IdPropertyName];
+ JToken? idToken = current[JsonTypeReflector.IdPropertyName];
if (idToken != null)
{
- id = (string)idToken;
+ id = (string?)idToken;
}
- JToken valuesToken = current[JsonTypeReflector.ArrayValuesPropertyName];
+ JToken? valuesToken = current[JsonTypeReflector.ArrayValuesPropertyName];
if (valuesToken != null)
{
JsonReader listReader = valuesToken.CreateReader();
@@ -677,14 +686,14 @@ private bool ReadMetadataPropertiesToken(JTokenReader reader, ref Type objectTyp
return false;
}
- private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id)
+ private bool ReadMetadataProperties(JsonReader reader, ref Type? objectType, ref JsonContract? contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerMember, object? existingValue, out object? newValue, out string? id)
{
id = null;
newValue = null;
if (reader.TokenType == JsonToken.PropertyName)
{
- string propertyName = reader.Value.ToString();
+ string propertyName = reader.Value!.ToString()!;
if (propertyName.Length > 0 && propertyName[0] == '$')
{
@@ -694,7 +703,7 @@ private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref
do
{
- propertyName = reader.Value.ToString();
+ propertyName = reader.Value!.ToString()!;
if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
{
@@ -704,7 +713,7 @@ private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref
throw JsonSerializationException.Create(reader, "JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
}
- string reference = reader.Value?.ToString();
+ string? reference = reader.Value?.ToString();
reader.ReadAndAssert();
@@ -719,7 +728,7 @@ private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
{
- TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, reference, newValue.GetType())), null);
+ TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, reference, newValue!.GetType())), null);
}
return true;
@@ -732,7 +741,7 @@ private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref
else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
{
reader.ReadAndAssert();
- string qualifiedTypeName = reader.Value.ToString();
+ string qualifiedTypeName = reader.Value!.ToString()!;
ResolveTypeName(reader, ref objectType, ref contract, member, containerContract, containerMember, qualifiedTypeName);
@@ -752,7 +761,7 @@ private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref
else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
{
reader.ReadAndAssert();
- object list = CreateList(reader, objectType, contract, member, existingValue, id);
+ object? list = CreateList(reader, objectType, contract, member, existingValue, id);
reader.ReadAndAssert();
newValue = list;
return true;
@@ -767,7 +776,7 @@ private bool ReadMetadataProperties(JsonReader reader, ref Type objectType, ref
return false;
}
- private void ResolveTypeName(JsonReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, string qualifiedTypeName)
+ private void ResolveTypeName(JsonReader reader, ref Type? objectType, ref JsonContract? contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerMember, string qualifiedTypeName)
{
TypeNameHandling resolvedTypeNameHandling =
member?.TypeNameHandling
@@ -777,7 +786,7 @@ private void ResolveTypeName(JsonReader reader, ref Type objectType, ref JsonCon
if (resolvedTypeNameHandling != TypeNameHandling.None)
{
- StructMultiKey typeNameKey = ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName);
+ StructMultiKey typeNameKey = ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName);
Type specifiedType;
try
@@ -809,7 +818,7 @@ private void ResolveTypeName(JsonReader reader, ref Type objectType, ref JsonCon
}
objectType = specifiedType;
- contract = GetContractSafe(specifiedType);
+ contract = GetContract(specifiedType);
}
}
@@ -832,15 +841,18 @@ private JsonArrayContract EnsureArrayContract(JsonReader reader, Type objectType
return arrayContract;
}
- private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string id)
+ private object? CreateList(JsonReader reader, Type? objectType, JsonContract? contract, JsonProperty? member, object? existingValue, string? id)
{
- object value;
+ object? value;
if (HasNoDefinedType(contract))
{
return CreateJToken(reader, contract);
}
+ MiscellaneousUtils.Assert(objectType != null);
+ MiscellaneousUtils.Assert(contract != null);
+
JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract);
if (existingValue == null)
@@ -883,17 +895,17 @@ private object CreateList(JsonReader reader, Type objectType, JsonContract contr
{
if (arrayContract.IsMultidimensionalArray)
{
- list = CollectionUtils.ToMultidimensionalArray(list, arrayContract.CollectionItemType, contract.CreatedType.GetArrayRank());
+ list = CollectionUtils.ToMultidimensionalArray(list, arrayContract.CollectionItemType!, contract.CreatedType.GetArrayRank());
}
else if (arrayContract.IsArray)
{
- Array a = Array.CreateInstance(arrayContract.CollectionItemType, list.Count);
+ Array a = Array.CreateInstance(arrayContract.CollectionItemType!, list.Count);
list.CopyTo(a, 0);
list = a;
}
else
{
- ObjectConstructor creator = arrayContract.OverrideCreator ?? arrayContract.ParameterizedCreator;
+ ObjectConstructor creator = (arrayContract.OverrideCreator ?? arrayContract.ParameterizedCreator)!;
return creator(list);
}
@@ -918,7 +930,7 @@ private object CreateList(JsonReader reader, Type objectType, JsonContract contr
return value;
}
- private bool HasNoDefinedType(JsonContract contract)
+ private bool HasNoDefinedType(JsonContract? contract)
{
return (contract == null || contract.UnderlyingType == typeof(object) || contract.ContractType == JsonContractType.Linq
#if HAVE_DYNAMIC
@@ -927,14 +939,15 @@ private bool HasNoDefinedType(JsonContract contract)
);
}
- private object EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType)
+ private object? EnsureType(JsonReader reader, object? value, CultureInfo culture, JsonContract? contract, Type? targetType)
{
if (targetType == null)
{
return value;
}
- Type valueType = ReflectionUtils.GetObjectType(value);
+ MiscellaneousUtils.Assert(contract != null);
+ Type? valueType = ReflectionUtils.GetObjectType(value);
// type of value and type of target don't match
// attempt to convert value's type to target's type
@@ -955,11 +968,15 @@ private object EnsureType(JsonReader reader, object value, CultureInfo culture,
{
if (value is string s)
{
- return EnumUtils.ParseEnum(contract.NonNullableUnderlyingType, null, s, false);
+ return EnumUtils.ParseEnum(
+ contract.NonNullableUnderlyingType,
+ null,
+ s,
+ false);
}
if (ConvertUtils.IsInteger(primitiveContract.TypeCode))
{
- return Enum.ToObject(contract.NonNullableUnderlyingType, value);
+ return Enum.ToObject(contract.NonNullableUnderlyingType, value!);
}
}
else if (contract.NonNullableUnderlyingType == typeof(DateTime))
@@ -993,7 +1010,7 @@ private object EnsureType(JsonReader reader, object value, CultureInfo culture,
return value;
}
- private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
+ private bool SetPropertyValue(JsonProperty property, JsonConverter? propertyConverter, JsonContainerContract? containerContract, JsonProperty? containerProperty, JsonReader reader, object target)
{
bool skipSettingProperty = CalculatePropertyDetails(
property,
@@ -1003,8 +1020,8 @@ private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConve
reader,
target,
out bool useExistingValue,
- out object currentValue,
- out JsonContract propertyContract,
+ out object? currentValue,
+ out JsonContract? propertyContract,
out bool gottenCurrentValue,
out bool ignoredValue);
@@ -1020,16 +1037,16 @@ private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConve
return false;
}
- object value;
+ object? value;
if (propertyConverter != null && propertyConverter.CanRead)
{
- if (!gottenCurrentValue && target != null && property.Readable)
+ if (!gottenCurrentValue && property.Readable)
{
- currentValue = property.ValueProvider.GetValue(target);
+ currentValue = property.ValueProvider!.GetValue(target);
}
- value = DeserializeConvertable(propertyConverter, reader, property.PropertyType, currentValue);
+ value = DeserializeConvertable(propertyConverter, reader, property.PropertyType!, currentValue);
}
else
{
@@ -1042,7 +1059,7 @@ private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConve
if ((!useExistingValue || value != currentValue)
&& ShouldSetPropertyValue(property, containerContract as JsonObjectContract, value))
{
- property.ValueProvider.SetValue(target, value);
+ property.ValueProvider!.SetValue(target, value);
if (property.SetIsSpecified != null)
{
@@ -1063,14 +1080,14 @@ private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConve
private bool CalculatePropertyDetails(
JsonProperty property,
- ref JsonConverter propertyConverter,
- JsonContainerContract containerContract,
- JsonProperty containerProperty,
+ ref JsonConverter? propertyConverter,
+ JsonContainerContract? containerContract,
+ JsonProperty? containerProperty,
JsonReader reader,
object target,
out bool useExistingValue,
- out object currentValue,
- out JsonContract propertyContract,
+ out object? currentValue,
+ out JsonContract? propertyContract,
out bool gottenCurrentValue,
out bool ignoredValue)
{
@@ -1097,14 +1114,15 @@ private bool CalculatePropertyDetails(
if ((objectCreationHandling != ObjectCreationHandling.Replace)
&& (tokenType == JsonToken.StartArray || tokenType == JsonToken.StartObject || propertyConverter != null)
- && property.Readable)
+ && property.Readable
+ && property.PropertyContract?.ContractType != JsonContractType.Linq)
{
- currentValue = property.ValueProvider.GetValue(target);
+ currentValue = property.ValueProvider!.GetValue(target);
gottenCurrentValue = true;
if (currentValue != null)
{
- propertyContract = GetContractSafe(currentValue.GetType());
+ propertyContract = GetContract(currentValue.GetType());
useExistingValue = (!propertyContract.IsReadOnlyOrFixedSize && !propertyContract.UnderlyingType.IsValueType());
}
@@ -1143,7 +1161,7 @@ private bool CalculatePropertyDetails(
}
else
{
- propertyContract = GetContractSafe(currentValue.GetType());
+ propertyContract = GetContract(currentValue.GetType());
if (propertyContract != property.PropertyContract)
{
@@ -1176,7 +1194,7 @@ private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag)
return ((value & flag) == flag);
}
- private bool ShouldSetPropertyValue(JsonProperty property, JsonObjectContract contract, object value)
+ private bool ShouldSetPropertyValue(JsonProperty property, JsonObjectContract? contract, object? value)
{
if (value == null && ResolvedNullValueHandling(contract, property) == NullValueHandling.Ignore)
{
@@ -1334,7 +1352,7 @@ private void OnDeserialized(JsonReader reader, JsonContract contract, object val
contract.InvokeOnDeserialized(value, Serializer._context);
}
- private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id)
+ private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty? containerProperty, string? id)
{
object underlyingDictionary = dictionary is IWrappedDictionary wrappedDictionary ? wrappedDictionary.UnderlyingDictionary : dictionary;
@@ -1357,7 +1375,7 @@ private object PopulateDictionary(IDictionary dictionary, JsonReader reader, Jso
contract.ItemContract = GetContractSafe(contract.DictionaryValueType);
}
- JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty);
+ JsonConverter? dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty);
PrimitiveTypeCode keyTypeCode = (contract.KeyContract is JsonPrimitiveContract keyContract) ? keyContract.TypeCode : PrimitiveTypeCode.Empty;
bool finished = false;
@@ -1366,8 +1384,8 @@ private object PopulateDictionary(IDictionary dictionary, JsonReader reader, Jso
switch (reader.TokenType)
{
case JsonToken.PropertyName:
- object keyValue = reader.Value;
- if (CheckPropertyName(reader, keyValue.ToString()))
+ object keyValue = reader.Value!;
+ if (CheckPropertyName(reader, keyValue.ToString()!))
{
continue;
}
@@ -1382,23 +1400,25 @@ private object PopulateDictionary(IDictionary dictionary, JsonReader reader, Jso
case PrimitiveTypeCode.DateTime:
case PrimitiveTypeCode.DateTimeNullable:
{
- keyValue = DateTimeUtils.TryParseDateTime(keyValue.ToString(), reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out DateTime dt)
+ keyValue = DateTimeUtils.TryParseDateTime(keyValue.ToString()!, reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out DateTime dt)
? dt
- : EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
+ : EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType)!;
break;
}
#if HAVE_DATE_TIME_OFFSET
case PrimitiveTypeCode.DateTimeOffset:
case PrimitiveTypeCode.DateTimeOffsetNullable:
{
- keyValue = DateTimeUtils.TryParseDateTimeOffset(keyValue.ToString(), reader.DateFormatString, reader.Culture, out DateTimeOffset dt)
+ keyValue = DateTimeUtils.TryParseDateTimeOffset(keyValue.ToString()!, reader.DateFormatString, reader.Culture, out DateTimeOffset dt)
? dt
- : EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
+ : EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType)!;
break;
}
#endif
default:
- keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
+ keyValue = contract.KeyContract != null && contract.KeyContract.IsEnum
+ ? EnumUtils.ParseEnum(contract.KeyContract.NonNullableUnderlyingType, (Serializer._contractResolver as DefaultContractResolver)?.NamingStrategy, keyValue.ToString()!, false)
+ : EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType)!;
break;
}
}
@@ -1412,10 +1432,10 @@ private object PopulateDictionary(IDictionary dictionary, JsonReader reader, Jso
throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
}
- object itemValue;
+ object? itemValue;
if (dictionaryValueConverter != null && dictionaryValueConverter.CanRead)
{
- itemValue = DeserializeConvertable(dictionaryValueConverter, reader, contract.DictionaryValueType, null);
+ itemValue = DeserializeConvertable(dictionaryValueConverter, reader, contract.DictionaryValueType!, null);
}
else
{
@@ -1455,7 +1475,7 @@ private object PopulateDictionary(IDictionary dictionary, JsonReader reader, Jso
return underlyingDictionary;
}
- private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
+ private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty? containerProperty, string? id)
{
int rank = contract.UnderlyingType.GetArrayRank();
@@ -1466,8 +1486,8 @@ private object PopulateMultidimensionalArray(IList list, JsonReader reader, Json
OnDeserializing(reader, contract, list);
- JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType);
- JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty);
+ JsonContract? collectionItemContract = GetContractSafe(contract.CollectionItemType);
+ JsonConverter? collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty);
int? previousErrorIndex = null;
Stack listStack = new Stack();
@@ -1495,11 +1515,11 @@ private object PopulateMultidimensionalArray(IList list, JsonReader reader, Json
case JsonToken.Comment:
break;
default:
- object value;
+ object? value;
if (collectionItemConverter != null && collectionItemConverter.CanRead)
{
- value = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType, null);
+ value = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType!, null);
}
else
{
@@ -1586,7 +1606,7 @@ private object PopulateMultidimensionalArray(IList list, JsonReader reader, Json
return list;
}
- private void ThrowUnexpectedEndException(JsonReader reader, JsonContract contract, object currentObject, string message)
+ private void ThrowUnexpectedEndException(JsonReader reader, JsonContract contract, object? currentObject, string message)
{
try
{
@@ -1605,8 +1625,9 @@ private void ThrowUnexpectedEndException(JsonReader reader, JsonContract contrac
}
}
- private object PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id)
+ private object PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty? containerProperty, string? id)
{
+#pragma warning disable CS8600, CS8602, CS8603, CS8604
object underlyingList = list is IWrappedCollection wrappedCollection ? wrappedCollection.UnderlyingCollection : list;
if (id != null)
@@ -1630,7 +1651,7 @@ private object PopulateList(IList list, JsonReader reader, JsonArrayContract con
contract.ItemContract = GetContractSafe(contract.CollectionItemType);
}
- JsonConverter collectionItemConverter = GetConverter(contract.ItemContract, null, contract, containerProperty);
+ JsonConverter? collectionItemConverter = GetConverter(contract.ItemContract, null, contract, containerProperty);
int? previousErrorIndex = null;
@@ -1649,7 +1670,7 @@ private object PopulateList(IList list, JsonReader reader, JsonArrayContract con
case JsonToken.Comment:
break;
default:
- object value;
+ object? value;
if (collectionItemConverter != null && collectionItemConverter.CanRead)
{
@@ -1702,10 +1723,11 @@ private object PopulateList(IList list, JsonReader reader, JsonArrayContract con
OnDeserialized(reader, contract, underlyingList);
return underlyingList;
+#pragma warning restore CS8600, CS8602, CS8603, CS8604
}
#if HAVE_BINARY_SERIALIZATION
- private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, string id)
+ private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty? member, string? id)
{
Type objectType = contract.UnderlyingType;
@@ -1731,7 +1753,7 @@ private object CreateISerializable(JsonReader reader, JsonISerializableContract
switch (reader.TokenType)
{
case JsonToken.PropertyName:
- string memberName = reader.Value.ToString();
+ string memberName = reader.Value!.ToString()!;
if (!reader.Read())
{
throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
@@ -1777,15 +1799,15 @@ private object CreateISerializable(JsonReader reader, JsonISerializableContract
return createdObject;
}
- internal object CreateISerializableItem(JToken token, Type type, JsonISerializableContract contract, JsonProperty member)
+ internal object? CreateISerializableItem(JToken token, Type type, JsonISerializableContract contract, JsonProperty? member)
{
- JsonContract itemContract = GetContractSafe(type);
- JsonConverter itemConverter = GetConverter(itemContract, null, contract, member);
+ JsonContract? itemContract = GetContractSafe(type);
+ JsonConverter? itemConverter = GetConverter(itemContract, null, contract, member);
JsonReader tokenReader = token.CreateReader();
tokenReader.ReadAndAssert(); // Move to first token
- object result;
+ object? result;
if (itemConverter != null && itemConverter.CanRead)
{
result = DeserializeConvertable(itemConverter, tokenReader, type, null);
@@ -1800,7 +1822,7 @@ internal object CreateISerializableItem(JToken token, Type type, JsonISerializab
#endif
#if HAVE_DYNAMIC
- private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty member, string id)
+ private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty? member, string? id)
{
IDynamicMetaObjectProvider newObject;
@@ -1834,7 +1856,7 @@ private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, Js
switch (reader.TokenType)
{
case JsonToken.PropertyName:
- string memberName = reader.Value.ToString();
+ string memberName = reader.Value!.ToString()!;
try
{
@@ -1844,7 +1866,7 @@ private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, Js
}
// first attempt to find a settable property, otherwise fall back to a dynamic set without type
- JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+ JsonProperty? property = contract.Properties.GetClosestMatchProperty(memberName);
if (property != null && property.Writable && !property.Ignored)
{
@@ -1853,7 +1875,7 @@ private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, Js
property.PropertyContract = GetContractSafe(property.PropertyType);
}
- JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.Converter, null, null);
+ JsonConverter? propertyConverter = GetConverter(property.PropertyContract, property.Converter, null, null);
if (!SetPropertyValue(property, propertyConverter, null, member, reader, newObject))
{
@@ -1862,15 +1884,15 @@ private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, Js
}
else
{
- Type t = (JsonTokenUtils.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof(IDynamicMetaObjectProvider);
+ Type t = (JsonTokenUtils.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType! : typeof(IDynamicMetaObjectProvider);
- JsonContract dynamicMemberContract = GetContractSafe(t);
- JsonConverter dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null, member);
+ JsonContract? dynamicMemberContract = GetContractSafe(t);
+ JsonConverter? dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null, member);
- object value;
+ object? value;
if (dynamicMemberConverter != null && dynamicMemberConverter.CanRead)
{
- value = DeserializeConvertable(dynamicMemberConverter, reader, t, null);
+ value = DeserializeConvertable(dynamicMemberConverter!, reader, t, null);
}
else
{
@@ -1913,15 +1935,20 @@ private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, Js
internal class CreatorPropertyContext
{
- public string Name;
- public JsonProperty Property;
- public JsonProperty ConstructorProperty;
+ public readonly string Name;
+ public JsonProperty? Property;
+ public JsonProperty? ConstructorProperty;
public PropertyPresence? Presence;
- public object Value;
+ public object? Value;
public bool Used;
+
+ public CreatorPropertyContext(string name)
+ {
+ Name = name;
+ }
}
- private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor creator, string id)
+ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty? containerProperty, ObjectConstructor creator, string? id)
{
ValidationUtils.ArgumentNotNull(creator, nameof(creator));
@@ -1949,10 +1976,9 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
{
if (propertyContexts.All(p => p.Property != property))
{
- propertyContexts.Add(new CreatorPropertyContext
+ propertyContexts.Add(new CreatorPropertyContext(property.PropertyName!)
{
Property = property,
- Name = property.PropertyName,
Presence = PropertyPresence.None
});
}
@@ -1960,7 +1986,7 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
}
}
- object[] creatorParameterValues = new object[contract.CreatorParameters.Count];
+ object?[] creatorParameterValues = new object?[contract.CreatorParameters.Count];
foreach (CreatorPropertyContext context in propertyContexts)
{
@@ -1969,7 +1995,7 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
{
if (context.Property != null && context.Presence == null)
{
- object v = context.Value;
+ object? v = context.Value;
PropertyPresence propertyPresence;
if (v == null)
{
@@ -1990,10 +2016,10 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
}
}
- JsonProperty constructorProperty = context.ConstructorProperty;
+ JsonProperty? constructorProperty = context.ConstructorProperty;
if (constructorProperty == null && context.Property != null)
{
- constructorProperty = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName, context.Property.UnderlyingName);
+ constructorProperty = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName!, context.Property.UnderlyingName!);
}
if (constructorProperty != null && !constructorProperty.Ignored)
@@ -2015,7 +2041,7 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
reader,
constructorProperty.GetResolvedDefaultValue(),
CultureInfo.InvariantCulture,
- constructorProperty.PropertyContract,
+ constructorProperty.PropertyContract!,
constructorProperty.PropertyType);
}
}
@@ -2049,17 +2075,17 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
}
JsonProperty property = context.Property;
- object value = context.Value;
+ object? value = context.Value;
if (ShouldSetPropertyValue(property, contract, value))
{
- property.ValueProvider.SetValue(createdObject, value);
+ property.ValueProvider!.SetValue(createdObject, value);
context.Used = true;
}
else if (!property.Writable && value != null)
{
// handle readonly collection/dictionary properties
- JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType);
+ JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType!);
if (propertyContract.ContractType == JsonContractType.Array)
{
@@ -2067,15 +2093,22 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
if (propertyArrayContract.CanDeserialize && !propertyArrayContract.IsReadOnlyOrFixedSize)
{
- object createdObjectCollection = property.ValueProvider.GetValue(createdObject);
+ object? createdObjectCollection = property.ValueProvider!.GetValue(createdObject);
if (createdObjectCollection != null)
{
+ propertyArrayContract = (JsonArrayContract)GetContract(createdObjectCollection.GetType());
+
IList createdObjectCollectionWrapper = (propertyArrayContract.ShouldCreateWrapper) ? propertyArrayContract.CreateWrapper(createdObjectCollection) : (IList)createdObjectCollection;
- IList newValues = (propertyArrayContract.ShouldCreateWrapper) ? propertyArrayContract.CreateWrapper(value) : (IList)value;
- foreach (object newValue in newValues)
+ // Don't attempt to populate array/read-only list
+ if (!createdObjectCollectionWrapper.IsFixedSize)
{
- createdObjectCollectionWrapper.Add(newValue);
+ IList newValues = (propertyArrayContract.ShouldCreateWrapper) ? propertyArrayContract.CreateWrapper(value) : (IList)value;
+
+ foreach (object newValue in newValues)
+ {
+ createdObjectCollectionWrapper.Add(newValue);
+ }
}
}
}
@@ -2086,7 +2119,7 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
if (!dictionaryContract.IsReadOnlyOrFixedSize)
{
- object createdObjectDictionary = property.ValueProvider.GetValue(createdObject);
+ object? createdObjectDictionary = property.ValueProvider!.GetValue(createdObject);
if (createdObjectDictionary != null)
{
IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary)createdObjectDictionary;
@@ -2149,14 +2182,14 @@ private object CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObj
return createdObject;
}
- private object DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, object existingValue)
+ private object? DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, object? existingValue)
{
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
{
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Started deserializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, objectType, converter.GetType())), null);
}
- object value = converter.ReadJson(reader, objectType, existingValue, GetInternalSerializer());
+ object? value = converter.ReadJson(reader, objectType, existingValue, GetInternalSerializer());
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
{
@@ -2166,7 +2199,7 @@ private object DeserializeConvertable(JsonConverter converter, JsonReader reader
return value;
}
- private List ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
+ private List ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty? containerProperty, JsonReader reader, Type objectType)
{
List propertyValues = new List();
bool exit = false;
@@ -2175,41 +2208,43 @@ private List ResolvePropertyAndCreatorValues(JsonObjectC
switch (reader.TokenType)
{
case JsonToken.PropertyName:
- string memberName = reader.Value.ToString();
+ string memberName = reader.Value!.ToString()!;
- CreatorPropertyContext creatorPropertyContext = new CreatorPropertyContext
+ CreatorPropertyContext creatorPropertyContext = new CreatorPropertyContext(memberName)
{
- Name = reader.Value.ToString(),
ConstructorProperty = contract.CreatorParameters.GetClosestMatchProperty(memberName),
Property = contract.Properties.GetClosestMatchProperty(memberName)
};
propertyValues.Add(creatorPropertyContext);
- JsonProperty property = creatorPropertyContext.ConstructorProperty ?? creatorPropertyContext.Property;
- if (property != null && !property.Ignored)
+ JsonProperty? property = creatorPropertyContext.ConstructorProperty ?? creatorPropertyContext.Property;
+ if (property != null)
{
- if (property.PropertyContract == null)
+ if (!property.Ignored)
{
- property.PropertyContract = GetContractSafe(property.PropertyType);
- }
+ if (property.PropertyContract == null)
+ {
+ property.PropertyContract = GetContractSafe(property.PropertyType);
+ }
- JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.Converter, contract, containerProperty);
+ JsonConverter? propertyConverter = GetConverter(property.PropertyContract, property.Converter, contract, containerProperty);
- if (!reader.ReadForType(property.PropertyContract, propertyConverter != null))
- {
- throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
- }
+ if (!reader.ReadForType(property.PropertyContract, propertyConverter != null))
+ {
+ throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+ }
- if (propertyConverter != null && propertyConverter.CanRead)
- {
- creatorPropertyContext.Value = DeserializeConvertable(propertyConverter, reader, property.PropertyType, null);
- }
- else
- {
- creatorPropertyContext.Value = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null);
+ if (propertyConverter != null && propertyConverter.CanRead)
+ {
+ creatorPropertyContext.Value = DeserializeConvertable(propertyConverter, reader, property.PropertyType!, null);
+ }
+ else
+ {
+ creatorPropertyContext.Value = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null);
+ }
+
+ continue;
}
-
- continue;
}
else
{
@@ -2223,7 +2258,7 @@ private List ResolvePropertyAndCreatorValues(JsonObjectC
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}.".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null);
}
- if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
+ if ((contract.MissingMemberHandling ?? Serializer._missingMemberHandling) == MissingMemberHandling.Error)
{
throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
}
@@ -2256,9 +2291,9 @@ private List ResolvePropertyAndCreatorValues(JsonObjectC
return propertyValues;
}
- public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultCreator)
+ public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty? containerMember, JsonProperty? containerProperty, string? id, out bool createdFromNonDefaultCreator)
{
- object newObject = null;
+ object? newObject = null;
if (objectContract.OverrideCreator != null)
{
@@ -2299,12 +2334,12 @@ public object CreateNewObject(JsonReader reader, JsonObjectContract objectContra
return newObject;
}
- private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id)
+ private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty? member, string? id)
{
OnDeserializing(reader, contract, newObject);
// only need to keep a track of properties' presence if they are required or a value should be defaulted if missing
- Dictionary propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate))
+ Dictionary? propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate))
? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None)
: null;
@@ -2322,7 +2357,7 @@ private object PopulateObject(object newObject, JsonReader reader, JsonObjectCon
{
case JsonToken.PropertyName:
{
- string propertyName = reader.Value.ToString();
+ string propertyName = reader.Value!.ToString()!;
if (CheckPropertyName(reader, propertyName))
{
@@ -2333,7 +2368,7 @@ private object PopulateObject(object newObject, JsonReader reader, JsonObjectCon
{
// attempt exact case match first
// then try match ignoring case
- JsonProperty property = contract.Properties.GetClosestMatchProperty(propertyName);
+ JsonProperty? property = contract.Properties.GetClosestMatchProperty(propertyName);
if (property == null)
{
@@ -2342,7 +2377,7 @@ private object PopulateObject(object newObject, JsonReader reader, JsonObjectCon
TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}".FormatWith(CultureInfo.InvariantCulture, propertyName, contract.UnderlyingType)), null);
}
- if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
+ if ((contract.MissingMemberHandling ?? Serializer._missingMemberHandling) == MissingMemberHandling.Error)
{
throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, propertyName, contract.UnderlyingType.Name));
}
@@ -2373,7 +2408,7 @@ private object PopulateObject(object newObject, JsonReader reader, JsonObjectCon
property.PropertyContract = GetContractSafe(property.PropertyType);
}
- JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.Converter, contract, member);
+ JsonConverter? propertyConverter = GetConverter(property.PropertyContract, property.Converter, contract, member);
if (!reader.ReadForType(property.PropertyContract, propertyConverter != null))
{
@@ -2467,13 +2502,13 @@ private bool CheckPropertyName(JsonReader reader, string memberName)
return false;
}
- private void SetExtensionData(JsonObjectContract contract, JsonProperty member, JsonReader reader, string memberName, object o)
+ private void SetExtensionData(JsonObjectContract contract, JsonProperty? member, JsonReader reader, string memberName, object o)
{
if (contract.ExtensionDataSetter != null)
{
try
{
- object value = ReadExtensionDataValue(contract, member, reader);
+ object? value = ReadExtensionDataValue(contract, member, reader);
contract.ExtensionDataSetter(o, memberName, value);
}
@@ -2488,9 +2523,9 @@ private void SetExtensionData(JsonObjectContract contract, JsonProperty member,
}
}
- private object ReadExtensionDataValue(JsonObjectContract contract, JsonProperty member, JsonReader reader)
+ private object? ReadExtensionDataValue(JsonObjectContract contract, JsonProperty? member, JsonReader reader)
{
- object value;
+ object? value;
if (contract.ExtensionDataIsJToken)
{
value = JToken.ReadFrom(reader);
@@ -2527,7 +2562,7 @@ private void EndProcessProperty(object newObject, JsonReader reader, JsonObjectC
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && property.Writable)
{
- property.ValueProvider.SetValue(newObject, EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType));
+ property.ValueProvider!.SetValue(newObject, EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract!, property.PropertyType));
}
}
break;
@@ -2557,7 +2592,7 @@ private void EndProcessProperty(object newObject, JsonReader reader, JsonObjectC
}
}
- private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dictionary requiredProperties)
+ private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dictionary? requiredProperties)
{
if (property != null && requiredProperties != null)
{
@@ -2565,7 +2600,7 @@ private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dicti
switch (reader.TokenType)
{
case JsonToken.String:
- propertyPresence = (CoerceEmptyStringToNull(property.PropertyType, property.PropertyContract, (string)reader.Value))
+ propertyPresence = (CoerceEmptyStringToNull(property.PropertyType, property.PropertyContract, (string)reader.Value!))
? PropertyPresence.Null
: PropertyPresence.Value;
break;
@@ -2600,4 +2635,5 @@ private void HandleError(JsonReader reader, bool readPastError, int initialDepth
}
}
}
+#nullable disable
}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalWriter.cs
index 32759f7784..e95b84c53f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerInternalWriter.cs
@@ -37,18 +37,20 @@
using Microsoft.IdentityModel.Json.Linq;
using Microsoft.IdentityModel.Json.Utilities;
using System.Runtime.Serialization;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
using System.Linq;
-
#endif
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class JsonSerializerInternalWriter : JsonSerializerInternalBase
{
- private Type _rootType;
+ private Type? _rootType;
private int _rootLevel;
private readonly List _serializeStack = new List();
@@ -57,7 +59,7 @@ public JsonSerializerInternalWriter(JsonSerializer serializer)
{
}
- public void Serialize(JsonWriter jsonWriter, object value, Type objectType)
+ public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType)
{
if (jsonWriter == null)
{
@@ -67,13 +69,13 @@ public void Serialize(JsonWriter jsonWriter, object value, Type objectType)
_rootType = objectType;
_rootLevel = _serializeStack.Count + 1;
- JsonContract contract = GetContractSafe(value);
+ JsonContract? contract = GetContractSafe(value);
try
{
if (ShouldWriteReference(value, null, contract, null, null))
{
- WriteReference(jsonWriter, value);
+ WriteReference(jsonWriter, value!);
}
else
{
@@ -113,17 +115,22 @@ private JsonSerializerProxy GetInternalSerializer()
return InternalSerializer;
}
- private JsonContract GetContractSafe(object value)
+ private JsonContract? GetContractSafe(object? value)
{
if (value == null)
{
return null;
}
+ return GetContract(value);
+ }
+
+ private JsonContract GetContract(object value)
+ {
return Serializer._contractResolver.ResolveContract(value.GetType());
}
- private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+ private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerProperty)
{
if (contract.TypeCode == PrimitiveTypeCode.Bytes)
{
@@ -145,7 +152,7 @@ private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveCo
JsonWriter.WriteValue(writer, contract.TypeCode, value);
}
- private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+ private void SerializeValue(JsonWriter writer, object? value, JsonContract? valueContract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerProperty)
{
if (value == null)
{
@@ -153,7 +160,9 @@ private void SerializeValue(JsonWriter writer, object value, JsonContract valueC
return;
}
- JsonConverter converter =
+ MiscellaneousUtils.Assert(valueContract != null);
+
+ JsonConverter? converter =
member?.Converter ??
containerProperty?.ItemConverter ??
containerContract?.ItemConverter ??
@@ -209,7 +218,7 @@ private void SerializeValue(JsonWriter writer, object value, JsonContract valueC
}
}
- private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private bool? ResolveIsReference(JsonContract contract, JsonProperty? property, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
bool? isReference = null;
@@ -237,12 +246,15 @@ private void SerializeValue(JsonWriter writer, object value, JsonContract valueC
return isReference;
}
- private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private bool ShouldWriteReference(object? value, JsonProperty? property, JsonContract? valueContract, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
if (value == null)
{
return false;
}
+
+ MiscellaneousUtils.Assert(valueContract != null);
+
if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String)
{
return false;
@@ -270,7 +282,7 @@ private bool ShouldWriteReference(object value, JsonProperty property, JsonContr
return Serializer.GetReferenceResolver().IsReferenced(this, value);
}
- private bool ShouldWriteProperty(object memberValue, JsonObjectContract containerContract, JsonProperty property)
+ private bool ShouldWriteProperty(object? memberValue, JsonObjectContract? containerContract, JsonProperty property)
{
if (memberValue == null && ResolvedNullValueHandling(containerContract, property) == NullValueHandling.Ignore)
{
@@ -286,9 +298,16 @@ private bool ShouldWriteProperty(object memberValue, JsonObjectContract containe
return true;
}
- private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)
+ private bool CheckForCircularReference(JsonWriter writer, object? value, JsonProperty? property, JsonContract? contract, JsonContainerContract? containerContract, JsonProperty? containerProperty)
{
- if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
+ if (value == null)
+ {
+ return true;
+ }
+
+ MiscellaneousUtils.Assert(contract != null);
+
+ if (contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String)
{
return true;
}
@@ -376,12 +395,25 @@ private string GetReference(JsonWriter writer, object value)
}
}
- internal static bool TryConvertToString(object value, Type type, out string s)
+ internal static bool TryConvertToString(object value, Type type, [NotNullWhen(true)]out string? s)
{
+#if HAVE_DATE_ONLY
+ if (value is DateOnly dateOnly)
+ {
+ s = dateOnly.ToString("yyyy'-'MM'-'dd", CultureInfo.InvariantCulture);
+ return true;
+ }
+ if (value is TimeOnly timeOnly)
+ {
+ s = timeOnly.ToString("HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture);
+ return true;
+ }
+#endif
+
#if HAVE_TYPE_DESCRIPTOR
if (JsonTypeReflector.CanTypeDescriptorConvertString(type, out TypeConverter converter))
{
- s = converter.ConvertToInvariantString(value);
+ s = converter.ConvertToInvariantString(value)!;
return true;
}
#endif
@@ -394,10 +426,9 @@ internal static bool TryConvertToString(object value, Type type, out string s)
}
#endif
- type = value as Type;
- if (type != null)
+ if (value is Type t)
{
- s = type.AssemblyQualifiedName;
+ s = t.AssemblyQualifiedName!;
return true;
}
@@ -409,7 +440,7 @@ private void SerializeString(JsonWriter writer, object value, JsonStringContract
{
OnSerializing(writer, contract, value);
- TryConvertToString(value, contract.UnderlyingType, out string s);
+ TryConvertToString(value, contract.UnderlyingType, out string? s);
writer.WriteValue(s);
OnSerialized(writer, contract, value);
@@ -435,7 +466,7 @@ private void OnSerialized(JsonWriter writer, JsonContract contract, object value
contract.InvokeOnSerialized(value, Serializer._context);
}
- private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty? member, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
OnSerializing(writer, contract, value);
@@ -450,7 +481,7 @@ private void SerializeObject(JsonWriter writer, object value, JsonObjectContract
JsonProperty property = contract.Properties[index];
try
{
- if (!CalculatePropertyValues(writer, value, contract, member, property, out JsonContract memberContract, out object memberValue))
+ if (!CalculatePropertyValues(writer, value, contract, member, property, out JsonContract? memberContract, out object? memberValue))
{
continue;
}
@@ -471,13 +502,13 @@ private void SerializeObject(JsonWriter writer, object value, JsonObjectContract
}
}
- IEnumerable> extensionData = contract.ExtensionDataGetter?.Invoke(value);
+ IEnumerable>? extensionData = contract.ExtensionDataGetter?.Invoke(value);
if (extensionData != null)
{
foreach (KeyValuePair e in extensionData)
{
- JsonContract keyContract = GetContractSafe(e.Key);
- JsonContract valueContract = GetContractSafe(e.Value);
+ JsonContract keyContract = GetContract(e.Key);
+ JsonContract? valueContract = GetContractSafe(e.Value);
string propertyName = GetPropertyName(writer, e.Key, keyContract, out _);
@@ -488,7 +519,7 @@ private void SerializeObject(JsonWriter writer, object value, JsonObjectContract
if (ShouldWriteReference(e.Value, null, valueContract, contract, member))
{
writer.WritePropertyName(propertyName);
- WriteReference(writer, e.Value);
+ WriteReference(writer, e.Value!);
}
else
{
@@ -511,16 +542,16 @@ private void SerializeObject(JsonWriter writer, object value, JsonObjectContract
OnSerialized(writer, contract, value);
}
- private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, out JsonContract memberContract, out object memberValue)
+ private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, JsonProperty? member, JsonProperty property, [NotNullWhen(true)]out JsonContract? memberContract, out object? memberValue)
{
if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value))
{
if (property.PropertyContract == null)
{
- property.PropertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType);
+ property.PropertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType!);
}
- memberValue = property.ValueProvider.GetValue(value);
+ memberValue = property.ValueProvider!.GetValue(value);
memberContract = (property.PropertyContract.IsSealed) ? property.PropertyContract : GetContractSafe(memberValue);
if (ShouldWriteProperty(memberValue, contract as JsonObjectContract, property))
@@ -528,7 +559,7 @@ private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContai
if (ShouldWriteReference(memberValue, property, memberContract, contract, member))
{
property.WritePropertyName(writer);
- WriteReference(writer, memberValue);
+ WriteReference(writer, memberValue!);
return false;
}
@@ -539,7 +570,7 @@ private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContai
if (memberValue == null)
{
- JsonObjectContract objectContract = contract as JsonObjectContract;
+ JsonObjectContract? objectContract = contract as JsonObjectContract;
Required resolvedRequired = property._required ?? objectContract?.ItemRequired ?? Required.Default;
if (resolvedRequired == Required.Always)
{
@@ -551,7 +582,9 @@ private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContai
}
}
+#pragma warning disable CS8762 // Parameter must have a non-null value when exiting in some condition.
return true;
+#pragma warning restore CS8762 // Parameter must have a non-null value when exiting in some condition.
}
}
@@ -560,7 +593,7 @@ private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContai
return false;
}
- private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty? member, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
writer.WriteStartObject();
@@ -576,14 +609,14 @@ private void WriteObjectStart(JsonWriter writer, object value, JsonContract cont
}
}
- private bool HasCreatorParameter(JsonContainerContract contract, JsonProperty property)
+ private bool HasCreatorParameter(JsonContainerContract? contract, JsonProperty property)
{
if (!(contract is JsonObjectContract objectContract))
{
return false;
}
- return objectContract.CreatorParameters.Contains(property.PropertyName);
+ return objectContract.CreatorParameters.Contains(property.PropertyName!);
}
private void WriteReferenceIdProperty(JsonWriter writer, Type type, object value)
@@ -627,7 +660,7 @@ private bool HasFlag(TypeNameHandling value, TypeNameHandling flag)
return ((value & flag) == flag);
}
- private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty))
{
@@ -658,7 +691,7 @@ private void SerializeConvertable(JsonWriter writer, JsonConverter converter, ob
}
}
- private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty? member, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
object underlyingList = values is IWrappedCollection wrappedCollection ? wrappedCollection.UnderlyingCollection : values;
@@ -678,7 +711,7 @@ private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContr
{
try
{
- JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+ JsonContract? valueContract = contract.FinalItemContract ?? GetContractSafe(value);
if (ShouldWriteReference(value, null, valueContract, contract, member))
{
@@ -721,7 +754,7 @@ private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContr
OnSerialized(writer, contract, underlyingList);
}
- private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty? member, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
OnSerializing(writer, contract, values);
@@ -741,7 +774,7 @@ private void SerializeMultidimensionalArray(JsonWriter writer, Array values, Jso
OnSerialized(writer, contract, values);
}
- private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, int initialDepth, int[] indices)
+ private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty? member, int initialDepth, int[] indices)
{
int dimension = indices.Length;
int[] newIndices = new int[dimension + 1];
@@ -759,11 +792,11 @@ private void SerializeMultidimensionalArray(JsonWriter writer, Array values, Jso
if (isTopLevel)
{
- object value = values.GetValue(newIndices);
+ object value = values.GetValue(newIndices)!;
try
{
- JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+ JsonContract? valueContract = contract.FinalItemContract ?? GetContractSafe(value);
if (ShouldWriteReference(value, null, valueContract, contract, member))
{
@@ -798,7 +831,7 @@ private void SerializeMultidimensionalArray(JsonWriter writer, Array values, Jso
writer.WriteEndArray();
}
- private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+ private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerProperty)
{
bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays);
// don't make readonly fields that aren't creator parameters the referenced value because they can't be deserialized to
@@ -834,7 +867,7 @@ private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract
#if HAVE_SECURITY_SAFE_CRITICAL_ATTRIBUTE
[SecuritySafeCritical]
#endif
- private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty? member, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
if (!JsonTypeReflector.FullyTrusted)
{
@@ -855,12 +888,12 @@ private void SerializeISerializable(JsonWriter writer, ISerializable value, Json
foreach (SerializationEntry serializationEntry in serializationInfo)
{
- JsonContract valueContract = GetContractSafe(serializationEntry.Value);
+ JsonContract? valueContract = GetContractSafe(serializationEntry.Value);
if (ShouldWriteReference(serializationEntry.Value, null, valueContract, contract, member))
{
writer.WritePropertyName(serializationEntry.Name);
- WriteReference(writer, serializationEntry.Value);
+ WriteReference(writer, serializationEntry.Value!);
}
else if (CheckForCircularReference(writer, serializationEntry.Value, null, valueContract, contract, member))
{
@@ -877,7 +910,7 @@ private void SerializeISerializable(JsonWriter writer, ISerializable value, Json
#endif
#if HAVE_DYNAMIC
- private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty? member, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
OnSerializing(writer, contract, value);
_serializeStack.Add(value);
@@ -895,7 +928,7 @@ private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider valu
{
try
{
- if (!CalculatePropertyValues(writer, value, contract, member, property, out JsonContract memberContract, out object memberValue))
+ if (!CalculatePropertyValues(writer, value, contract, member, property, out JsonContract? memberContract, out object? memberValue))
{
continue;
}
@@ -919,11 +952,11 @@ private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider valu
foreach (string memberName in value.GetDynamicMemberNames())
{
- if (contract.TryGetMember(value, memberName, out object memberValue))
+ if (contract.TryGetMember(value, memberName, out object? memberValue))
{
try
{
- JsonContract valueContract = GetContractSafe(memberValue);
+ JsonContract? valueContract = GetContractSafe(memberValue);
if (!ShouldWriteDynamicProperty(memberValue))
{
@@ -961,7 +994,7 @@ private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider valu
}
#endif
- private bool ShouldWriteDynamicProperty(object memberValue)
+ private bool ShouldWriteDynamicProperty(object? memberValue)
{
if (Serializer._nullValueHandling == NullValueHandling.Ignore && memberValue == null)
{
@@ -977,7 +1010,7 @@ private bool ShouldWriteDynamicProperty(object memberValue)
return true;
}
- private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
+ private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty? member, JsonContainerContract? containerContract, JsonProperty? containerProperty)
{
TypeNameHandling resolvedTypeNameHandling =
member?.TypeNameHandling
@@ -995,7 +1028,7 @@ private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract
{
if (member != null)
{
- if (contract.NonNullableUnderlyingType != member.PropertyContract.CreatedType)
+ if (contract.NonNullableUnderlyingType != member.PropertyContract!.CreatedType)
{
return true;
}
@@ -1021,8 +1054,9 @@ private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract
return false;
}
- private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
+ private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty? member, JsonContainerContract? collectionContract, JsonProperty? containerProperty)
{
+#pragma warning disable CS8600, CS8602, CS8604
object underlyingDictionary = values is IWrappedDictionary wrappedDictionary ? wrappedDictionary.UnderlyingDictionary : values;
OnSerializing(writer, contract, underlyingDictionary);
@@ -1059,7 +1093,7 @@ private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDict
try
{
object value = entry.Value;
- JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
+ JsonContract? valueContract = contract.FinalItemContract ?? GetContractSafe(value);
if (ShouldWriteReference(value, null, valueContract, contract, member))
{
@@ -1101,6 +1135,7 @@ private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDict
_serializeStack.RemoveAt(_serializeStack.Count - 1);
OnSerialized(writer, contract, underlyingDictionary);
+#pragma warning restore CS8600, CS8602, CS8604
}
private string GetPropertyName(JsonWriter writer, object name, JsonContract contract, out bool escape)
@@ -1150,16 +1185,16 @@ private string GetPropertyName(JsonWriter writer, object name, JsonContract cont
{
escape = true;
- if (primitiveContract.IsEnum && EnumUtils.TryToString(primitiveContract.NonNullableUnderlyingType, name, null, out string enumName))
+ if (primitiveContract.IsEnum && EnumUtils.TryToString(primitiveContract.NonNullableUnderlyingType, name, null, out string? enumName))
{
return enumName;
}
- return Convert.ToString(name, CultureInfo.InvariantCulture);
+ return Convert.ToString(name, CultureInfo.InvariantCulture)!;
}
}
}
- else if (TryConvertToString(name, name.GetType(), out string propertyName))
+ else if (TryConvertToString(name, name.GetType(), out string? propertyName))
{
escape = true;
return propertyName;
@@ -1167,7 +1202,7 @@ private string GetPropertyName(JsonWriter writer, object name, JsonContract cont
else
{
escape = true;
- return name.ToString();
+ return name.ToString()!;
}
}
@@ -1220,4 +1255,5 @@ private bool IsSpecified(JsonWriter writer, JsonProperty property, object target
return isSpecified;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerProxy.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerProxy.cs
index 30fdb0bfaf..7023e1290a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerProxy.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonSerializerProxy.cs
@@ -32,31 +32,32 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class JsonSerializerProxy : JsonSerializer
{
- private readonly JsonSerializerInternalReader _serializerReader;
- private readonly JsonSerializerInternalWriter _serializerWriter;
- private readonly JsonSerializer _serializer;
+ private readonly JsonSerializerInternalReader? _serializerReader;
+ private readonly JsonSerializerInternalWriter? _serializerWriter;
+ internal readonly JsonSerializer _serializer;
- public override event EventHandler Error
+ public override event EventHandler? Error
{
add => _serializer.Error += value;
remove => _serializer.Error -= value;
}
- public override IReferenceResolver ReferenceResolver
+ public override IReferenceResolver? ReferenceResolver
{
get => _serializer.ReferenceResolver;
set => _serializer.ReferenceResolver = value;
}
- public override ITraceWriter TraceWriter
+ public override ITraceWriter? TraceWriter
{
get => _serializer.TraceWriter;
set => _serializer.TraceWriter = value;
}
- public override IEqualityComparer EqualityComparer
+ public override IEqualityComparer? EqualityComparer
{
get => _serializer.EqualityComparer;
set => _serializer.EqualityComparer = value;
@@ -137,12 +138,12 @@ public override ConstructorHandling ConstructorHandling
set => _serializer.ConstructorHandling = value;
}
- //[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
- //public override SerializationBinder Binder
- //{
- // get => _serializer.Binder;
- // set => _serializer.Binder = value;
- //}
+ [Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
+ public override SerializationBinder Binder
+ {
+ get => _serializer.Binder;
+ set => _serializer.Binder = value;
+ }
public override ISerializationBinder SerializationBinder
{
@@ -230,7 +231,7 @@ internal JsonSerializerInternalBase GetInternalSerializer()
}
else
{
- return _serializerWriter;
+ return _serializerWriter!;
}
}
@@ -250,7 +251,7 @@ public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter)
_serializer = serializerWriter.Serializer;
}
- internal override object DeserializeInternal(JsonReader reader, Type objectType)
+ internal override object? DeserializeInternal(JsonReader reader, Type? objectType)
{
if (_serializerReader != null)
{
@@ -274,7 +275,7 @@ internal override void PopulateInternal(JsonReader reader, object target)
}
}
- internal override void SerializeInternal(JsonWriter jsonWriter, object value, Type rootType)
+ internal override void SerializeInternal(JsonWriter jsonWriter, object? value, Type? rootType)
{
if (_serializerWriter != null)
{
@@ -286,4 +287,5 @@ internal override void SerializeInternal(JsonWriter jsonWriter, object value, Ty
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonStringContract.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonStringContract.cs
index ea4ec0c1ee..d743ccdc6a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonStringContract.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonStringContract.cs
@@ -42,4 +42,4 @@ public JsonStringContract(Type underlyingType)
ContractType = JsonContractType.String;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonTypeReflector.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonTypeReflector.cs
index 680074d6f6..a2089741e1 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonTypeReflector.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/JsonTypeReflector.cs
@@ -33,6 +33,7 @@
using System.Security.Permissions;
#endif
using Microsoft.IdentityModel.Json.Utilities;
+using System.Runtime.CompilerServices;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
@@ -42,6 +43,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal static class JsonTypeReflector
{
private static bool? _dynamicCodeGeneration;
@@ -58,15 +60,15 @@ internal static class JsonTypeReflector
public const string ConcurrentDictionaryTypeName = "System.Collections.Concurrent.ConcurrentDictionary`2";
- private static readonly ThreadSafeStore> CreatorCache =
- new ThreadSafeStore>(GetCreator);
+ private static readonly ThreadSafeStore> CreatorCache =
+ new ThreadSafeStore>(GetCreator);
#if !(NET20 || DOTNET)
- private static readonly ThreadSafeStore AssociatedMetadataTypesCache = new ThreadSafeStore(GetAssociateMetadataTypeFromAttribute);
- private static ReflectionObject _metadataTypeAttributeReflectionObject;
+ private static readonly ThreadSafeStore AssociatedMetadataTypesCache = new ThreadSafeStore(GetAssociateMetadataTypeFromAttribute);
+ private static ReflectionObject? _metadataTypeAttributeReflectionObject;
#endif
- public static T GetCachedAttribute(object attributeProvider) where T : Attribute
+ public static T? GetCachedAttribute(object attributeProvider) where T : Attribute
{
return CachedAttributeGetter.GetAttribute(attributeProvider);
}
@@ -96,14 +98,14 @@ public static bool CanTypeDescriptorConvertString(Type type, out TypeConverter t
#endif
#if HAVE_DATA_CONTRACTS
- public static DataContractAttribute GetDataContractAttribute(Type type)
+ public static DataContractAttribute? GetDataContractAttribute(Type type)
{
// DataContractAttribute does not have inheritance
- Type currentType = type;
+ Type? currentType = type;
while (currentType != null)
{
- DataContractAttribute result = CachedAttributeGetter.GetAttribute(currentType);
+ DataContractAttribute? result = CachedAttributeGetter.GetAttribute(currentType);
if (result != null)
{
return result;
@@ -115,7 +117,7 @@ public static DataContractAttribute GetDataContractAttribute(Type type)
return null;
}
- public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo)
+ public static DataMemberAttribute? GetDataMemberAttribute(MemberInfo memberInfo)
{
// DataMemberAttribute does not have inheritance
@@ -127,16 +129,16 @@ public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo)
// search property and then search base properties if nothing is returned and the property is virtual
PropertyInfo propertyInfo = (PropertyInfo)memberInfo;
- DataMemberAttribute result = CachedAttributeGetter.GetAttribute(propertyInfo);
+ DataMemberAttribute? result = CachedAttributeGetter.GetAttribute(propertyInfo);
if (result == null)
{
if (propertyInfo.IsVirtual())
{
- Type currentType = propertyInfo.DeclaringType;
+ Type? currentType = propertyInfo.DeclaringType;
while (result == null && currentType != null)
{
- PropertyInfo baseProperty = (PropertyInfo)ReflectionUtils.GetMemberInfoFromType(currentType, propertyInfo);
+ PropertyInfo? baseProperty = (PropertyInfo?)ReflectionUtils.GetMemberInfoFromType(currentType, propertyInfo);
if (baseProperty != null && baseProperty.IsVirtual())
{
result = CachedAttributeGetter.GetAttribute(baseProperty);
@@ -153,14 +155,14 @@ public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo)
public static MemberSerialization GetObjectMemberSerialization(Type objectType, bool ignoreSerializableAttribute)
{
- JsonObjectAttribute objectAttribute = GetCachedAttribute(objectType);
+ JsonObjectAttribute? objectAttribute = GetCachedAttribute(objectType);
if (objectAttribute != null)
{
return objectAttribute.MemberSerialization;
}
#if HAVE_DATA_CONTRACTS
- DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
+ DataContractAttribute? dataContractAttribute = GetDataContractAttribute(objectType);
if (dataContractAttribute != null)
{
return MemberSerialization.OptIn;
@@ -178,13 +180,13 @@ public static MemberSerialization GetObjectMemberSerialization(Type objectType,
return MemberSerialization.OptOut;
}
- public static JsonConverter GetJsonConverter(object attributeProvider)
+ public static JsonConverter? GetJsonConverter(object attributeProvider)
{
- JsonConverterAttribute converterAttribute = GetCachedAttribute(attributeProvider);
+ JsonConverterAttribute? converterAttribute = GetCachedAttribute(attributeProvider);
if (converterAttribute != null)
{
- Func creator = CreatorCache.Get(converterAttribute.ConverterType);
+ Func creator = CreatorCache.Get(converterAttribute.ConverterType);
if (creator != null)
{
return (JsonConverter)creator(converterAttribute.ConverterParameters);
@@ -200,19 +202,19 @@ public static JsonConverter GetJsonConverter(object attributeProvider)
/// The type to create.
/// Optional arguments to pass to an initializing constructor of the JsonConverter.
/// If null, the default constructor is used.
- public static JsonConverter CreateJsonConverterInstance(Type converterType, object[] args)
+ public static JsonConverter CreateJsonConverterInstance(Type converterType, object[]? args)
{
- Func converterCreator = CreatorCache.Get(converterType);
+ Func converterCreator = CreatorCache.Get(converterType);
return (JsonConverter)converterCreator(args);
}
- public static NamingStrategy CreateNamingStrategyInstance(Type namingStrategyType, object[] args)
+ public static NamingStrategy CreateNamingStrategyInstance(Type namingStrategyType, object[]? args)
{
- Func converterCreator = CreatorCache.Get(namingStrategyType);
+ Func converterCreator = CreatorCache.Get(namingStrategyType);
return (NamingStrategy)converterCreator(args);
}
- public static NamingStrategy GetContainerNamingStrategy(JsonContainerAttribute containerAttribute)
+ public static NamingStrategy? GetContainerNamingStrategy(JsonContainerAttribute containerAttribute)
{
if (containerAttribute.NamingStrategyInstance == null)
{
@@ -227,9 +229,9 @@ public static NamingStrategy GetContainerNamingStrategy(JsonContainerAttribute c
return containerAttribute.NamingStrategyInstance;
}
- private static Func GetCreator(Type type)
+ private static Func GetCreator(Type type)
{
- Func defaultConstructor = (ReflectionUtils.HasDefaultConstructor(type, false))
+ Func? defaultConstructor = (ReflectionUtils.HasDefaultConstructor(type, false))
? ReflectionDelegateFactory.CreateDefaultConstructor(type)
: null;
@@ -248,7 +250,7 @@ private static Func GetCreator(Type type)
return param.GetType();
}).ToArray();
- ConstructorInfo parameterizedConstructorInfo = type.GetConstructor(paramTypes);
+ ConstructorInfo? parameterizedConstructorInfo = type.GetConstructor(paramTypes);
if (parameterizedConstructorInfo != null)
{
@@ -276,12 +278,12 @@ private static Func GetCreator(Type type)
}
#if !(NET20 || DOTNET)
- private static Type GetAssociatedMetadataType(Type type)
+ private static Type? GetAssociatedMetadataType(Type type)
{
return AssociatedMetadataTypesCache.Get(type);
}
- private static Type GetAssociateMetadataTypeFromAttribute(Type type)
+ private static Type? GetAssociateMetadataTypeFromAttribute(Type type)
{
Attribute[] customAttributes = ReflectionUtils.GetAttributes(type, null, true);
@@ -300,7 +302,7 @@ private static Type GetAssociateMetadataTypeFromAttribute(Type type)
_metadataTypeAttributeReflectionObject = ReflectionObject.Create(attributeType, metadataClassTypeName);
}
- return (Type)_metadataTypeAttributeReflectionObject.GetValue(attribute, metadataClassTypeName);
+ return (Type?)_metadataTypeAttributeReflectionObject.GetValue(attribute, metadataClassTypeName);
}
}
@@ -308,12 +310,12 @@ private static Type GetAssociateMetadataTypeFromAttribute(Type type)
}
#endif
- private static T GetAttribute(Type type) where T : Attribute
+ private static T? GetAttribute(Type type) where T : Attribute
{
- T attribute;
+ T? attribute;
#if !(NET20 || DOTNET)
- Type metadataType = GetAssociatedMetadataType(type);
+ Type? metadataType = GetAssociatedMetadataType(type);
if (metadataType != null)
{
attribute = ReflectionUtils.GetAttribute(metadataType, true);
@@ -342,15 +344,15 @@ private static T GetAttribute(Type type) where T : Attribute
return null;
}
- private static T GetAttribute(MemberInfo memberInfo) where T : Attribute
+ private static T? GetAttribute(MemberInfo memberInfo) where T : Attribute
{
- T attribute;
+ T? attribute;
#if !(NET20 || DOTNET)
- Type metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType);
+ Type? metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType!);
if (metadataType != null)
{
- MemberInfo metadataTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(metadataType, memberInfo);
+ MemberInfo? metadataTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(metadataType, memberInfo);
if (metadataTypeMemberInfo != null)
{
@@ -373,7 +375,7 @@ private static T GetAttribute(MemberInfo memberInfo) where T : Attribute
{
foreach (Type typeInterface in memberInfo.DeclaringType.GetInterfaces())
{
- MemberInfo interfaceTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(typeInterface, memberInfo);
+ MemberInfo? interfaceTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(typeInterface, memberInfo);
if (interfaceTypeMemberInfo != null)
{
@@ -423,7 +425,7 @@ public static bool IsSerializable(object provider)
}
#endif
- public static T GetAttribute(object provider) where T : Attribute
+ public static T? GetAttribute(object provider) where T : Attribute
{
if (provider is Type type)
{
@@ -459,7 +461,9 @@ public static bool DynamicCodeGeneration
{
if (_dynamicCodeGeneration == null)
{
-#if HAVE_CAS
+#if HAVE_DYNAMIC_CODE_COMPILED
+ _dynamicCodeGeneration = RuntimeFeature.IsDynamicCodeCompiled;
+#elif HAVE_CAS
try
{
new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
@@ -528,4 +532,5 @@ public static ReflectionDelegateFactory ReflectionDelegateFactory
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/KebabCaseNamingStrategy.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/KebabCaseNamingStrategy.cs
new file mode 100644
index 0000000000..9730f81260
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/KebabCaseNamingStrategy.cs
@@ -0,0 +1,84 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using Microsoft.IdentityModel.Json.Utilities;
+
+namespace Microsoft.IdentityModel.Json.Serialization
+{
+ ///
+ /// A kebab case naming strategy.
+ ///
+ internal class KebabCaseNamingStrategy : NamingStrategy
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A flag indicating whether dictionary keys should be processed.
+ ///
+ ///
+ /// A flag indicating whether explicitly specified property names should be processed,
+ /// e.g. a property name customized with a .
+ ///
+ public KebabCaseNamingStrategy(bool processDictionaryKeys, bool overrideSpecifiedNames)
+ {
+ ProcessDictionaryKeys = processDictionaryKeys;
+ OverrideSpecifiedNames = overrideSpecifiedNames;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// A flag indicating whether dictionary keys should be processed.
+ ///
+ ///
+ /// A flag indicating whether explicitly specified property names should be processed,
+ /// e.g. a property name customized with a .
+ ///
+ ///
+ /// A flag indicating whether extension data names should be processed.
+ ///
+ public KebabCaseNamingStrategy(bool processDictionaryKeys, bool overrideSpecifiedNames, bool processExtensionDataNames)
+ : this(processDictionaryKeys, overrideSpecifiedNames)
+ {
+ ProcessExtensionDataNames = processExtensionDataNames;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public KebabCaseNamingStrategy()
+ {
+ }
+
+ ///
+ /// Resolves the specified property name.
+ ///
+ /// The property name to resolve.
+ /// The resolved property name.
+ protected override string ResolvePropertyName(string name) => StringUtils.ToKebabCase(name);
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/MemoryTraceWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/MemoryTraceWriter.cs
index e20cf22fc3..560c3aeb2b 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/MemoryTraceWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/MemoryTraceWriter.cs
@@ -6,6 +6,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Represents a trace writer that writes to memory. When the trace message limit is
/// reached then old trace messages will be removed as new messages are added.
@@ -41,7 +42,7 @@ public MemoryTraceWriter()
/// The at which to write this trace.
/// The trace message.
/// The trace exception. This parameter is optional.
- public void Trace(TraceLevel level, string message, Exception ex)
+ public void Trace(TraceLevel level, string message, Exception? ex)
{
StringBuilder sb = new StringBuilder();
sb.Append(DateTime.Now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff", CultureInfo.InvariantCulture));
@@ -97,4 +98,5 @@ public override string ToString()
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/NamingStrategy.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/NamingStrategy.cs
index ea33c906c2..6e003ff832 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/NamingStrategy.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/NamingStrategy.cs
@@ -25,6 +25,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// A base class for resolving how property names and dictionary keys are serialized.
///
@@ -101,5 +102,47 @@ public virtual string GetDictionaryKey(string key)
/// The property name to resolve.
/// The resolved property name.
protected abstract string ResolvePropertyName(string name);
+
+ ///
+ /// Hash code calculation
+ ///
+ ///
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ var hashCode = GetType().GetHashCode(); // make sure different types do not result in equal values
+ hashCode = (hashCode * 397) ^ ProcessDictionaryKeys.GetHashCode();
+ hashCode = (hashCode * 397) ^ ProcessExtensionDataNames.GetHashCode();
+ hashCode = (hashCode * 397) ^ OverrideSpecifiedNames.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ ///
+ /// Object equality implementation
+ ///
+ ///
+ ///
+ public override bool Equals(object? obj) => Equals(obj as NamingStrategy);
+
+ ///
+ /// Compare to another NamingStrategy
+ ///
+ ///
+ ///
+ protected bool Equals(NamingStrategy? other)
+ {
+ if (other == null)
+ {
+ return false;
+ }
+
+ return GetType() == other.GetType() &&
+ ProcessDictionaryKeys == other.ProcessDictionaryKeys &&
+ ProcessExtensionDataNames == other.ProcessExtensionDataNames &&
+ OverrideSpecifiedNames == other.OverrideSpecifiedNames;
+ }
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ObjectConstructor.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ObjectConstructor.cs
index 4279a2223b..32d606a371 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ObjectConstructor.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ObjectConstructor.cs
@@ -25,9 +25,11 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Represents a method that constructs an object.
///
/// The object type to create.
- internal delegate object ObjectConstructor(params object[] args);
-}
\ No newline at end of file
+ internal delegate object ObjectConstructor(params object?[] args);
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/OnErrorAttribute.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/OnErrorAttribute.cs
index 5d02ee4830..ae2fe0ddf3 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/OnErrorAttribute.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/OnErrorAttribute.cs
@@ -34,4 +34,4 @@ namespace Microsoft.IdentityModel.Json.Serialization
internal sealed class OnErrorAttribute : Attribute
{
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionAttributeProvider.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionAttributeProvider.cs
index c662e47dc2..8200d5a2ad 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionAttributeProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionAttributeProvider.cs
@@ -68,4 +68,4 @@ public IList GetAttributes(Type attributeType, bool inherit)
return ReflectionUtils.GetAttributes(_attributeProvider, attributeType, inherit);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionValueProvider.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionValueProvider.cs
index 241d347a08..7b24289481 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionValueProvider.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/ReflectionValueProvider.cs
@@ -30,6 +30,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
///
/// Get and set values for a using reflection.
///
@@ -52,7 +53,7 @@ public ReflectionValueProvider(MemberInfo memberInfo)
///
/// The target to set the value on.
/// The value to set on the target.
- public void SetValue(object target, object value)
+ public void SetValue(object target, object? value)
{
try
{
@@ -69,7 +70,7 @@ public void SetValue(object target, object value)
///
/// The target to get the value from.
/// The value.
- public object GetValue(object target)
+ public object? GetValue(object target)
{
try
{
@@ -87,4 +88,5 @@ public object GetValue(object target)
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SerializationBinderAdapter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SerializationBinderAdapter.cs
index 04318e76a3..3d7a2e9907 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SerializationBinderAdapter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SerializationBinderAdapter.cs
@@ -28,6 +28,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class SerializationBinderAdapter : ISerializationBinder
{
#pragma warning disable 618
@@ -41,12 +42,12 @@ public SerializationBinderAdapter(SerializationBinder serializationBinder)
}
#pragma warning restore 618
- public Type BindToType(string assemblyName, string typeName)
+ public Type BindToType(string? assemblyName, string typeName)
{
- return SerializationBinder.BindToType(assemblyName, typeName);
+ return SerializationBinder.BindToType(assemblyName!, typeName)!;
}
- public void BindToName(Type serializedType, out string assemblyName, out string typeName)
+ public void BindToName(Type serializedType, out string? assemblyName, out string? typeName)
{
#if HAVE_SERIALIZATION_BINDER_BIND_TO_NAME
SerializationBinder.BindToName(serializedType, out assemblyName, out typeName);
@@ -56,4 +57,5 @@ public void BindToName(Type serializedType, out string assemblyName, out string
#endif
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SnakeCaseNamingStrategy.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SnakeCaseNamingStrategy.cs
index a0726ef65d..90c8b55da3 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SnakeCaseNamingStrategy.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/SnakeCaseNamingStrategy.cs
@@ -84,4 +84,4 @@ protected override string ResolvePropertyName(string name)
return StringUtils.ToSnakeCase(name);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonReader.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonReader.cs
index 5ff194b787..e147fe3796 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonReader.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonReader.cs
@@ -31,6 +31,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class TraceJsonReader : JsonReader, IJsonLineInfo
{
private readonly JsonReader _innerReader;
@@ -68,16 +69,16 @@ public override bool Read()
return value;
}
- public override string ReadAsString()
+ public override string? ReadAsString()
{
- string value = _innerReader.ReadAsString();
+ string? value = _innerReader.ReadAsString();
WriteCurrentToken();
return value;
}
- public override byte[] ReadAsBytes()
+ public override byte[]? ReadAsBytes()
{
- byte[] value = _innerReader.ReadAsBytes();
+ byte[]? value = _innerReader.ReadAsBytes();
WriteCurrentToken();
return value;
}
@@ -136,9 +137,9 @@ public override char QuoteChar
public override JsonToken TokenType => _innerReader.TokenType;
- public override object Value => _innerReader.Value;
+ public override object? Value => _innerReader.Value;
- public override Type ValueType => _innerReader.ValueType;
+ public override Type? ValueType => _innerReader.ValueType;
public override void Close()
{
@@ -154,4 +155,5 @@ bool IJsonLineInfo.HasLineInfo()
int IJsonLineInfo.LinePosition => (_innerReader is IJsonLineInfo lineInfo) ? lineInfo.LinePosition : 0;
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonWriter.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonWriter.cs
index 1cbd8476ea..4aaa093110 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonWriter.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Serialization/TraceJsonWriter.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json.Serialization
{
+#nullable enable
internal class TraceJsonWriter : JsonWriter
{
private readonly JsonWriter _innerWriter;
@@ -144,7 +145,7 @@ public override void WriteValue(char? value)
}
}
- public override void WriteValue(byte[] value)
+ public override void WriteValue(byte[]? value)
{
_textWriter.WriteValue(value);
_innerWriter.WriteValue(value);
@@ -321,7 +322,7 @@ public override void WriteValue(long? value)
}
}
- public override void WriteValue(object value)
+ public override void WriteValue(object? value)
{
#if HAVE_BIG_INTEGER
if (value is BigInteger)
@@ -389,7 +390,7 @@ public override void WriteValue(short? value)
}
}
- public override void WriteValue(string value)
+ public override void WriteValue(string? value)
{
_textWriter.WriteValue(value);
_innerWriter.WriteValue(value);
@@ -459,7 +460,7 @@ public override void WriteValue(ulong? value)
}
}
- public override void WriteValue(Uri value)
+ public override void WriteValue(Uri? value)
{
_textWriter.WriteValue(value);
_innerWriter.WriteValue(value);
@@ -501,7 +502,7 @@ public override void WriteWhitespace(string ws)
base.WriteWhitespace(ws);
}
- public override void WriteComment(string text)
+ public override void WriteComment(string? text)
{
_textWriter.WriteComment(text);
_innerWriter.WriteComment(text);
@@ -566,7 +567,7 @@ public override void WriteEndObject()
base.WriteEndObject();
}
- public override void WriteRawValue(string json)
+ public override void WriteRawValue(string? json)
{
_textWriter.WriteRawValue(json);
_innerWriter.WriteRawValue(json);
@@ -575,7 +576,7 @@ public override void WriteRawValue(string json)
InternalWriteValue(JsonToken.Undefined);
}
- public override void WriteRaw(string json)
+ public override void WriteRaw(string? json)
{
_textWriter.WriteRaw(json);
_innerWriter.WriteRaw(json);
@@ -595,4 +596,5 @@ public override void Flush()
_innerWriter.Flush();
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/SerializationBinder.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/SerializationBinder.cs
index 62744685f8..61f6ec3b60 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/SerializationBinder.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/SerializationBinder.cs
@@ -17,7 +17,7 @@ internal abstract class SerializationBinder
/// Specifies the name of the serialized object.
/// Specifies the name of the serialized object
/// The type of the object the formatter creates a new instance of.
- public abstract Type BindToType(string assemblyName, string typeName);
+ public abstract Type BindToType(string? assemblyName, string typeName);
///
/// When overridden in a derived class, controls the binding of a serialized object to a type.
@@ -25,7 +25,7 @@ internal abstract class SerializationBinder
/// The type of the object the formatter creates a new instance of.
/// Specifies the name of the serialized object.
/// Specifies the name of the serialized object.
- public virtual void BindToName(Type serializedType, out string assemblyName, out string typeName)
+ public virtual void BindToName(Type serializedType, out string? assemblyName, out string? typeName)
{
assemblyName = null;
typeName = null;
@@ -33,4 +33,4 @@ public virtual void BindToName(Type serializedType, out string assemblyName, out
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/StringEscapeHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/StringEscapeHandling.cs
index e1adbdf189..8895785e11 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/StringEscapeHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/StringEscapeHandling.cs
@@ -45,4 +45,4 @@ internal enum StringEscapeHandling
///
EscapeHtml = 2
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/TraceLevel.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/TraceLevel.cs
index 068fec52da..91ef45330a 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/TraceLevel.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/TraceLevel.cs
@@ -36,4 +36,4 @@ internal enum TraceLevel
}
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameAssemblyFormatHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameAssemblyFormatHandling.cs
index d87a4c3e90..9d430a51f6 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameAssemblyFormatHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameAssemblyFormatHandling.cs
@@ -40,4 +40,4 @@ internal enum TypeNameAssemblyFormatHandling
///
Full = 1
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameHandling.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameHandling.cs
index dab3b0fa98..7e85fb14d8 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameHandling.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/TypeNameHandling.cs
@@ -67,4 +67,4 @@ internal enum TypeNameHandling
///
Auto = 4
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/AsyncUtils.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/AsyncUtils.cs
index 756d863789..c8d49c0dbd 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/AsyncUtils.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/AsyncUtils.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal static class AsyncUtils
{
// Pre-allocate to avoid wasted allocations.
@@ -40,33 +41,30 @@ internal static class AsyncUtils
internal static Task ToAsync(this bool value) => value ? True : False;
- public static Task CancelIfRequestedAsync(this CancellationToken cancellationToken)
+ public static Task? CancelIfRequestedAsync(this CancellationToken cancellationToken)
{
return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : null;
}
- public static Task CancelIfRequestedAsync(this CancellationToken cancellationToken)
+ public static Task? CancelIfRequestedAsync(this CancellationToken cancellationToken)
{
return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : null;
}
-
// From 4.6 on we could use Task.FromCanceled(), but we need an equivalent for
// previous frameworks.
-#pragma warning disable UseAsyncSuffix // Use Async suffix
public static Task FromCanceled(this CancellationToken cancellationToken)
-#pragma warning restore UseAsyncSuffix // Use Async suffix
{
- Debug.Assert(cancellationToken.IsCancellationRequested);
+ MiscellaneousUtils.Assert(cancellationToken.IsCancellationRequested);
return new Task(() => {}, cancellationToken);
}
-#pragma warning disable UseAsyncSuffix // Use Async suffix
public static Task FromCanceled(this CancellationToken cancellationToken)
-#pragma warning restore UseAsyncSuffix // Use Async suffix
{
- Debug.Assert(cancellationToken.IsCancellationRequested);
+ MiscellaneousUtils.Assert(cancellationToken.IsCancellationRequested);
+#pragma warning disable CS8603 // Possible null reference return.
return new Task(() => default, cancellationToken);
+#pragma warning restore CS8603 // Possible null reference return.
}
// Task.Delay(0) is optimised as a cached task within the framework, and indeed
@@ -76,38 +74,39 @@ public static Task FromCanceled(this CancellationToken cancellationToken)
public static Task WriteAsync(this TextWriter writer, char value, CancellationToken cancellationToken)
{
- Debug.Assert(writer != null);
+ MiscellaneousUtils.Assert(writer != null);
return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : writer.WriteAsync(value);
}
- public static Task WriteAsync(this TextWriter writer, string value, CancellationToken cancellationToken)
+ public static Task WriteAsync(this TextWriter writer, string? value, CancellationToken cancellationToken)
{
- Debug.Assert(writer != null);
+ MiscellaneousUtils.Assert(writer != null);
return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : writer.WriteAsync(value);
}
public static Task WriteAsync(this TextWriter writer, char[] value, int start, int count, CancellationToken cancellationToken)
{
- Debug.Assert(writer != null);
+ MiscellaneousUtils.Assert(writer != null);
return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : writer.WriteAsync(value, start, count);
}
public static Task ReadAsync(this TextReader reader, char[] buffer, int index, int count, CancellationToken cancellationToken)
{
- Debug.Assert(reader != null);
+ MiscellaneousUtils.Assert(reader != null);
return cancellationToken.IsCancellationRequested ? FromCanceled(cancellationToken) : reader.ReadAsync(buffer, index, count);
}
- public static bool IsCompletedSucessfully(this Task task)
+ public static bool IsCompletedSuccessfully(this Task task)
{
// IsCompletedSucessfully is the faster method, but only currently exposed on .NET Core 2.0
-#if NETCOREAPP2_0
- return task.IsCompletedSucessfully;
+#if NETCOREAPP2_0_OR_GREATER
+ return task.IsCompletedSuccessfully;
#else
return task.Status == TaskStatus.RanToCompletion;
#endif
}
}
+#nullable disable
}
#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/Base64Encoder.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/Base64Encoder.cs
index 84c899266f..a932432b64 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/Base64Encoder.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/Base64Encoder.cs
@@ -32,6 +32,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal class Base64Encoder
{
private const int Base64LineSize = 76;
@@ -40,7 +41,7 @@ internal class Base64Encoder
private readonly char[] _charsLine = new char[Base64LineSize];
private readonly TextWriter _writer;
- private byte[] _leftOverBytes;
+ private byte[]? _leftOverBytes;
private int _leftOverBytesCount;
public Base64Encoder(TextWriter writer)
@@ -78,12 +79,12 @@ public void Encode(byte[] buffer, int index, int count)
if (_leftOverBytesCount > 0)
{
- if(FulfillFromLeftover(buffer, index, ref count))
+ if (FulfillFromLeftover(buffer, index, ref count))
{
return;
}
- int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0);
+ int num2 = Convert.ToBase64CharArray(_leftOverBytes!, 0, 3, _charsLine, 0);
WriteChars(_charsLine, 0, num2);
}
@@ -128,7 +129,7 @@ private bool FulfillFromLeftover(byte[] buffer, int index, ref int count)
int leftOverBytesCount = _leftOverBytesCount;
while (leftOverBytesCount < 3 && count > 0)
{
- _leftOverBytes[leftOverBytesCount++] = buffer[index++];
+ _leftOverBytes![leftOverBytesCount++] = buffer[index++];
count--;
}
@@ -145,7 +146,7 @@ public void Flush()
{
if (_leftOverBytesCount > 0)
{
- int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
+ int count = Convert.ToBase64CharArray(_leftOverBytes!, 0, _leftOverBytesCount, _charsLine, 0);
WriteChars(_charsLine, 0, count);
_leftOverBytesCount = 0;
}
@@ -169,7 +170,7 @@ public async Task EncodeAsync(byte[] buffer, int index, int count, CancellationT
return;
}
- int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0);
+ int num2 = Convert.ToBase64CharArray(_leftOverBytes!, 0, 3, _charsLine, 0);
await WriteCharsAsync(_charsLine, 0, num2, cancellationToken).ConfigureAwait(false);
}
@@ -203,7 +204,7 @@ public Task FlushAsync(CancellationToken cancellationToken)
if (_leftOverBytesCount > 0)
{
- int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
+ int count = Convert.ToBase64CharArray(_leftOverBytes!, 0, _leftOverBytesCount, _charsLine, 0);
_leftOverBytesCount = 0;
return WriteCharsAsync(_charsLine, 0, count, cancellationToken);
}
@@ -214,4 +215,5 @@ public Task FlushAsync(CancellationToken cancellationToken)
#endif
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/BidirectionalDictionary.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/BidirectionalDictionary.cs
index e06ff12152..47d92b7077 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/BidirectionalDictionary.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/BidirectionalDictionary.cs
@@ -25,11 +25,15 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal class BidirectionalDictionary
+ where TFirst : notnull
+ where TSecond : notnull
{
private readonly IDictionary _firstToSecond;
private readonly IDictionary _secondToFirst;
@@ -61,17 +65,17 @@ public BidirectionalDictionary(IEqualityComparer firstEqualityComparer,
public void Set(TFirst first, TSecond second)
{
- if (_firstToSecond.TryGetValue(first, out TSecond existingSecond))
+ if (_firstToSecond.TryGetValue(first, out TSecond? existingSecond))
{
- if (!existingSecond.Equals(second))
+ if (!existingSecond!.Equals(second))
{
throw new ArgumentException(_duplicateFirstErrorMessage.FormatWith(CultureInfo.InvariantCulture, first));
}
}
- if (_secondToFirst.TryGetValue(second, out TFirst existingFirst))
+ if (_secondToFirst.TryGetValue(second, out TFirst? existingFirst))
{
- if (!existingFirst.Equals(first))
+ if (!existingFirst!.Equals(first))
{
throw new ArgumentException(_duplicateSecondErrorMessage.FormatWith(CultureInfo.InvariantCulture, second));
}
@@ -81,14 +85,15 @@ public void Set(TFirst first, TSecond second)
_secondToFirst.Add(second, first);
}
- public bool TryGetByFirst(TFirst first, out TSecond second)
+ public bool TryGetByFirst(TFirst first, [NotNullWhen(true)] out TSecond? second)
{
return _firstToSecond.TryGetValue(first, out second);
}
- public bool TryGetBySecond(TSecond second, out TFirst first)
+ public bool TryGetBySecond(TSecond second, [NotNullWhen(true)] out TFirst? first)
{
return _secondToFirst.TryGetValue(second, out first);
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/BoxedPrimitives.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/BoxedPrimitives.cs
new file mode 100644
index 0000000000..7ccb6f2c8b
--- /dev/null
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/BoxedPrimitives.cs
@@ -0,0 +1,116 @@
+#region License
+// Copyright (c) 2022 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Microsoft.IdentityModel.Json.Utilities
+{
+ internal static class BoxedPrimitives
+ {
+ internal static object Get(bool value) => value ? BooleanTrue : BooleanFalse;
+
+ internal static readonly object BooleanTrue = true;
+ internal static readonly object BooleanFalse = false;
+
+ internal static object Get(int value) => value switch
+ {
+ -1 => Int32_M1,
+ 0 => Int32_0,
+ 1 => Int32_1,
+ 2 => Int32_2,
+ 3 => Int32_3,
+ 4 => Int32_4,
+ 5 => Int32_5,
+ 6 => Int32_6,
+ 7 => Int32_7,
+ 8 => Int32_8,
+ _ => value,
+ };
+
+ // integers tend to be weighted towards a handful of low numbers; we could argue
+ // for days over the "correct" range to have special handling, but I'm arbitrarily
+ // mirroring the same decision as the IL opcodes, which has M1 thru 8
+ internal static readonly object Int32_M1 = -1;
+ internal static readonly object Int32_0 = 0;
+ internal static readonly object Int32_1 = 1;
+ internal static readonly object Int32_2 = 2;
+ internal static readonly object Int32_3 = 3;
+ internal static readonly object Int32_4 = 4;
+ internal static readonly object Int32_5 = 5;
+ internal static readonly object Int32_6 = 6;
+ internal static readonly object Int32_7 = 7;
+ internal static readonly object Int32_8 = 8;
+
+ internal static object Get(long value) => value switch
+ {
+ -1 => Int64_M1,
+ 0 => Int64_0,
+ 1 => Int64_1,
+ 2 => Int64_2,
+ 3 => Int64_3,
+ 4 => Int64_4,
+ 5 => Int64_5,
+ 6 => Int64_6,
+ 7 => Int64_7,
+ 8 => Int64_8,
+ _ => value,
+ };
+
+ internal static readonly object Int64_M1 = -1L;
+ internal static readonly object Int64_0 = 0L;
+ internal static readonly object Int64_1 = 1L;
+ internal static readonly object Int64_2 = 2L;
+ internal static readonly object Int64_3 = 3L;
+ internal static readonly object Int64_4 = 4L;
+ internal static readonly object Int64_5 = 5L;
+ internal static readonly object Int64_6 = 6L;
+ internal static readonly object Int64_7 = 7L;
+ internal static readonly object Int64_8 = 8L;
+
+ internal static object Get(decimal value) => value == decimal.Zero ? DecimalZero : value;
+
+ private static readonly object DecimalZero = decimal.Zero;
+
+ internal static object Get(double value)
+ {
+ if (value == 0.0d)
+ {
+ return DoubleZero;
+ }
+ if (double.IsInfinity(value))
+ {
+ return double.IsPositiveInfinity(value) ? DoublePositiveInfinity : DoubleNegativeInfinity;
+ }
+ if (double.IsNaN(value))
+ {
+ return DoubleNaN;
+ }
+ return value;
+ }
+
+ internal static readonly object DoubleNaN = double.NaN;
+ internal static readonly object DoublePositiveInfinity = double.PositiveInfinity;
+ internal static readonly object DoubleNegativeInfinity = double.NegativeInfinity;
+ internal static readonly object DoubleZero = (double)0;
+ }
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionUtils.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionUtils.cs
index c07a0338f2..f3c7eca167 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionUtils.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionUtils.cs
@@ -43,6 +43,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal static class CollectionUtils
{
///
@@ -116,17 +117,17 @@ public static bool IsDictionaryType(Type type)
return false;
}
- public static ConstructorInfo ResolveEnumerableCollectionConstructor(Type collectionType, Type collectionItemType)
+ public static ConstructorInfo? ResolveEnumerableCollectionConstructor(Type collectionType, Type collectionItemType)
{
Type genericConstructorArgument = typeof(IList<>).MakeGenericType(collectionItemType);
return ResolveEnumerableCollectionConstructor(collectionType, collectionItemType, genericConstructorArgument);
}
- public static ConstructorInfo ResolveEnumerableCollectionConstructor(Type collectionType, Type collectionItemType, Type constructorArgumentType)
+ public static ConstructorInfo? ResolveEnumerableCollectionConstructor(Type collectionType, Type collectionItemType, Type constructorArgumentType)
{
Type genericEnumerable = typeof(IEnumerable<>).MakeGenericType(collectionItemType);
- ConstructorInfo match = null;
+ ConstructorInfo? match = null;
foreach (ConstructorInfo constructor in collectionType.GetConstructors(BindingFlags.Public | BindingFlags.Instance))
{
@@ -248,11 +249,12 @@ public static int IndexOfReference(this List list, T item)
return i;
}
}
+
return -1;
}
#if HAVE_FAST_REVERSE
- // faster reverse in .NET Framework with value types - https://github.com/JamesNK/Microsoft.IdentityModel.Json/issues/1430
+ // faster reverse in .NET Framework with value types - https://github.com/JamesNK/Newtonsoft.Json/issues/1430
public static void FastReverse(this List list)
{
int i = 0;
@@ -288,7 +290,7 @@ private static IList GetDimensions(IList values, int dimensionsCount)
break;
}
- object v = currentArray[0];
+ object? v = currentArray[0];
if (v is IList list)
{
currentArray = list;
@@ -316,9 +318,7 @@ private static void CopyFromJaggedToMultidimensionalArray(IList values, Array mu
int currentValuesLength = list.Count;
if (currentValuesLength != dimensionLength)
{
-#pragma warning disable CA2201 // Do not raise reserved exception types
throw new Exception("Cannot deserialize non-cubical array as multidimensional array.");
-#pragma warning restore CA2201 // Do not raise reserved exception types
}
int[] newIndices = new int[dimension + 1];
@@ -342,11 +342,11 @@ private static object JaggedArrayGetValue(IList values, int[] indices)
int index = indices[i];
if (i == indices.Length - 1)
{
- return currentList[index];
+ return currentList[index]!;
}
else
{
- currentList = (IList)currentList[index];
+ currentList = (IList)currentList[index]!;
}
}
return currentList;
@@ -367,25 +367,24 @@ public static Array ToMultidimensionalArray(IList values, Type type, int rank)
return multidimensionalArray;
}
- // 4.6 has Array.Empty to return a cached empty array. Lacking that in other
- // frameworks, Enumerable.Empty happens to be implemented as a cached empty
- // array in all versions (in .NET Core the same instance as Array.Empty).
- // This includes the internal Linq bridge for 2.0.
- // Since this method is simple and only 11 bytes long in a release build it's
- // pretty much guaranteed to be inlined, giving us fast access of that cached
- // array. With 4.5 and up we use AggressiveInlining just to be sure, so it's
- // effectively the same as calling Array.Empty even when not available.
-#if HAVE_METHOD_IMPL_ATTRIBUTE
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
public static T[] ArrayEmpty()
{
- T[] array = Enumerable.Empty() as T[];
- Debug.Assert(array != null);
- // Defensively guard against a version of Linq where Enumerable.Empty doesn't
- // return an array, but throw in debug versions so a better strategy can be
- // used if that ever happens.
- return array ?? new T[0];
+#if !HAS_ARRAY_EMPTY
+ // Enumerable.Empty no longer returns an empty array in .NET Core 3.0
+ return EmptyArrayContainer.Empty;
+#else
+ return Array.Empty();
+#endif
}
+
+#if !HAS_ARRAY_EMPTY
+ private static class EmptyArrayContainer
+ {
+#pragma warning disable CA1825 // Avoid zero-length array allocations.
+ public static readonly T[] Empty = new T[0];
+#pragma warning restore CA1825 // Avoid zero-length array allocations.
+ }
+#endif
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionWrapper.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionWrapper.cs
index 697909f337..274a7cdb69 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionWrapper.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/CollectionWrapper.cs
@@ -37,6 +37,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal interface IWrappedCollection : IList
{
object UnderlyingCollection { get; }
@@ -44,9 +45,9 @@ internal interface IWrappedCollection : IList
internal class CollectionWrapper : ICollection, IWrappedCollection
{
- private readonly IList _list;
- private readonly ICollection _genericCollection;
- private object _syncRoot;
+ private readonly IList? _list;
+ private readonly ICollection? _genericCollection;
+ private object? _syncRoot;
public CollectionWrapper(IList list)
{
@@ -77,7 +78,7 @@ public virtual void Add(T item)
}
else
{
- _list.Add(item);
+ _list!.Add(item);
}
}
@@ -89,7 +90,7 @@ public virtual void Clear()
}
else
{
- _list.Clear();
+ _list!.Clear();
}
}
@@ -101,7 +102,7 @@ public virtual bool Contains(T item)
}
else
{
- return _list.Contains(item);
+ return _list!.Contains(item);
}
}
@@ -113,7 +114,7 @@ public virtual void CopyTo(T[] array, int arrayIndex)
}
else
{
- _list.CopyTo(array, arrayIndex);
+ _list!.CopyTo(array, arrayIndex);
}
}
@@ -127,7 +128,7 @@ public virtual int Count
}
else
{
- return _list.Count;
+ return _list!.Count;
}
}
}
@@ -142,7 +143,7 @@ public virtual bool IsReadOnly
}
else
{
- return _list.IsReadOnly;
+ return _list!.IsReadOnly;
}
}
}
@@ -155,11 +156,11 @@ public virtual bool Remove(T item)
}
else
{
- bool contains = _list.Contains(item);
+ bool contains = _list!.Contains(item);
if (contains)
{
- _list.Remove(item);
+ _list!.Remove(item);
}
return contains;
@@ -168,33 +169,33 @@ public virtual bool Remove(T item)
public virtual IEnumerator GetEnumerator()
{
- return (_genericCollection ?? _list.Cast()).GetEnumerator();
+ return (_genericCollection ?? _list!.Cast()).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
- return ((IEnumerable)_genericCollection ?? _list).GetEnumerator();
+ return ((IEnumerable)_genericCollection! ?? _list!).GetEnumerator();
}
- int IList.Add(object value)
+ int IList.Add(object? value)
{
VerifyValueType(value);
- Add((T)value);
+ Add((T)value!);
return (Count - 1);
}
- bool IList.Contains(object value)
+ bool IList.Contains(object? value)
{
if (IsCompatibleObject(value))
{
- return Contains((T)value);
+ return Contains((T)value!);
}
return false;
}
- int IList.IndexOf(object value)
+ int IList.IndexOf(object? value)
{
if (_genericCollection != null)
{
@@ -203,7 +204,7 @@ int IList.IndexOf(object value)
if (IsCompatibleObject(value))
{
- return _list.IndexOf((T)value);
+ return _list!.IndexOf((T)value!);
}
return -1;
@@ -216,10 +217,10 @@ void IList.RemoveAt(int index)
throw new InvalidOperationException("Wrapped ICollection does not support RemoveAt.");
}
- _list.RemoveAt(index);
+ _list!.RemoveAt(index);
}
- void IList.Insert(int index, object value)
+ void IList.Insert(int index, object? value)
{
if (_genericCollection != null)
{
@@ -227,7 +228,7 @@ void IList.Insert(int index, object value)
}
VerifyValueType(value);
- _list.Insert(index, (T)value);
+ _list!.Insert(index, (T)value!);
}
bool IList.IsFixedSize
@@ -241,20 +242,20 @@ bool IList.IsFixedSize
}
else
{
- return _list.IsFixedSize;
+ return _list!.IsFixedSize;
}
}
}
- void IList.Remove(object value)
+ void IList.Remove(object? value)
{
if (IsCompatibleObject(value))
{
- Remove((T)value);
+ Remove((T)value!);
}
}
- object IList.this[int index]
+ object? IList.this[int index]
{
get
{
@@ -263,7 +264,7 @@ object IList.this[int index]
throw new InvalidOperationException("Wrapped ICollection does not support indexer.");
}
- return _list[index];
+ return _list![index];
}
set
{
@@ -273,7 +274,7 @@ object IList.this[int index]
}
VerifyValueType(value);
- _list[index] = (T)value;
+ _list![index] = (T?)value;
}
}
@@ -297,7 +298,7 @@ object ICollection.SyncRoot
}
}
- private static void VerifyValueType(object value)
+ private static void VerifyValueType(object? value)
{
if (!IsCompatibleObject(value))
{
@@ -305,7 +306,7 @@ private static void VerifyValueType(object value)
}
}
- private static bool IsCompatibleObject(object value)
+ private static bool IsCompatibleObject(object? value)
{
if (!(value is T) && (value != null || (typeof(T).IsValueType() && !ReflectionUtils.IsNullableType(typeof(T)))))
{
@@ -315,6 +316,7 @@ private static bool IsCompatibleObject(object value)
return true;
}
- public object UnderlyingCollection => (object)_genericCollection ?? _list;
+ public object UnderlyingCollection => (object)_genericCollection! ?? _list!;
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ConvertUtils.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ConvertUtils.cs
index 59e6cbdbd5..e7d04d4dcd 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ConvertUtils.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ConvertUtils.cs
@@ -27,6 +27,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.ComponentModel;
+using System.Runtime.CompilerServices;
#if HAVE_BIG_INTEGER
using System.Numerics;
#endif
@@ -36,6 +37,7 @@
#endif
using Microsoft.IdentityModel.Json.Serialization;
using System.Reflection;
+using System.Diagnostics.CodeAnalysis;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#endif
@@ -46,6 +48,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal enum PrimitiveTypeCode
{
Empty = 0,
@@ -94,8 +97,14 @@ internal enum PrimitiveTypeCode
internal class TypeInformation
{
- public Type Type { get; set; }
- public PrimitiveTypeCode TypeCode { get; set; }
+ public Type Type { get; }
+ public PrimitiveTypeCode TypeCode { get; }
+
+ public TypeInformation(Type type, PrimitiveTypeCode typeCode)
+ {
+ Type = type;
+ TypeCode = typeCode;
+ }
}
internal enum ParseResult
@@ -163,25 +172,25 @@ internal static class ConvertUtils
private static readonly TypeInformation[] PrimitiveTypeCodes =
{
// need all of these. lookup against the index with TypeCode value
- new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty },
- new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Object },
- new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.DBNull },
- new TypeInformation { Type = typeof(bool), TypeCode = PrimitiveTypeCode.Boolean },
- new TypeInformation { Type = typeof(char), TypeCode = PrimitiveTypeCode.Char },
- new TypeInformation { Type = typeof(sbyte), TypeCode = PrimitiveTypeCode.SByte },
- new TypeInformation { Type = typeof(byte), TypeCode = PrimitiveTypeCode.Byte },
- new TypeInformation { Type = typeof(short), TypeCode = PrimitiveTypeCode.Int16 },
- new TypeInformation { Type = typeof(ushort), TypeCode = PrimitiveTypeCode.UInt16 },
- new TypeInformation { Type = typeof(int), TypeCode = PrimitiveTypeCode.Int32 },
- new TypeInformation { Type = typeof(uint), TypeCode = PrimitiveTypeCode.UInt32 },
- new TypeInformation { Type = typeof(long), TypeCode = PrimitiveTypeCode.Int64 },
- new TypeInformation { Type = typeof(ulong), TypeCode = PrimitiveTypeCode.UInt64 },
- new TypeInformation { Type = typeof(float), TypeCode = PrimitiveTypeCode.Single },
- new TypeInformation { Type = typeof(double), TypeCode = PrimitiveTypeCode.Double },
- new TypeInformation { Type = typeof(decimal), TypeCode = PrimitiveTypeCode.Decimal },
- new TypeInformation { Type = typeof(DateTime), TypeCode = PrimitiveTypeCode.DateTime },
- new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty }, // no 17 in TypeCode for some reason
- new TypeInformation { Type = typeof(string), TypeCode = PrimitiveTypeCode.String }
+ new TypeInformation(typeof(object), PrimitiveTypeCode.Empty),
+ new TypeInformation(typeof(object), PrimitiveTypeCode.Object),
+ new TypeInformation(typeof(object), PrimitiveTypeCode.DBNull),
+ new TypeInformation(typeof(bool), PrimitiveTypeCode.Boolean),
+ new TypeInformation(typeof(char), PrimitiveTypeCode.Char),
+ new TypeInformation(typeof(sbyte), PrimitiveTypeCode.SByte),
+ new TypeInformation(typeof(byte), PrimitiveTypeCode.Byte),
+ new TypeInformation(typeof(short), PrimitiveTypeCode.Int16),
+ new TypeInformation(typeof(ushort), PrimitiveTypeCode.UInt16),
+ new TypeInformation(typeof(int), PrimitiveTypeCode.Int32),
+ new TypeInformation(typeof(uint), PrimitiveTypeCode.UInt32),
+ new TypeInformation(typeof(long), PrimitiveTypeCode.Int64),
+ new TypeInformation(typeof(ulong), PrimitiveTypeCode.UInt64),
+ new TypeInformation(typeof(float), PrimitiveTypeCode.Single),
+ new TypeInformation(typeof(double), PrimitiveTypeCode.Double),
+ new TypeInformation(typeof(decimal), PrimitiveTypeCode.Decimal),
+ new TypeInformation(typeof(DateTime), PrimitiveTypeCode.DateTime),
+ new TypeInformation(typeof(object), PrimitiveTypeCode.Empty), // no 17 in TypeCode for some reason
+ new TypeInformation(typeof(string), PrimitiveTypeCode.String)
};
#endif
@@ -207,7 +216,7 @@ public static PrimitiveTypeCode GetTypeCode(Type t, out bool isEnum)
// performance?
if (ReflectionUtils.IsNullableType(t))
{
- Type nonNullable = Nullable.GetUnderlyingType(t);
+ Type nonNullable = Nullable.GetUnderlyingType(t)!;
if (nonNullable.IsEnum())
{
Type nullableUnderlyingType = typeof(Nullable<>).MakeGenericType(Enum.GetUnderlyingType(nonNullable));
@@ -248,14 +257,14 @@ public static TimeSpan ParseTimeSpan(string input)
#endif
}
- private static readonly ThreadSafeStore, Func> CastConverters =
- new ThreadSafeStore, Func>(CreateCastConverter);
+ private static readonly ThreadSafeStore, Func?> CastConverters =
+ new ThreadSafeStore, Func?>(CreateCastConverter);
- private static Func CreateCastConverter(StructMultiKey t)
+ private static Func? CreateCastConverter(StructMultiKey t)
{
Type initialType = t.Value1;
Type targetType = t.Value2;
- MethodInfo castMethodInfo = targetType.GetMethod("op_Implicit", new[] { initialType })
+ MethodInfo? castMethodInfo = targetType.GetMethod("op_Implicit", new[] { initialType })
?? targetType.GetMethod("op_Explicit", new[] { initialType });
if (castMethodInfo == null)
@@ -263,7 +272,7 @@ private static Func CreateCastConverter(StructMultiKey call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(castMethodInfo);
+ MethodCall call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(castMethodInfo);
return o => call(null, o);
}
@@ -363,14 +372,12 @@ internal enum ConvertResult
public static object Convert(object initialValue, CultureInfo culture, Type targetType)
{
- switch (TryConvertInternal(initialValue, culture, targetType, out object value))
+ switch (TryConvertInternal(initialValue, culture, targetType, out object? value))
{
case ConvertResult.Success:
- return value;
+ return value!;
case ConvertResult.CannotConvertNull:
-#pragma warning disable CA2201 // Do not raise reserved exception types
throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, initialValue.GetType(), targetType));
-#pragma warning restore CA2201 // Do not raise reserved exception types
case ConvertResult.NotInstantiableType:
throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), nameof(targetType));
case ConvertResult.NoValidConversion:
@@ -380,7 +387,7 @@ public static object Convert(object initialValue, CultureInfo culture, Type targ
}
}
- private static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object value)
+ private static bool TryConvert(object? initialValue, CultureInfo culture, Type targetType, out object? value)
{
try
{
@@ -399,7 +406,7 @@ private static bool TryConvert(object initialValue, CultureInfo culture, Type ta
}
}
- private static ConvertResult TryConvertInternal(object initialValue, CultureInfo culture, Type targetType, out object value)
+ private static ConvertResult TryConvertInternal(object? initialValue, CultureInfo culture, Type targetType, out object? value)
{
if (initialValue == null)
{
@@ -408,7 +415,7 @@ private static ConvertResult TryConvertInternal(object initialValue, CultureInfo
if (ReflectionUtils.IsNullableType(targetType))
{
- targetType = Nullable.GetUnderlyingType(targetType);
+ targetType = Nullable.GetUnderlyingType(targetType)!;
}
Type initialType = initialValue.GetType();
@@ -426,7 +433,7 @@ private static ConvertResult TryConvertInternal(object initialValue, CultureInfo
{
if (initialValue is string)
{
- value = Enum.Parse(targetType, initialValue.ToString(), true);
+ value = Enum.Parse(targetType, initialValue.ToString()!, true);
return ConvertResult.Success;
}
else if (IsInteger(initialValue))
@@ -484,7 +491,7 @@ private static ConvertResult TryConvertInternal(object initialValue, CultureInfo
}
if (targetType == typeof(Version))
{
- if (VersionTryParse(s, out Version result))
+ if (VersionTryParse(s, out Version? result))
{
value = result;
return ConvertResult.Success;
@@ -497,6 +504,18 @@ private static ConvertResult TryConvertInternal(object initialValue, CultureInfo
value = Type.GetType(s, true);
return ConvertResult.Success;
}
+#if HAVE_DATE_ONLY
+ if (targetType == typeof(DateOnly))
+ {
+ value = DateOnly.ParseExact(s, "yyyy'-'MM'-'dd", CultureInfo.InvariantCulture);
+ return ConvertResult.Success;
+ }
+ if (targetType == typeof(TimeOnly))
+ {
+ value = TimeOnly.ParseExact(s, "HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture);
+ return ConvertResult.Success;
+ }
+#endif
}
#if HAVE_BIG_INTEGER
@@ -569,7 +588,7 @@ private static ConvertResult TryConvertInternal(object initialValue, CultureInfo
/// The converted type. If conversion was unsuccessful, the initial value
/// is returned if assignable to the target type.
///
- public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType)
+ public static object? ConvertOrCast(object? initialValue, CultureInfo culture, Type targetType)
{
if (targetType == typeof(object))
{
@@ -581,27 +600,27 @@ public static object ConvertOrCast(object initialValue, CultureInfo culture, Typ
return null;
}
- if (TryConvert(initialValue, culture, targetType, out object convertedValue))
+ if (TryConvert(initialValue, culture, targetType, out object? convertedValue))
{
return convertedValue;
}
- return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue), targetType);
+ return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue)!, targetType);
}
#endregion
- private static object EnsureTypeAssignable(object value, Type initialType, Type targetType)
+ private static object? EnsureTypeAssignable(object? value, Type initialType, Type targetType)
{
- Type valueType = value?.GetType();
-
if (value != null)
{
+ Type valueType = value.GetType();
+
if (targetType.IsAssignableFrom(valueType))
{
return value;
}
- Func castConverter = CastConverters.Get(new StructMultiKey(valueType, targetType));
+ Func? castConverter = CastConverters.Get(new StructMultiKey(valueType, targetType));
if (castConverter != null)
{
return castConverter(value);
@@ -618,7 +637,7 @@ private static object EnsureTypeAssignable(object value, Type initialType, Type
throw new ArgumentException("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialType?.ToString() ?? "{null}", targetType));
}
- public static bool VersionTryParse(string input, out Version result)
+ public static bool VersionTryParse(string input, [NotNullWhen(true)]out Version? result)
{
#if HAVE_VERSION_TRY_PARSE
return Version.TryParse(input, out result);
@@ -1568,4 +1587,5 @@ public static bool TryHexTextToInt(char[] text, int start, int end, out int valu
return true;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DateTimeUtils.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DateTimeUtils.cs
index 346f17da5d..585d15706f 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DateTimeUtils.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DateTimeUtils.cs
@@ -30,6 +30,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal static class DateTimeUtils
{
internal static readonly long InitialJavaScriptDateTicks = 621355968000000000;
@@ -179,9 +180,9 @@ private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset)
internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset)
{
- long universialTicks = ToUniversalTicks(dateTime, offset);
+ long universalTicks = ToUniversalTicks(dateTime, offset);
- return UniversialTicksToJavaScriptTicks(universialTicks);
+ return UniversalTicksToJavaScriptTicks(universalTicks);
}
internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
@@ -193,12 +194,12 @@ internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool co
{
long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks;
- return UniversialTicksToJavaScriptTicks(ticks);
+ return UniversalTicksToJavaScriptTicks(ticks);
}
- private static long UniversialTicksToJavaScriptTicks(long universialTicks)
+ private static long UniversalTicksToJavaScriptTicks(long universalTicks)
{
- long javaScriptTicks = (universialTicks - InitialJavaScriptDateTicks) / 10000;
+ long javaScriptTicks = (universalTicks - InitialJavaScriptDateTicks) / 10000;
return javaScriptTicks;
}
@@ -341,7 +342,7 @@ private static DateTime CreateDateTime(DateTimeParser dateTimeParser)
return d;
}
- internal static bool TryParseDateTime(StringReference s, DateTimeZoneHandling dateTimeZoneHandling, string dateFormatString, CultureInfo culture, out DateTime dt)
+ internal static bool TryParseDateTime(StringReference s, DateTimeZoneHandling dateTimeZoneHandling, string? dateFormatString, CultureInfo culture, out DateTime dt)
{
if (s.Length > 0)
{
@@ -364,7 +365,7 @@ internal static bool TryParseDateTime(StringReference s, DateTimeZoneHandling da
}
}
- if (!string.IsNullOrEmpty(dateFormatString))
+ if (!StringUtils.IsNullOrEmpty(dateFormatString))
{
if (TryParseDateTimeExact(s.ToString(), dateTimeZoneHandling, dateFormatString, culture, out dt))
{
@@ -377,7 +378,7 @@ internal static bool TryParseDateTime(StringReference s, DateTimeZoneHandling da
return false;
}
- internal static bool TryParseDateTime(string s, DateTimeZoneHandling dateTimeZoneHandling, string dateFormatString, CultureInfo culture, out DateTime dt)
+ internal static bool TryParseDateTime(string s, DateTimeZoneHandling dateTimeZoneHandling, string? dateFormatString, CultureInfo culture, out DateTime dt)
{
if (s.Length > 0)
{
@@ -400,7 +401,7 @@ internal static bool TryParseDateTime(string s, DateTimeZoneHandling dateTimeZon
}
}
- if (!string.IsNullOrEmpty(dateFormatString))
+ if (!StringUtils.IsNullOrEmpty(dateFormatString))
{
if (TryParseDateTimeExact(s, dateTimeZoneHandling, dateFormatString, culture, out dt))
{
@@ -414,7 +415,7 @@ internal static bool TryParseDateTime(string s, DateTimeZoneHandling dateTimeZon
}
#if HAVE_DATE_TIME_OFFSET
- internal static bool TryParseDateTimeOffset(StringReference s, string dateFormatString, CultureInfo culture, out DateTimeOffset dt)
+ internal static bool TryParseDateTimeOffset(StringReference s, string? dateFormatString, CultureInfo culture, out DateTimeOffset dt)
{
if (s.Length > 0)
{
@@ -437,7 +438,7 @@ internal static bool TryParseDateTimeOffset(StringReference s, string dateFormat
}
}
- if (!string.IsNullOrEmpty(dateFormatString))
+ if (!StringUtils.IsNullOrEmpty(dateFormatString))
{
if (TryParseDateTimeOffsetExact(s.ToString(), dateFormatString, culture, out dt))
{
@@ -450,7 +451,7 @@ internal static bool TryParseDateTimeOffset(StringReference s, string dateFormat
return false;
}
- internal static bool TryParseDateTimeOffset(string s, string dateFormatString, CultureInfo culture, out DateTimeOffset dt)
+ internal static bool TryParseDateTimeOffset(string s, string? dateFormatString, CultureInfo culture, out DateTimeOffset dt)
{
if (s.Length > 0)
{
@@ -475,7 +476,7 @@ internal static bool TryParseDateTimeOffset(string s, string dateFormatString, C
}
}
- if (!string.IsNullOrEmpty(dateFormatString))
+ if (!StringUtils.IsNullOrEmpty(dateFormatString))
{
if (TryParseDateTimeOffsetExact(s, dateFormatString, culture, out dt))
{
@@ -618,9 +619,9 @@ private static bool TryReadOffset(StringReference offsetText, int startIndex, ou
#endregion
#region Write
- internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, string formatString, CultureInfo culture)
+ internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, string? formatString, CultureInfo culture)
{
- if (string.IsNullOrEmpty(formatString))
+ if (StringUtils.IsNullOrEmpty(formatString))
{
char[] chars = new char[64];
int pos = WriteDateTimeString(chars, 0, value, null, value.Kind, format);
@@ -751,9 +752,9 @@ internal static int WriteDateTimeOffset(char[] chars, int start, TimeSpan offset
}
#if HAVE_DATE_TIME_OFFSET
- internal static void WriteDateTimeOffsetString(TextWriter writer, DateTimeOffset value, DateFormatHandling format, string formatString, CultureInfo culture)
+ internal static void WriteDateTimeOffsetString(TextWriter writer, DateTimeOffset value, DateFormatHandling format, string? formatString, CultureInfo culture)
{
- if (string.IsNullOrEmpty(formatString))
+ if (StringUtils.IsNullOrEmpty(formatString))
{
char[] chars = new char[64];
int pos = WriteDateTimeString(chars, 0, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format);
@@ -821,5 +822,6 @@ private static void GetDateValues(DateTime td, out int year, out int month, out
// Return 1-based day-of-month
day = n - days[m - 1] + 1;
}
+#nullable disable
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DictionaryWrapper.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DictionaryWrapper.cs
index 82cb82bb80..28fc895469 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DictionaryWrapper.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DictionaryWrapper.cs
@@ -27,15 +27,18 @@
using System.Collections.Generic;
using System.Collections;
using System.Threading;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
#if !HAVE_LINQ
using Microsoft.IdentityModel.Json.Utilities.LinqBridge;
#else
using System.Linq;
-
#endif
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal interface IWrappedDictionary
: IDictionary
{
@@ -44,12 +47,12 @@ internal interface IWrappedDictionary
internal class DictionaryWrapper : IDictionary, IWrappedDictionary
{
- private readonly IDictionary _dictionary;
- private readonly IDictionary _genericDictionary;
+ private readonly IDictionary? _dictionary;
+ private readonly IDictionary? _genericDictionary;
#if HAVE_READ_ONLY_COLLECTIONS
- private readonly IReadOnlyDictionary _readOnlyDictionary;
+ private readonly IReadOnlyDictionary? _readOnlyDictionary;
#endif
- private object _syncRoot;
+ private object? _syncRoot;
public DictionaryWrapper(IDictionary dictionary)
{
@@ -74,11 +77,20 @@ public DictionaryWrapper(IReadOnlyDictionary dictionary)
}
#endif
+ internal IDictionary GenericDictionary
+ {
+ get
+ {
+ MiscellaneousUtils.Assert(_genericDictionary != null);
+ return _genericDictionary;
+ }
+ }
+
public void Add(TKey key, TValue value)
{
if (_dictionary != null)
{
- _dictionary.Add(key, value);
+ _dictionary.Add(key!, value);
}
else if (_genericDictionary != null)
{
@@ -94,7 +106,7 @@ public bool ContainsKey(TKey key)
{
if (_dictionary != null)
{
- return _dictionary.Contains(key);
+ return _dictionary.Contains(key!);
}
#if HAVE_READ_ONLY_COLLECTIONS
else if (_readOnlyDictionary != null)
@@ -104,7 +116,7 @@ public bool ContainsKey(TKey key)
#endif
else
{
- return _genericDictionary.ContainsKey(key);
+ return GenericDictionary.ContainsKey(key);
}
}
@@ -124,7 +136,7 @@ public ICollection Keys
#endif
else
{
- return _genericDictionary.Keys;
+ return GenericDictionary.Keys;
}
}
}
@@ -133,9 +145,9 @@ public bool Remove(TKey key)
{
if (_dictionary != null)
{
- if (_dictionary.Contains(key))
+ if (_dictionary.Contains(key!))
{
- _dictionary.Remove(key);
+ _dictionary.Remove(key!);
return true;
}
else
@@ -151,22 +163,26 @@ public bool Remove(TKey key)
#endif
else
{
- return _genericDictionary.Remove(key);
+ return GenericDictionary.Remove(key);
}
}
- public bool TryGetValue(TKey key, out TValue value)
+#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
+ public bool TryGetValue(TKey key, out TValue? value)
+#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
{
if (_dictionary != null)
{
- if (!_dictionary.Contains(key))
+ if (!_dictionary.Contains(key!))
{
+#pragma warning disable CS8653 // A default expression introduces a null value for a type parameter.
value = default;
+#pragma warning restore CS8653 // A default expression introduces a null value for a type parameter.
return false;
}
else
{
- value = (TValue)_dictionary[key];
+ value = (TValue)_dictionary[key!]!;
return true;
}
}
@@ -178,7 +194,7 @@ public bool TryGetValue(TKey key, out TValue value)
#endif
else
{
- return _genericDictionary.TryGetValue(key, out value);
+ return GenericDictionary.TryGetValue(key, out value);
}
}
@@ -198,7 +214,7 @@ public ICollection Values
#endif
else
{
- return _genericDictionary.Values;
+ return GenericDictionary.Values;
}
}
}
@@ -209,7 +225,7 @@ public TValue this[TKey key]
{
if (_dictionary != null)
{
- return (TValue)_dictionary[key];
+ return (TValue)_dictionary[key!]!;
}
#if HAVE_READ_ONLY_COLLECTIONS
else if (_readOnlyDictionary != null)
@@ -219,14 +235,14 @@ public TValue this[TKey key]
#endif
else
{
- return _genericDictionary[key];
+ return GenericDictionary[key];
}
}
set
{
if (_dictionary != null)
{
- _dictionary[key] = value;
+ _dictionary[key!] = value;
}
#if HAVE_READ_ONLY_COLLECTIONS
else if (_readOnlyDictionary != null)
@@ -236,7 +252,7 @@ public TValue this[TKey key]
#endif
else
{
- _genericDictionary[key] = value;
+ GenericDictionary[key] = value;
}
}
}
@@ -273,7 +289,7 @@ public void Clear()
#endif
else
{
- _genericDictionary.Clear();
+ GenericDictionary.Clear();
}
}
@@ -291,7 +307,7 @@ public bool Contains(KeyValuePair item)
#endif
else
{
- return _genericDictionary.Contains(item);
+ return GenericDictionary.Contains(item);
}
}
@@ -306,7 +322,7 @@ public void CopyTo(KeyValuePair[] array, int arrayIndex)
while (e.MoveNext())
{
DictionaryEntry entry = e.Entry;
- array[arrayIndex++] = new KeyValuePair((TKey)entry.Key, (TValue)entry.Value);
+ array[arrayIndex++] = new KeyValuePair((TKey)entry.Key, (TValue)entry.Value!);
}
}
finally
@@ -322,7 +338,7 @@ public void CopyTo(KeyValuePair[] array, int arrayIndex)
#endif
else
{
- _genericDictionary.CopyTo(array, arrayIndex);
+ GenericDictionary.CopyTo(array, arrayIndex);
}
}
@@ -342,7 +358,7 @@ public int Count
#endif
else
{
- return _genericDictionary.Count;
+ return GenericDictionary.Count;
}
}
}
@@ -363,7 +379,7 @@ public bool IsReadOnly
#endif
else
{
- return _genericDictionary.IsReadOnly;
+ return GenericDictionary.IsReadOnly;
}
}
}
@@ -372,13 +388,13 @@ public bool Remove(KeyValuePair item)
{
if (_dictionary != null)
{
- if (_dictionary.Contains(item.Key))
+ if (_dictionary.Contains(item.Key!))
{
- object value = _dictionary[item.Key];
+ object? value = _dictionary[item.Key!];
if (Equals(value, item.Value))
{
- _dictionary.Remove(item.Key);
+ _dictionary.Remove(item.Key!);
return true;
}
else
@@ -399,7 +415,7 @@ public bool Remove(KeyValuePair item)
#endif
else
{
- return _genericDictionary.Remove(item);
+ return GenericDictionary.Remove(item);
}
}
@@ -407,7 +423,7 @@ public IEnumerator> GetEnumerator()
{
if (_dictionary != null)
{
- return _dictionary.Cast().Select(de => new KeyValuePair((TKey)de.Key, (TValue)de.Value)).GetEnumerator();
+ return _dictionary.Cast().Select(de => new KeyValuePair((TKey)de.Key, (TValue)de.Value!)).GetEnumerator();
}
#if HAVE_READ_ONLY_COLLECTIONS
else if (_readOnlyDictionary != null)
@@ -417,7 +433,7 @@ public IEnumerator> GetEnumerator()
#endif
else
{
- return _genericDictionary.GetEnumerator();
+ return GenericDictionary.GetEnumerator();
}
}
@@ -426,7 +442,7 @@ IEnumerator IEnumerable.GetEnumerator()
return GetEnumerator();
}
- void IDictionary.Add(object key, object value)
+ void IDictionary.Add(object key, object? value)
{
if (_dictionary != null)
{
@@ -440,11 +456,11 @@ void IDictionary.Add(object key, object value)
#endif
else
{
- _genericDictionary.Add((TKey)key, (TValue)value);
+ GenericDictionary.Add((TKey)key, (TValue)value!);
}
}
- object IDictionary.this[object key]
+ object? IDictionary.this[object key]
{
get
{
@@ -460,7 +476,7 @@ object IDictionary.this[object key]
#endif
else
{
- return _genericDictionary[(TKey)key];
+ return GenericDictionary[(TKey)key];
}
}
set
@@ -477,7 +493,13 @@ object IDictionary.this[object key]
#endif
else
{
- _genericDictionary[(TKey)key] = (TValue)value;
+ // Consider changing this code to call GenericDictionary.Remove when value is null.
+ //
+#pragma warning disable CS8601 // Possible null reference assignment.
+#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
+ GenericDictionary[(TKey)key] = (TValue)value;
+#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
+#pragma warning restore CS8601 // Possible null reference assignment.
}
}
}
@@ -496,9 +518,9 @@ public DictionaryEnumerator(IEnumerator Entry.Key;
- public object Value => Entry.Value;
+ public object? Value => Entry.Value;
- public object Current => new DictionaryEntry(_e.Current.Key, _e.Current.Value);
+ public object Current => new DictionaryEntry(_e.Current.Key!, _e.Current.Value);
public bool MoveNext()
{
@@ -525,7 +547,7 @@ IDictionaryEnumerator IDictionary.GetEnumerator()
#endif
else
{
- return new DictionaryEnumerator(_genericDictionary.GetEnumerator());
+ return new DictionaryEnumerator(GenericDictionary.GetEnumerator());
}
}
@@ -543,7 +565,7 @@ bool IDictionary.Contains(object key)
#endif
else
{
- return _dictionary.Contains(key);
+ return _dictionary!.Contains(key);
}
}
@@ -563,7 +585,7 @@ bool IDictionary.IsFixedSize
#endif
else
{
- return _dictionary.IsFixedSize;
+ return _dictionary!.IsFixedSize;
}
}
}
@@ -584,7 +606,7 @@ ICollection IDictionary.Keys
#endif
else
{
- return _dictionary.Keys;
+ return _dictionary!.Keys;
}
}
}
@@ -603,7 +625,7 @@ public void Remove(object key)
#endif
else
{
- _genericDictionary.Remove((TKey)key);
+ GenericDictionary.Remove((TKey)key);
}
}
@@ -623,7 +645,7 @@ ICollection IDictionary.Values
#endif
else
{
- return _dictionary.Values;
+ return _dictionary!.Values;
}
}
}
@@ -642,7 +664,7 @@ void ICollection.CopyTo(Array array, int index)
#endif
else
{
- _genericDictionary.CopyTo((KeyValuePair[])array, index);
+ GenericDictionary.CopyTo((KeyValuePair[])array, index);
}
}
@@ -690,9 +712,10 @@ public object UnderlyingDictionary
#endif
else
{
- return _genericDictionary;
+ return GenericDictionary;
}
}
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxy.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxy.cs
index 8daf1613e1..61236be7d0 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxy.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxy.cs
@@ -29,6 +29,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal class DynamicProxy
{
public virtual IEnumerable GetDynamicMemberNames(T instance)
@@ -36,19 +37,19 @@ public virtual IEnumerable GetDynamicMemberNames(T instance)
return CollectionUtils.ArrayEmpty();
}
- public virtual bool TryBinaryOperation(T instance, BinaryOperationBinder binder, object arg, out object result)
+ public virtual bool TryBinaryOperation(T instance, BinaryOperationBinder binder, object arg, out object? result)
{
result = null;
return false;
}
- public virtual bool TryConvert(T instance, ConvertBinder binder, out object result)
+ public virtual bool TryConvert(T instance, ConvertBinder binder, out object? result)
{
result = null;
return false;
}
- public virtual bool TryCreateInstance(T instance, CreateInstanceBinder binder, object[] args, out object result)
+ public virtual bool TryCreateInstance(T instance, CreateInstanceBinder binder, object[] args, out object? result)
{
result = null;
return false;
@@ -64,25 +65,25 @@ public virtual bool TryDeleteMember(T instance, DeleteMemberBinder binder)
return false;
}
- public virtual bool TryGetIndex(T instance, GetIndexBinder binder, object[] indexes, out object result)
+ public virtual bool TryGetIndex(T instance, GetIndexBinder binder, object[] indexes, out object? result)
{
result = null;
return false;
}
- public virtual bool TryGetMember(T instance, GetMemberBinder binder, out object result)
+ public virtual bool TryGetMember(T instance, GetMemberBinder binder, out object? result)
{
result = null;
return false;
}
- public virtual bool TryInvoke(T instance, InvokeBinder binder, object[] args, out object result)
+ public virtual bool TryInvoke(T instance, InvokeBinder binder, object[] args, out object? result)
{
result = null;
return false;
}
- public virtual bool TryInvokeMember(T instance, InvokeMemberBinder binder, object[] args, out object result)
+ public virtual bool TryInvokeMember(T instance, InvokeMemberBinder binder, object[] args, out object? result)
{
result = null;
return false;
@@ -98,12 +99,13 @@ public virtual bool TrySetMember(T instance, SetMemberBinder binder, object valu
return false;
}
- public virtual bool TryUnaryOperation(T instance, UnaryOperationBinder binder, out object result)
+ public virtual bool TryUnaryOperation(T instance, UnaryOperationBinder binder, out object? result)
{
result = null;
return false;
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxyMetaObject.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxyMetaObject.cs
index 4d9591f11f..760b1b58a5 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxyMetaObject.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicProxyMetaObject.cs
@@ -32,12 +32,13 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal sealed class DynamicProxyMetaObject : DynamicMetaObject
{
private readonly DynamicProxy _proxy;
internal DynamicProxyMetaObject(Expression expression, T value, DynamicProxy proxy)
- : base(expression, BindingRestrictions.Empty, value)
+ : base(expression, BindingRestrictions.Empty, value!)
{
_proxy = proxy;
}
@@ -109,7 +110,7 @@ public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, Dy
new GetBinderAdapter(binder),
NoArgs,
fallback(null),
- e => binder.FallbackInvoke(e, args, null)
+ e => binder.FallbackInvoke(e!, args, null)
),
null
);
@@ -164,7 +165,7 @@ public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, Dyna
: base.BindDeleteIndex(binder, indexes);
}
- private delegate DynamicMetaObject Fallback(DynamicMetaObject errorSuggestion);
+ private delegate DynamicMetaObject Fallback(DynamicMetaObject? errorSuggestion);
private static Expression[] NoArgs => CollectionUtils.ArrayEmpty();
@@ -197,7 +198,7 @@ private static ConstantExpression Constant(DynamicMetaObjectBinder binder)
Type t = binder.GetType();
while (!t.IsVisible())
{
- t = t.BaseType();
+ t = t.BaseType()!;
}
return Expression.Constant(binder, t);
}
@@ -206,7 +207,7 @@ private static ConstantExpression Constant(DynamicMetaObjectBinder binder)
/// Helper method for generating a MetaObject which calls a
/// specific method on Dynamic that returns a result
///
- private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, IEnumerable args, Fallback fallback, Fallback fallbackInvoke = null)
+ private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, IEnumerable args, Fallback fallback, Fallback? fallbackInvoke = null)
{
//
// First, call fallback to do default binding
@@ -217,7 +218,7 @@ private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObj
return BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);
}
- private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, IEnumerable args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
+ private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, IEnumerable args, DynamicMetaObject fallbackResult, Fallback? fallbackInvoke)
{
//
// Build a new expression like:
@@ -256,7 +257,7 @@ private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMe
Expression.Condition(
Expression.Call(
Expression.Constant(_proxy),
- typeof(DynamicProxy).GetMethod(methodName),
+ typeof(DynamicProxy).GetMethod(methodName)!,
callArgs
),
resultMetaObject.Expression,
@@ -304,7 +305,7 @@ private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObj
Expression.Condition(
Expression.Call(
Expression.Constant(_proxy),
- typeof(DynamicProxy).GetMethod(methodName),
+ typeof(DynamicProxy).GetMethod(methodName)!,
callArgs
),
result,
@@ -342,7 +343,7 @@ private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjec
Expression.Condition(
Expression.Call(
Expression.Constant(_proxy),
- typeof(DynamicProxy).GetMethod(methodName),
+ typeof(DynamicProxy).GetMethod(methodName)!,
callArgs
),
Expression.Empty(),
@@ -366,7 +367,7 @@ private BindingRestrictions GetRestrictions()
public override IEnumerable GetDynamicMemberNames()
{
- return _proxy.GetDynamicMemberNames((T)Value);
+ return _proxy.GetDynamicMemberNames((T)Value!);
}
// It is okay to throw NotSupported from this binder. This object
@@ -380,12 +381,13 @@ internal GetBinderAdapter(InvokeMemberBinder binder) :
{
}
- public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+ public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject? errorSuggestion)
{
throw new NotSupportedException();
}
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicReflectionDelegateFactory.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicReflectionDelegateFactory.cs
index 0e9c82a7b2..b2d50cca6d 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicReflectionDelegateFactory.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicReflectionDelegateFactory.cs
@@ -36,11 +36,12 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal class DynamicReflectionDelegateFactory : ReflectionDelegateFactory
{
internal static DynamicReflectionDelegateFactory Instance { get; } = new DynamicReflectionDelegateFactory();
- private static DynamicMethod CreateDynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner)
+ private static DynamicMethod CreateDynamicMethod(string name, Type? returnType, Type[] parameterTypes, Type owner)
{
DynamicMethod dynamicMethod = !owner.IsInterface()
? new DynamicMethod(name, returnType, parameterTypes, owner, true)
@@ -51,7 +52,7 @@ private static DynamicMethod CreateDynamicMethod(string name, Type returnType, T
public override ObjectConstructor CreateParameterizedConstructor(MethodBase method)
{
- DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object[]) }, method.DeclaringType);
+ DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString()!, typeof(object), new[] { typeof(object[]) }, method.DeclaringType!);
ILGenerator generator = dynamicMethod.GetILGenerator();
GenerateCreateMethodCallIL(method, generator, 0);
@@ -59,14 +60,14 @@ public override ObjectConstructor CreateParameterizedConstructor(MethodB
return (ObjectConstructor)dynamicMethod.CreateDelegate(typeof(ObjectConstructor));
}
- public override MethodCall CreateMethodCall(MethodBase method)
+ public override MethodCall CreateMethodCall(MethodBase method)
{
- DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType);
+ DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString()!, typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType!);
ILGenerator generator = dynamicMethod.GetILGenerator();
GenerateCreateMethodCallIL(method, generator, 1);
- return (MethodCall)dynamicMethod.CreateDelegate(typeof(MethodCall));
+ return (MethodCall)dynamicMethod.CreateDelegate(typeof(MethodCall));
}
private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator, int argsIndex)
@@ -80,19 +81,22 @@ private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator
generator.Emit(OpCodes.Ldlen);
generator.Emit(OpCodes.Ldc_I4, args.Length);
generator.Emit(OpCodes.Beq, argsOk);
- generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
+ generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes)!);
generator.Emit(OpCodes.Throw);
generator.MarkLabel(argsOk);
if (!method.IsConstructor && !method.IsStatic)
{
- generator.PushInstance(method.DeclaringType);
+ generator.PushInstance(method.DeclaringType!);
}
LocalBuilder localConvertible = generator.DeclareLocal(typeof(IConvertible));
LocalBuilder localObject = generator.DeclareLocal(typeof(object));
+ OpCode variableAddressOpCode = args.Length < 256 ? OpCodes.Ldloca_S : OpCodes.Ldloca;
+ OpCode variableLoadOpCode = args.Length < 256 ? OpCodes.Ldloc_S : OpCodes.Ldloc;
+
for (int i = 0; i < args.Length; i++)
{
ParameterInfo parameter = args[i];
@@ -100,7 +104,7 @@ private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator
if (parameterType.IsByRef)
{
- parameterType = parameterType.GetElementType();
+ parameterType = parameterType.GetElementType()!;
LocalBuilder localVariable = generator.DeclareLocal(parameterType);
@@ -118,7 +122,7 @@ private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator
generator.Emit(OpCodes.Brtrue_S, skipSettingDefault);
// parameter has no value, initialize to default
- generator.Emit(OpCodes.Ldloca_S, localVariable);
+ generator.Emit(variableAddressOpCode, localVariable);
generator.Emit(OpCodes.Initobj, parameterType);
generator.Emit(OpCodes.Br_S, finishedProcessingParameter);
@@ -138,7 +142,7 @@ private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator
}
}
- generator.Emit(OpCodes.Ldloca_S, localVariable);
+ generator.Emit(variableAddressOpCode, localVariable);
}
else if (parameterType.IsValueType())
{
@@ -156,9 +160,9 @@ private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator
// parameter has no value, initialize to default
LocalBuilder localVariable = generator.DeclareLocal(parameterType);
- generator.Emit(OpCodes.Ldloca_S, localVariable);
+ generator.Emit(variableAddressOpCode, localVariable);
generator.Emit(OpCodes.Initobj, parameterType);
- generator.Emit(OpCodes.Ldloc_S, localVariable);
+ generator.Emit(variableLoadOpCode, localVariable);
generator.Emit(OpCodes.Br_S, finishedProcessingParameter);
// argument has value, try to convert it to parameter type
@@ -167,7 +171,7 @@ private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator
if (parameterType.IsPrimitive())
{
// for primitive types we need to handle type widening (e.g. short -> int)
- MethodInfo toParameterTypeMethod = typeof(IConvertible)
+ MethodInfo? toParameterTypeMethod = typeof(IConvertible)
.GetMethod("To" + parameterType.Name, new[] { typeof(IFormatProvider) });
if (toParameterTypeMethod != null)
@@ -224,7 +228,7 @@ private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator
}
Type returnType = method.IsConstructor
- ? method.DeclaringType
+ ? method.DeclaringType!
: ((MethodInfo)method).ReturnType;
if (returnType != typeof(void))
@@ -265,7 +269,7 @@ private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator
}
else
{
- ConstructorInfo constructorInfo =
+ ConstructorInfo? constructorInfo =
type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, ReflectionUtils.EmptyTypes, null);
if (constructorInfo == null)
@@ -279,19 +283,19 @@ private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator
generator.Return();
}
- public override Func CreateGet(PropertyInfo propertyInfo)
+ public override Func CreateGet(PropertyInfo propertyInfo)
{
- DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(object), new[] { typeof(T) }, propertyInfo.DeclaringType);
+ DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(object), new[] { typeof(T) }, propertyInfo.DeclaringType!);
ILGenerator generator = dynamicMethod.GetILGenerator();
GenerateCreateGetPropertyIL(propertyInfo, generator);
- return (Func)dynamicMethod.CreateDelegate(typeof(Func));
+ return (Func)dynamicMethod.CreateDelegate(typeof(Func));
}
private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator)
{
- MethodInfo getMethod = propertyInfo.GetGetMethod(true);
+ MethodInfo? getMethod = propertyInfo.GetGetMethod(true);
if (getMethod == null)
{
throw new ArgumentException("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture, propertyInfo.Name));
@@ -299,7 +303,7 @@ private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator
if (!getMethod.IsStatic)
{
- generator.PushInstance(propertyInfo.DeclaringType);
+ generator.PushInstance(propertyInfo.DeclaringType!);
}
generator.CallMethod(getMethod);
@@ -307,28 +311,28 @@ private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator
generator.Return();
}
- public override Func CreateGet(FieldInfo fieldInfo)
+ public override Func CreateGet(FieldInfo fieldInfo)
{
if (fieldInfo.IsLiteral)
{
- object constantValue = fieldInfo.GetValue(null);
- Func getter = o => constantValue;
+ object constantValue = fieldInfo.GetValue(null)!;
+ Func getter = o => constantValue;
return getter;
}
- DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType);
+ DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType!);
ILGenerator generator = dynamicMethod.GetILGenerator();
GenerateCreateGetFieldIL(fieldInfo, generator);
- return (Func)dynamicMethod.CreateDelegate(typeof(Func));
+ return (Func)dynamicMethod.CreateDelegate(typeof(Func));
}
private void GenerateCreateGetFieldIL(FieldInfo fieldInfo, ILGenerator generator)
{
if (!fieldInfo.IsStatic)
{
- generator.PushInstance(fieldInfo.DeclaringType);
+ generator.PushInstance(fieldInfo.DeclaringType!);
generator.Emit(OpCodes.Ldfld, fieldInfo);
}
else
@@ -340,21 +344,21 @@ private void GenerateCreateGetFieldIL(FieldInfo fieldInfo, ILGenerator generator
generator.Return();
}
- public override Action CreateSet(FieldInfo fieldInfo)
+ public override Action CreateSet(FieldInfo fieldInfo)
{
- DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(T), typeof(object) }, fieldInfo.DeclaringType);
+ DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(T), typeof(object) }, fieldInfo.DeclaringType!);
ILGenerator generator = dynamicMethod.GetILGenerator();
GenerateCreateSetFieldIL(fieldInfo, generator);
- return (Action)dynamicMethod.CreateDelegate(typeof(Action));
+ return (Action)dynamicMethod.CreateDelegate(typeof(Action));
}
internal static void GenerateCreateSetFieldIL(FieldInfo fieldInfo, ILGenerator generator)
{
if (!fieldInfo.IsStatic)
{
- generator.PushInstance(fieldInfo.DeclaringType);
+ generator.PushInstance(fieldInfo.DeclaringType!);
}
generator.Emit(OpCodes.Ldarg_1);
@@ -372,22 +376,22 @@ internal static void GenerateCreateSetFieldIL(FieldInfo fieldInfo, ILGenerator g
generator.Return();
}
- public override Action CreateSet(PropertyInfo propertyInfo)
+ public override Action CreateSet(PropertyInfo propertyInfo)
{
- DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new[] { typeof(T), typeof(object) }, propertyInfo.DeclaringType);
+ DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new[] { typeof(T), typeof(object) }, propertyInfo.DeclaringType!);
ILGenerator generator = dynamicMethod.GetILGenerator();
GenerateCreateSetPropertyIL(propertyInfo, generator);
- return (Action)dynamicMethod.CreateDelegate(typeof(Action));
+ return (Action)dynamicMethod.CreateDelegate(typeof(Action));
}
internal static void GenerateCreateSetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator)
{
- MethodInfo setMethod = propertyInfo.GetSetMethod(true);
+ MethodInfo setMethod = propertyInfo.GetSetMethod(true)!;
if (!setMethod.IsStatic)
{
- generator.PushInstance(propertyInfo.DeclaringType);
+ generator.PushInstance(propertyInfo.DeclaringType!);
}
generator.Emit(OpCodes.Ldarg_1);
@@ -396,6 +400,7 @@ internal static void GenerateCreateSetPropertyIL(PropertyInfo propertyInfo, ILGe
generator.Return();
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicUtils.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicUtils.cs
index 98386f4957..1d6abfc3a1 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicUtils.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/DynamicUtils.cs
@@ -38,9 +38,11 @@
using System.Text;
using System.Globalization;
using Microsoft.IdentityModel.Json.Serialization;
+using System.Diagnostics;
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal static class DynamicUtils
{
internal static class BinderWrapper
@@ -53,17 +55,17 @@ internal static class BinderWrapper
private const string CSharpArgumentInfoFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, " + CSharpAssemblyName;
private const string CSharpBinderFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, " + CSharpAssemblyName;
- private static object _getCSharpArgumentInfoArray;
- private static object _setCSharpArgumentInfoArray;
- private static MethodCall _getMemberCall;
- private static MethodCall _setMemberCall;
+ private static object? _getCSharpArgumentInfoArray;
+ private static object? _setCSharpArgumentInfoArray;
+ private static MethodCall? _getMemberCall;
+ private static MethodCall? _setMemberCall;
private static bool _init;
private static void Init()
{
if (!_init)
{
- Type binderType = Type.GetType(BinderTypeName, false);
+ Type? binderType = Type.GetType(BinderTypeName, false);
if (binderType == null)
{
throw new InvalidOperationException("Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types.".FormatWith(CultureInfo.InvariantCulture, BinderTypeName));
@@ -81,15 +83,15 @@ private static void Init()
private static object CreateSharpArgumentInfoArray(params int[] values)
{
- Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
- Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName);
+ Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName, true)!;
+ Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName, true)!;
Array a = Array.CreateInstance(csharpArgumentInfoType, values.Length);
for (int i = 0; i < values.Length; i++)
{
- MethodInfo createArgumentInfoMethod = csharpArgumentInfoType.GetMethod("Create", new[] { csharpArgumentInfoFlags, typeof(string) });
- object arg = createArgumentInfoMethod.Invoke(null, new object[] { 0, null });
+ MethodInfo createArgumentInfoMethod = csharpArgumentInfoType.GetMethod("Create", new[] { csharpArgumentInfoFlags, typeof(string) })!;
+ object arg = createArgumentInfoMethod.Invoke(null, new object?[] { 0, null })!;
a.SetValue(arg, i);
}
@@ -98,17 +100,17 @@ private static object CreateSharpArgumentInfoArray(params int[] values)
private static void CreateMemberCalls()
{
- Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName, true);
- Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName, true);
- Type binderType = Type.GetType(BinderTypeName, true);
+ Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName, true)!;
+ Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName, true)!;
+ Type binderType = Type.GetType(BinderTypeName, true)!;
Type csharpArgumentInfoTypeEnumerableType = typeof(IEnumerable<>).MakeGenericType(csharpArgumentInfoType);
- MethodInfo getMemberMethod = binderType.GetMethod("GetMember", new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType });
- _getMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getMemberMethod);
+ MethodInfo getMemberMethod = binderType.GetMethod("GetMember", new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType })!;
+ _getMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getMemberMethod);
- MethodInfo setMemberMethod = binderType.GetMethod("SetMember", new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType });
- _setMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(setMemberMethod);
+ MethodInfo setMemberMethod = binderType.GetMethod("SetMember", new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType })!;
+ _setMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(setMemberMethod);
}
#endif
@@ -116,7 +118,9 @@ public static CallSiteBinder GetMember(string name, Type context)
{
#if !HAVE_REFLECTION_BINDER
Init();
- return (CallSiteBinder)_getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray);
+ MiscellaneousUtils.Assert(_getMemberCall != null);
+ MiscellaneousUtils.Assert(_getCSharpArgumentInfoArray != null);
+ return (CallSiteBinder)_getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray)!;
#else
return Binder.GetMember(
CSharpBinderFlags.None, name, context, new[] {CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
@@ -127,7 +131,9 @@ public static CallSiteBinder SetMember(string name, Type context)
{
#if !HAVE_REFLECTION_BINDER
Init();
- return (CallSiteBinder)_setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray);
+ MiscellaneousUtils.Assert(_setMemberCall != null);
+ MiscellaneousUtils.Assert(_setCSharpArgumentInfoArray != null);
+ return (CallSiteBinder)_setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray)!;
#else
return Binder.SetMember(
CSharpBinderFlags.None, name, context, new[]
@@ -156,7 +162,7 @@ public NoThrowGetBinderMember(GetMemberBinder innerBinder)
_innerBinder = innerBinder;
}
- public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+ public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject? errorSuggestion)
{
DynamicMetaObject retMetaObject = _innerBinder.Bind(target, CollectionUtils.ArrayEmpty());
@@ -178,7 +184,7 @@ public NoThrowSetBinderMember(SetMemberBinder innerBinder)
_innerBinder = innerBinder;
}
- public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
+ public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject? errorSuggestion)
{
DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { value });
@@ -205,6 +211,7 @@ protected override Expression VisitConditional(ConditionalExpression node)
return base.VisitConditional(node);
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/EnumUtils.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/EnumUtils.cs
index 77bc52ef94..176904e26d 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/EnumUtils.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/EnumUtils.cs
@@ -36,35 +36,41 @@
using System.Reflection;
using System.Text;
using Microsoft.IdentityModel.Json.Serialization;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal static class EnumUtils
{
private const char EnumSeparatorChar = ',';
private const string EnumSeparatorString = ", ";
- private static readonly ThreadSafeStore, EnumInfo> ValuesAndNamesPerEnum = new ThreadSafeStore, EnumInfo>(InitializeValuesAndNames);
+ private static readonly ThreadSafeStore, EnumInfo> ValuesAndNamesPerEnum = new ThreadSafeStore, EnumInfo>(InitializeValuesAndNames);
- private static EnumInfo InitializeValuesAndNames(StructMultiKey key)
+ private static EnumInfo InitializeValuesAndNames(StructMultiKey key)
{
Type enumType = key.Value1;
string[] names = Enum.GetNames(enumType);
string[] resolvedNames = new string[names.Length];
ulong[] values = new ulong[names.Length];
+ bool hasSpecifiedName;
for (int i = 0; i < names.Length; i++)
{
string name = names[i];
- FieldInfo f = enumType.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
- values[i] = ToUInt64(f.GetValue(null));
+ FieldInfo f = enumType.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)!;
+ values[i] = ToUInt64(f.GetValue(null)!);
string resolvedName;
#if HAVE_DATA_CONTRACTS
- resolvedName = f.GetCustomAttributes(typeof(EnumMemberAttribute), true)
+ string? specifiedName = f.GetCustomAttributes(typeof(EnumMemberAttribute), true)
.Cast()
.Select(a => a.Value)
- .SingleOrDefault() ?? f.Name;
+ .SingleOrDefault();
+ hasSpecifiedName = specifiedName != null;
+ resolvedName = specifiedName ?? name;
if (Array.IndexOf(resolvedNames, resolvedName, 0, i) != -1)
{
@@ -72,10 +78,11 @@ private static EnumInfo InitializeValuesAndNames(StructMultiKey GetFlagsValues(T value) where T : struct
return selectedFlagsValues;
}
- public static bool TryToString(Type enumType, object value, NamingStrategy namingStrategy, out string name)
+ // Used by Microsoft.IdentityModel.Json.Schema
+ private static CamelCaseNamingStrategy _camelCaseNamingStrategy = new CamelCaseNamingStrategy();
+ public static bool TryToString(Type enumType, object value, bool camelCase, [NotNullWhen(true)]out string? name)
{
- EnumInfo enumInfo = ValuesAndNamesPerEnum.Get(new StructMultiKey(enumType, namingStrategy));
+ return TryToString(enumType, value, camelCase ? _camelCaseNamingStrategy : null, out name);
+ }
+
+ public static bool TryToString(Type enumType, object value, NamingStrategy? namingStrategy, [NotNullWhen(true)]out string? name)
+ {
+ EnumInfo enumInfo = ValuesAndNamesPerEnum.Get(new StructMultiKey(enumType, namingStrategy));
ulong v = ToUInt64(value);
if (!enumInfo.IsFlags)
@@ -142,7 +156,7 @@ public static bool TryToString(Type enumType, object value, NamingStrategy namin
}
}
- private static string InternalFlagsFormat(EnumInfo entry, ulong result)
+ private static string? InternalFlagsFormat(EnumInfo entry, ulong result)
{
string[] resolvedNames = entry.ResolvedNames;
ulong[] values = entry.Values;
@@ -178,7 +192,7 @@ private static string InternalFlagsFormat(EnumInfo entry, ulong result)
index--;
}
- string returnString;
+ string? returnString;
if (result != 0)
{
// We were unable to represent this number as a bitwise or of valid flags
@@ -206,7 +220,7 @@ private static string InternalFlagsFormat(EnumInfo entry, ulong result)
public static EnumInfo GetEnumValuesAndNames(Type enumType)
{
- return ValuesAndNamesPerEnum.Get(new StructMultiKey(enumType, null));
+ return ValuesAndNamesPerEnum.Get(new StructMultiKey(enumType, null));
}
private static ulong ToUInt64(object value)
@@ -242,7 +256,7 @@ private static ulong ToUInt64(object value)
}
}
- public static object ParseEnum(Type enumType, NamingStrategy namingStrategy, string value, bool disallowNumber)
+ public static object ParseEnum(Type enumType, NamingStrategy? namingStrategy, string value, bool disallowNumber)
{
ValidationUtils.ArgumentNotNull(enumType, nameof(enumType));
ValidationUtils.ArgumentNotNull(value, nameof(value));
@@ -252,7 +266,7 @@ public static object ParseEnum(Type enumType, NamingStrategy namingStrategy, str
throw new ArgumentException("Type provided must be an Enum.", nameof(enumType));
}
- EnumInfo entry = ValuesAndNamesPerEnum.Get(new StructMultiKey(enumType, namingStrategy));
+ EnumInfo entry = ValuesAndNamesPerEnum.Get(new StructMultiKey(enumType, namingStrategy));
string[] enumNames = entry.Names;
string[] resolvedNames = entry.ResolvedNames;
ulong[] enumValues = entry.Values;
@@ -285,7 +299,7 @@ public static object ParseEnum(Type enumType, NamingStrategy namingStrategy, str
Type underlyingType = Enum.GetUnderlyingType(enumType);
value = value.Trim();
- object temp = null;
+ object? temp = null;
try
{
@@ -391,4 +405,5 @@ public static object ParseEnum(Type enumType, NamingStrategy namingStrategy, str
return null;
}
}
-}
\ No newline at end of file
+#nullable disable
+}
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ExpressionReflectionDelegateFactory.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ExpressionReflectionDelegateFactory.cs
index 357e654fc2..078112ca81 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ExpressionReflectionDelegateFactory.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/ExpressionReflectionDelegateFactory.cs
@@ -35,6 +35,7 @@
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal class ExpressionReflectionDelegateFactory : ReflectionDelegateFactory
{
private static readonly ExpressionReflectionDelegateFactory _instance = new ExpressionReflectionDelegateFactory();
@@ -57,7 +58,7 @@ public override ObjectConstructor CreateParameterizedConstructor(MethodB
return compiled;
}
- public override MethodCall CreateMethodCall(MethodBase method)
+ public override MethodCall CreateMethodCall(MethodBase method)
{
ValidationUtils.ArgumentNotNull(method, nameof(method));
@@ -70,7 +71,7 @@ public override MethodCall CreateMethodCall(MethodBase method)
LambdaExpression lambdaExpression = Expression.Lambda(typeof(MethodCall), callExpression, targetParameterExpression, argsParameterExpression);
- MethodCall compiled = (MethodCall)lambdaExpression.Compile();
+ MethodCall compiled = (MethodCall)lambdaExpression.Compile();
return compiled;
}
@@ -79,9 +80,16 @@ private class ByRefParameter
public Expression Value;
public ParameterExpression Variable;
public bool IsOut;
+
+ public ByRefParameter(Expression value, ParameterExpression variable, bool isOut)
+ {
+ Value = value;
+ Variable = variable;
+ IsOut = isOut;
+ }
}
- private Expression BuildMethodCall(MethodBase method, Type type, ParameterExpression targetParameterExpression, ParameterExpression argsParameterExpression)
+ private Expression BuildMethodCall(MethodBase method, Type type, ParameterExpression? targetParameterExpression, ParameterExpression argsParameterExpression)
{
ParameterInfo[] parametersInfo = method.GetParameters();
@@ -104,7 +112,7 @@ private Expression BuildMethodCall(MethodBase method, Type type, ParameterExpres
bool isByRef = false;
if (parameterType.IsByRef)
{
- parameterType = parameterType.GetElementType();
+ parameterType = parameterType.GetElementType()!;
isByRef = true;
}
@@ -117,7 +125,7 @@ private Expression BuildMethodCall(MethodBase method, Type type, ParameterExpres
if (isByRef)
{
ParameterExpression variable = Expression.Variable(parameterType);
- refParameterMap.Add(new ByRefParameter {Value = argExpression, Variable = variable, IsOut = parameter.IsOut});
+ refParameterMap.Add(new ByRefParameter(argExpression, variable, parameter.IsOut));
argExpression = variable;
}
@@ -137,7 +145,7 @@ private Expression BuildMethodCall(MethodBase method, Type type, ParameterExpres
}
else
{
- Expression readParameter = EnsureCastExpression(targetParameterExpression, method.DeclaringType);
+ Expression readParameter = EnsureCastExpression(targetParameterExpression!, method.DeclaringType!);
callExpression = Expression.Call(readParameter, (MethodInfo)method, argsExpression);
}
@@ -187,7 +195,7 @@ public override Func CreateDefaultConstructor(Type type)
// avoid error from expressions compiler because of abstract class
if (type.IsAbstract())
{
- return () => (T)Activator.CreateInstance(type);
+ return () => (T)Activator.CreateInstance(type)!;
}
try
@@ -207,11 +215,11 @@ public override Func CreateDefaultConstructor(Type type)
{
// an error can be thrown if constructor is not valid on Win8
// will have INVOCATION_FLAGS_NON_W8P_FX_API invocation flag
- return () => (T)Activator.CreateInstance(type);
+ return () => (T)Activator.CreateInstance(type)!;
}
}
- public override Func CreateGet(PropertyInfo propertyInfo)
+ public override Func CreateGet(PropertyInfo propertyInfo)
{
ValidationUtils.ArgumentNotNull(propertyInfo, nameof(propertyInfo));
@@ -221,7 +229,11 @@ public override Func CreateGet(PropertyInfo propertyInfo)
ParameterExpression parameterExpression = Expression.Parameter(instanceType, "instance");
Expression resultExpression;
- MethodInfo getMethod = propertyInfo.GetGetMethod(true);
+ MethodInfo? getMethod = propertyInfo.GetGetMethod(true);
+ if (getMethod == null)
+ {
+ throw new ArgumentException("Property does not have a getter.");
+ }
if (getMethod.IsStatic)
{
@@ -229,7 +241,7 @@ public override Func CreateGet(PropertyInfo propertyInfo)
}
else
{
- Expression readParameter = EnsureCastExpression(parameterExpression, propertyInfo.DeclaringType);
+ Expression readParameter = EnsureCastExpression(parameterExpression, propertyInfo.DeclaringType!);
resultExpression = Expression.MakeMemberAccess(readParameter, propertyInfo);
}
@@ -238,11 +250,11 @@ public override Func CreateGet(PropertyInfo propertyInfo)
LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func), resultExpression, parameterExpression);
- Func compiled = (Func)lambdaExpression.Compile();
+ Func compiled = (Func)lambdaExpression.Compile();
return compiled;
}
- public override Func CreateGet(FieldInfo fieldInfo)
+ public override Func CreateGet(FieldInfo fieldInfo)
{
ValidationUtils.ArgumentNotNull(fieldInfo, nameof(fieldInfo));
@@ -255,24 +267,24 @@ public override Func CreateGet(FieldInfo fieldInfo)
}
else
{
- Expression sourceExpression = EnsureCastExpression(sourceParameter, fieldInfo.DeclaringType);
+ Expression sourceExpression = EnsureCastExpression(sourceParameter, fieldInfo.DeclaringType!);
fieldExpression = Expression.Field(sourceExpression, fieldInfo);
}
fieldExpression = EnsureCastExpression(fieldExpression, typeof(object));
- Func compiled = Expression.Lambda>(fieldExpression, sourceParameter).Compile();
+ Func compiled = Expression.Lambda>(fieldExpression, sourceParameter).Compile();
return compiled;
}
- public override Action CreateSet(FieldInfo fieldInfo)
+ public override Action CreateSet(FieldInfo fieldInfo)
{
ValidationUtils.ArgumentNotNull(fieldInfo, nameof(fieldInfo));
// use reflection for structs
// expression doesn't correctly set value
- if (fieldInfo.DeclaringType.IsValueType() || fieldInfo.IsInitOnly)
+ if (fieldInfo.DeclaringType!.IsValueType() || fieldInfo.IsInitOnly)
{
return LateBoundReflectionDelegateFactory.Instance.CreateSet(fieldInfo);
}
@@ -287,7 +299,7 @@ public override Action CreateSet(FieldInfo fieldInfo)
}
else
{
- Expression sourceExpression = EnsureCastExpression(sourceParameterExpression, fieldInfo.DeclaringType);
+ Expression sourceExpression = EnsureCastExpression(sourceParameterExpression, fieldInfo.DeclaringType!);
fieldExpression = Expression.Field(sourceExpression, fieldInfo);
}
@@ -298,17 +310,17 @@ public override Action CreateSet(FieldInfo fieldInfo)
LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action), assignExpression, sourceParameterExpression, valueParameterExpression);
- Action compiled = (Action)lambdaExpression.Compile();
+ Action compiled = (Action)lambdaExpression.Compile();
return compiled;
}
- public override Action CreateSet(PropertyInfo propertyInfo)
+ public override Action CreateSet(PropertyInfo propertyInfo)
{
ValidationUtils.ArgumentNotNull(propertyInfo, nameof(propertyInfo));
// use reflection for structs
// expression doesn't correctly set value
- if (propertyInfo.DeclaringType.IsValueType())
+ if (propertyInfo.DeclaringType!.IsValueType())
{
return LateBoundReflectionDelegateFactory.Instance.CreateSet(propertyInfo);
}
@@ -321,7 +333,11 @@ public override Action CreateSet(PropertyInfo propertyInfo)
ParameterExpression valueParameter = Expression.Parameter(valueType, "value");
Expression readValueParameter = EnsureCastExpression(valueParameter, propertyInfo.PropertyType);
- MethodInfo setMethod = propertyInfo.GetSetMethod(true);
+ MethodInfo? setMethod = propertyInfo.GetSetMethod(true);
+ if (setMethod == null)
+ {
+ throw new ArgumentException("Property does not have a setter.");
+ }
Expression setExpression;
if (setMethod.IsStatic)
@@ -330,14 +346,14 @@ public override Action CreateSet(PropertyInfo propertyInfo)
}
else
{
- Expression readInstanceParameter = EnsureCastExpression(instanceParameter, propertyInfo.DeclaringType);
+ Expression readInstanceParameter = EnsureCastExpression(instanceParameter, propertyInfo.DeclaringType!);
setExpression = Expression.Call(readInstanceParameter, setMethod, readValueParameter);
}
- LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action), setExpression, instanceParameter, valueParameter);
+ LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action), setExpression, instanceParameter, valueParameter);
- Action compiled = (Action)lambdaExpression.Compile();
+ Action compiled = (Action)lambdaExpression.Compile();
return compiled;
}
@@ -357,7 +373,7 @@ private Expression EnsureCastExpression(Expression expression, Type targetType,
if (allowWidening && targetType.IsPrimitive())
{
- MethodInfo toTargetTypeMethod = typeof(Convert)
+ MethodInfo? toTargetTypeMethod = typeof(Convert)
.GetMethod("To" + targetType.Name, new[] { typeof(object) });
if (toTargetTypeMethod != null)
@@ -378,6 +394,7 @@ private Expression EnsureCastExpression(Expression expression, Type targetType,
return Expression.Convert(expression, targetType);
}
}
+#nullable disable
}
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/FSharpUtils.cs b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/FSharpUtils.cs
index 17794cfedb..b6a19e3f9e 100644
--- a/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/FSharpUtils.cs
+++ b/src/Microsoft.IdentityModel.Tokens/opensource/json/Utilities/FSharpUtils.cs
@@ -31,15 +31,17 @@
using System.Reflection;
using System.Text;
using Microsoft.IdentityModel.Json.Serialization;
+using System.Diagnostics;
namespace Microsoft.IdentityModel.Json.Utilities
{
+#nullable enable
internal class FSharpFunction
{
- private readonly object _instance;
- private readonly MethodCall _invoker;
+ private readonly object? _instance;
+ private readonly MethodCall _invoker;
- public FSharpFunction(object instance, MethodCall invoker)
+ public FSharpFunction(object? instance, MethodCall invoker)
{
_instance = instance;
_invoker = invoker;
@@ -53,69 +55,78 @@ public object Invoke(params object[] args)
}
}
- internal static class FSharpUtils
+ internal class FSharpUtils
{
- private static readonly object Lock = new object();
+ private FSharpUtils(Assembly fsharpCoreAssembly)
+ {
+ FSharpCoreAssembly = fsharpCoreAssembly;
- private static bool _initialized;
- private static MethodInfo _ofSeq;
- private static Type _mapType;
-
- public static Assembly FSharpCoreAssembly { get; private set; }
- public static MethodCall IsUnion { get; private set; }
- public static MethodCall GetUnionCases { get; private set; }
- public static MethodCall PreComputeUnionTagReader { get; private set; }
- public static MethodCall PreComputeUnionReader { get; private set; }
- public static MethodCall PreComputeUnionConstructor { get; private set; }
- public static Func GetUnionCaseInfoDeclaringType { get; private set; }
- public static Func GetUnionCaseInfoName { get; private set; }
- public static Func GetUnionCaseInfoTag { get; private set; }
- public static MethodCall GetUnionCaseInfoFields { get; private set; }
+ Type fsharpType = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpType")!;
- public const string FSharpSetTypeName = "FSharpSet`1";
- public const string FSharpListTypeName = "FSharpList`1";
- public const string FSharpMapTypeName = "FSharpMap`2";
+ MethodInfo isUnionMethodInfo = GetMethodWithNonPublicFallback(fsharpType, "IsUnion", BindingFlags.Public | BindingFlags.Static);
+ IsUnion = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(isUnionMethodInfo)!;
- public static void EnsureInitialized(Assembly fsharpCoreAssembly)
- {
- if (!_initialized)
- {
- lock (Lock)
- {
- if (!_initialized)
- {
- FSharpCoreAssembly = fsharpCoreAssembly;
+ MethodInfo getUnionCasesMethodInfo = GetMethodWithNonPublicFallback(fsharpType, "GetUnionCases", BindingFlags.Public | BindingFlags.Static);
+ GetUnionCases = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getUnionCasesMethodInfo)!;
+
+ Type fsharpValue = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpValue")!;
- Type fsharpType = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpType");
+ PreComputeUnionTagReader = CreateFSharpFuncCall(fsharpValue, "PreComputeUnionTagReader");
+ PreComputeUnionReader = CreateFSharpFuncCall(fsharpValue, "PreComputeUnionReader");
+ PreComputeUnionConstructor = CreateFSharpFuncCall(fsharpValue, "PreComputeUnionConstructor");
- MethodInfo isUnionMethodInfo = GetMethodWithNonPublicFallback(fsharpType, "IsUnion", BindingFlags.Public | BindingFlags.Static);
- IsUnion = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(isUnionMethodInfo);
+ Type unionCaseInfo = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.UnionCaseInfo")!;
- MethodInfo getUnionCasesMethodInfo = GetMethodWithNonPublicFallback(fsharpType, "GetUnionCases", BindingFlags.Public | BindingFlags.Static);
- GetUnionCases = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getUnionCasesMethodInfo);
+ GetUnionCaseInfoName = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("Name")!)!;
+ GetUnionCaseInfoTag = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("Tag")!)!;
+ GetUnionCaseInfoDeclaringType = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("DeclaringType")!)!;
+ GetUnionCaseInfoFields = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(unionCaseInfo.GetMethod("GetFields")!);
- Type fsharpValue = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.FSharpValue");
+ Type listModule = fsharpCoreAssembly.GetType("Microsoft.FSharp.Collections.ListModule")!;
+ _ofSeq = listModule.GetMethod("OfSeq")!;
- PreComputeUnionTagReader = CreateFSharpFuncCall(fsharpValue, "PreComputeUnionTagReader");
- PreComputeUnionReader = CreateFSharpFuncCall(fsharpValue, "PreComputeUnionReader");
- PreComputeUnionConstructor = CreateFSharpFuncCall(fsharpValue, "PreComputeUnionConstructor");
+ _mapType = fsharpCoreAssembly.GetType("Microsoft.FSharp.Collections.FSharpMap`2")!;
+ }
+
+ private static readonly object Lock = new object();
+ private static FSharpUtils? _instance;
- Type unionCaseInfo = fsharpCoreAssembly.GetType("Microsoft.FSharp.Reflection.UnionCaseInfo");
+ public static FSharpUtils Instance
+ {
+ get
+ {
+ MiscellaneousUtils.Assert(_instance != null);
+ return _instance;
+ }
+ }
- GetUnionCaseInfoName = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("Name"));
- GetUnionCaseInfoTag = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("Tag"));
- GetUnionCaseInfoDeclaringType = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(unionCaseInfo.GetProperty("DeclaringType"));
- GetUnionCaseInfoFields = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(unionCaseInfo.GetMethod("GetFields"));
+ private MethodInfo _ofSeq;
+ private Type _mapType;
- Type listModule = fsharpCoreAssembly.GetType("Microsoft.FSharp.Collections.ListModule");
- _ofSeq = listModule.GetMethod("OfSeq");
+ public Assembly FSharpCoreAssembly { get; private set; }
+ public MethodCall IsUnion { get; private set; }
+ public MethodCall GetUnionCases { get; private set; }
+ public MethodCall PreComputeUnionTagReader { get; private set; }
+ public MethodCall PreComputeUnionReader { get; private set; }
+ public MethodCall PreComputeUnionConstructor { get; private set; }
+ public Func