Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2018-05-26 00:27:49 +0300
committerMarek Safar <marek.safar@gmail.com>2018-05-26 00:27:49 +0300
commit2fddf72d3d43004add7df0133f01fa230bedcaa9 (patch)
tree82f9d4c969b552f59557384253105eb6580e5328
parent8831553c919bf74772c0b382eb2c76e1c0af873a (diff)
parent615f75c590d83355acd85fe4a45ea5de6a08bfb7 (diff)
Update to head of 2.1 release branch
-rw-r--r--BuildToolsVersion.txt2
-rw-r--r--DotnetCLIVersion.txt2
-rw-r--r--Packaging.props2
-rw-r--r--buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json54
-rw-r--r--buildpipeline/DotNet-CoreFx-Trusted-Linux.json54
-rw-r--r--buildpipeline/DotNet-CoreFx-Trusted-OSX.json57
-rw-r--r--buildpipeline/DotNet-CoreFx-Trusted-Windows-NoTest.json27
-rw-r--r--buildpipeline/DotNet-CoreFx-Trusted-Windows.json27
-rw-r--r--buildpipeline/DotNet-Trusted-Publish-Symbols.json48
-rw-r--r--buildpipeline/DotNet-Trusted-Publish.json46
-rw-r--r--buildpipeline/DotNet-Trusted-Tests-Publish.json48
-rw-r--r--buildpipeline/linux-musl.groovy (renamed from buildpipeline/alpine.3.6.groovy)6
-rw-r--r--buildpipeline/pipeline.json16
-rw-r--r--buildpipeline/pipelinejobs.groovy4
-rw-r--r--dependencies.props24
-rw-r--r--external/runtime/runtime.depproj2
-rwxr-xr-xinit-tools.sh4
-rw-r--r--pkg/Microsoft.Private.CoreFx.NETCoreApp/netcoreapp.rids.props1
-rw-r--r--pkg/dir.props4
-rw-r--r--pkg/test/frameworkSettings/netcoreapp2.1/settings.targets8
-rw-r--r--pkg/test/testPackages.proj3
-rw-r--r--src/Common/src/CoreLib/System/Number.Parsing.cs61
-rw-r--r--src/Common/src/Interop/Unix/System.Native/Interop.WaitId.cs11
-rw-r--r--src/Common/src/Interop/Unix/System.Native/Interop.WaitPid.cs24
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.Print.cs3
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.cs12
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Bignum.cs9
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Crypto.cs13
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Dsa.cs15
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.ImportExport.cs9
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.cs32
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcKey.cs12
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Encode.cs12
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs22
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs23
-rw-r--r--src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs5
-rw-r--r--src/Common/src/System/Security/Cryptography/Asn1V2.Serializer.cs4
-rw-r--r--src/Common/src/System/Security/Cryptography/DSAOpenSsl.cs2
-rw-r--r--src/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs2
-rw-r--r--src/Common/src/System/Security/Cryptography/ECOpenSsl.ImportExport.cs4
-rw-r--r--src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs10
-rw-r--r--src/Microsoft.XmlSerializer.Generator/pkg/build/Microsoft.XmlSerializer.Generator.targets4
-rw-r--r--src/Microsoft.XmlSerializer.Generator/src/Sgen.cs18
-rw-r--r--src/Native/Unix/Common/pal_config.h.in1
-rw-r--r--src/Native/Unix/System.Native/pal_process.cpp42
-rw-r--r--src/Native/Unix/System.Native/pal_process.h16
-rw-r--r--src/Native/Unix/System.Native/pal_random.c7
-rw-r--r--src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp23
-rw-r--r--src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp28
-rw-r--r--src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h2
-rw-r--r--src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp5
-rw-r--r--src/Native/Unix/configure.cmake6
-rw-r--r--src/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj3
-rw-r--r--src/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs7
-rw-r--r--src/System.Diagnostics.Process/tests/ProcessTests.Unix.cs15
-rw-r--r--src/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj4
-rw-r--r--src/System.Diagnostics.StackTrace/src/System/Diagnostics/StackTraceSymbols.CoreCLR.cs15
-rw-r--r--src/System.IO.FileSystem/src/System.IO.FileSystem.csproj1
-rw-r--r--src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs18
-rw-r--r--src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Windows.cs8
-rw-r--r--src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.cs43
-rw-r--r--src/System.IO.FileSystem/tests/Directory/GetFiles.cs29
-rw-r--r--src/System.IO.FileSystem/tests/DirectoryInfo/EnumerableAPIs.cs2
-rw-r--r--src/System.IO.FileSystem/tests/DirectoryInfo/GetFiles.cs2
-rw-r--r--src/System.IO.FileSystem/tests/FileSystemTest.cs20
-rw-r--r--src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs2
-rw-r--r--src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs4
-rw-r--r--src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs2
-rw-r--r--src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs5
-rw-r--r--src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs44
-rw-r--r--src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj3
-rw-r--r--src/System.Private.Xml/src/Resources/Strings.resx2
-rw-r--r--src/System.Runtime/tests/System/BooleanTests.netcoreapp.cs20
-rw-r--r--src/System.Runtime/tests/System/ByteTests.netcoreapp.cs26
-rw-r--r--src/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs18
-rw-r--r--src/System.Runtime/tests/System/DecimalTests.netcoreapp.cs30
-rw-r--r--src/System.Runtime/tests/System/DoubleTests.netcoreapp.cs29
-rw-r--r--src/System.Runtime/tests/System/Int16Tests.netcoreapp.cs26
-rw-r--r--src/System.Runtime/tests/System/Int32Tests.netcoreapp.cs73
-rw-r--r--src/System.Runtime/tests/System/Int64Tests.netcoreapp.cs24
-rw-r--r--src/System.Runtime/tests/System/SByteTests.netcoreapp.cs24
-rw-r--r--src/System.Runtime/tests/System/SingleTests.netcoreapp.cs32
-rw-r--r--src/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs24
-rw-r--r--src/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs25
-rw-r--r--src/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs25
-rw-r--r--src/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs24
-rw-r--r--src/System.Runtime/tests/System/VersionTests.netcoreapp.cs22
-rw-r--r--src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs3
-rw-r--r--src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OpenSslAsnFormatter.cs69
-rw-r--r--src/System.Security.Cryptography.Encoding/tests/Asn1/Serializer/SimpleDeserialize.cs40
-rw-r--r--src/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs4
-rw-r--r--src/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs40
-rw-r--r--src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs96
-rw-r--r--src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs47
-rw-r--r--src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs6
-rw-r--r--src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs11
-rw-r--r--src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs12
-rw-r--r--src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs10
-rw-r--r--src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs7
-rw-r--r--src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.OpenSslDecode.cs1
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CipherReference.cs3
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs32
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs4
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs6
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs44
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/KeyInfo.cs9
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs4
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs54
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Signature.cs32
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedInfo.cs32
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs6
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs12
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/TransformChain.cs2
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs26
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDecryptionTransform.cs25
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigC14NTransform.cs6
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigEnvelopedSignatureTransform.cs6
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigExcC14NTransform.cs21
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigXPathTransform.cs41
-rw-r--r--src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlLicenseTransform.cs6
-rw-r--r--src/System.Security.Cryptography.Xml/tests/Configurations.props3
-rw-r--r--src/System.Security.Cryptography.Xml/tests/KeyInfo_ArbitraryElements.cs33
-rw-r--r--src/System.Security.Cryptography.Xml/tests/Reference_ArbitraryElements.cs156
-rw-r--r--src/System.Security.Cryptography.Xml/tests/Signature_ArbitraryElements.cs153
-rw-r--r--src/System.Security.Cryptography.Xml/tests/SignedInfo_ArbitraryElements.cs81
-rw-r--r--src/System.Security.Cryptography.Xml/tests/SignedXml_Helpers.cs34
-rw-r--r--src/System.Security.Cryptography.Xml/tests/SignedXml_Limits.cs41
-rw-r--r--src/System.Security.Cryptography.Xml/tests/SignedXml_SignatureMethodAlgorithm.cs38
-rw-r--r--src/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj15
-rw-r--r--src/System.Security.Cryptography.Xml/tests/XmlDecryptionTransformTest.cs2
-rw-r--r--src/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj2
-rw-r--r--src/System.ServiceModel.Syndication/src/Configurations.props1
-rw-r--r--src/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj10
-rw-r--r--src/System.ServiceModel.Syndication/tests/BasicScenarioTests.cs3
-rw-r--r--src/packages.builds9
-rw-r--r--tools-local/ILAsmVersion.txt2
136 files changed, 2414 insertions, 413 deletions
diff --git a/BuildToolsVersion.txt b/BuildToolsVersion.txt
index beab3dc4b9..aa4bd21bee 100644
--- a/BuildToolsVersion.txt
+++ b/BuildToolsVersion.txt
@@ -1 +1 @@
-2.1.0-rc1-02719-01
+2.1.0-rc1-02804-05
diff --git a/DotnetCLIVersion.txt b/DotnetCLIVersion.txt
index eca07e4c1a..319992f48c 100644
--- a/DotnetCLIVersion.txt
+++ b/DotnetCLIVersion.txt
@@ -1 +1 @@
-2.1.2
+2.1.300-rc1-008673 \ No newline at end of file
diff --git a/Packaging.props b/Packaging.props
index cc522b50d2..b54ccad190 100644
--- a/Packaging.props
+++ b/Packaging.props
@@ -2,7 +2,7 @@
<PropertyGroup>
<StabilizePackageVersion Condition="'$(StabilizePackageVersion)' == ''">false</StabilizePackageVersion>
<PreReleaseLabel Condition="'$(PackageVersionStamp)' != ''">$(PackageVersionStamp)</PreReleaseLabel>
- <PreReleaseLabel Condition="'$(PreReleaseLabel)' == ''">rc1</PreReleaseLabel>
+ <PreReleaseLabel Condition="'$(PreReleaseLabel)' == ''">rtm</PreReleaseLabel>
<IncludePreReleaseLabelInPackageVersion Condition="'$(StabilizePackageVersion)' != 'true' or '$(PackageVersionStamp)' != ''">true</IncludePreReleaseLabelInPackageVersion>
<IncludeBuildNumberInPackageVersion Condition="'$(StabilizePackageVersion)' == 'true'">false</IncludeBuildNumberInPackageVersion>
<IncludeBuildNumberInPackageVersion Condition="'$(StabilizePackageVersion)' != 'true'">true</IncludeBuildNumberInPackageVersion>
diff --git a/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json b/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json
index 62b8ce3da2..032c3fd655 100644
--- a/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json
+++ b/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json
@@ -3,6 +3,27 @@
{
"environment": {},
"enabled": true,
+ "continueOnError": true,
+ "displayName": "run begin.sh",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "10f1f9a1-74b0-47ab-87bf-e3c9c68e8b0d",
+ "versionSpec": "0.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "type": "InlineScript",
+ "scriptPath": "",
+ "args": "",
+ "cwd": "",
+ "failOnStandardError": "false",
+ "script": "if [ -f \"$AGENTTOOLSPATH/begin.sh\" ]; then echo \"$AGENTTOOLSPATH/begin.sh script found. Executing...\"; $AGENTTOOLSPATH/begin.sh ; else echo \"$AGENTTOOLSPATH/begin.sh script does not exist. Moving on.\" ; fi"
+ }
+ },
+ {
+ "environment": {},
+ "enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Change permissions to agent folder for cleanup steps",
@@ -331,6 +352,27 @@
"workingFolder": "",
"failOnStandardError": "false"
}
+ },
+ {
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "displayName": "run end.sh",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "10f1f9a1-74b0-47ab-87bf-e3c9c68e8b0d",
+ "versionSpec": "0.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "type": "InlineScript",
+ "scriptPath": "",
+ "args": "",
+ "cwd": "",
+ "failOnStandardError": "false",
+ "script": "if [ -f \"$AGENTTOOLSPATH/end.sh\" ]; then echo \"$AGENTTOOLSPATH/end.sh script found. Executing...\"; $AGENTTOOLSPATH/end.sh ; else echo \"$AGENTTOOLSPATH/end.sh script does not exist. Moving on.\" ; fi"
+ }
}
],
"options": [
@@ -371,7 +413,8 @@
"value": "arm"
},
"PB_AssetRootUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
},
"PB_BuildArguments": {
"value": "-BuildArch=$(PB_Architecture)"
@@ -423,7 +466,12 @@
"value": "$(Build.BuildNumber)"
},
"PB_PackageVersionPropsUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
+ },
+ "PB_RestoreSource": {
+ "value": "",
+ "isSecret": true
},
"PB_SyncArguments": {
"value": "-p -- /p:ArchGroup=$(PB_Architecture)",
@@ -532,4 +580,4 @@
"revision": 418099111,
"visibility": "organization"
}
-} \ No newline at end of file
+}
diff --git a/buildpipeline/DotNet-CoreFx-Trusted-Linux.json b/buildpipeline/DotNet-CoreFx-Trusted-Linux.json
index e9e8680c55..f3ae7e29f0 100644
--- a/buildpipeline/DotNet-CoreFx-Trusted-Linux.json
+++ b/buildpipeline/DotNet-CoreFx-Trusted-Linux.json
@@ -3,6 +3,27 @@
{
"environment": {},
"enabled": true,
+ "continueOnError": true,
+ "displayName": "run begin.sh",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "10f1f9a1-74b0-47ab-87bf-e3c9c68e8b0d",
+ "versionSpec": "0.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "type": "InlineScript",
+ "scriptPath": "",
+ "args": "",
+ "cwd": "",
+ "failOnStandardError": "false",
+ "script": "if [ -f \"$AGENTTOOLSPATH/begin.sh\" ]; then echo \"$AGENTTOOLSPATH/begin.sh script found. Executing...\"; $AGENTTOOLSPATH/begin.sh ; else echo \"$AGENTTOOLSPATH/begin.sh script does not exist. Moving on.\" ; fi"
+ }
+ },
+ {
+ "environment": {},
+ "enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Change permissions to agent folder for cleanup steps",
@@ -331,6 +352,27 @@
"workingFolder": "",
"failOnStandardError": "false"
}
+ },
+ {
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "displayName": "run end.sh",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "10f1f9a1-74b0-47ab-87bf-e3c9c68e8b0d",
+ "versionSpec": "0.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "type": "InlineScript",
+ "scriptPath": "",
+ "args": "",
+ "cwd": "",
+ "failOnStandardError": "false",
+ "script": "if [ -f \"$AGENTTOOLSPATH/end.sh\" ]; then echo \"$AGENTTOOLSPATH/end.sh script found. Executing...\"; $AGENTTOOLSPATH/end.sh ; else echo \"$AGENTTOOLSPATH/end.sh script does not exist. Moving on.\" ; fi"
+ }
}
],
"options": [
@@ -370,7 +412,12 @@
"allowOverride": true
},
"PB_AssetRootUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
+ },
+ "PB_RestoreSource": {
+ "value": "",
+ "isSecret": true
},
"PB_BuildArguments": {
"value": "-buildArch=x64 -Release -stripSymbols",
@@ -427,7 +474,8 @@
"allowOverride": true
},
"PB_PackageVersionPropsUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
},
"PB_SkipTests": {
"value": "false",
@@ -540,4 +588,4 @@
"revision": 418099111,
"visibility": "organization"
}
-} \ No newline at end of file
+}
diff --git a/buildpipeline/DotNet-CoreFx-Trusted-OSX.json b/buildpipeline/DotNet-CoreFx-Trusted-OSX.json
index a75b4335dd..2c221dc98d 100644
--- a/buildpipeline/DotNet-CoreFx-Trusted-OSX.json
+++ b/buildpipeline/DotNet-CoreFx-Trusted-OSX.json
@@ -3,6 +3,27 @@
{
"environment": {},
"enabled": true,
+ "continueOnError": true,
+ "displayName": "run begin.sh",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "10f1f9a1-74b0-47ab-87bf-e3c9c68e8b0d",
+ "versionSpec": "0.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "type": "InlineScript",
+ "scriptPath": "",
+ "args": "",
+ "cwd": "",
+ "failOnStandardError": "false",
+ "script": "if [ -f \"$AGENTTOOLSPATH/begin.sh\" ]; then echo \"$AGENTTOOLSPATH/begin.sh script found. Executing...\"; $AGENTTOOLSPATH/begin.sh ; else echo \"$AGENTTOOLSPATH/begin.sh script does not exist. Moving on.\" ; fi"
+ }
+ },
+ {
+ "environment": {},
+ "enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Delete files from $(Agent.BuildDirectory)/s",
@@ -79,7 +100,9 @@
}
},
{
- "environment": {},
+ "environment": {
+ "PACKAGEVERSIONPROPSURL": "$(PB_PackageVersionPropsUrl)"
+ },
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
@@ -245,6 +268,27 @@
"Parallel": "false",
"ParallelCount": "8"
}
+ },
+ {
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "displayName": "run end.sh",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "10f1f9a1-74b0-47ab-87bf-e3c9c68e8b0d",
+ "versionSpec": "0.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "type": "InlineScript",
+ "scriptPath": "",
+ "args": "",
+ "cwd": "",
+ "failOnStandardError": "false",
+ "script": "if [ -f \"$AGENTTOOLSPATH/end.sh\" ]; then echo \"$AGENTTOOLSPATH/end.sh script found. Executing...\"; $AGENTTOOLSPATH/end.sh ; else echo \"$AGENTTOOLSPATH/end.sh script does not exist. Moving on.\" ; fi"
+ }
}
],
"options": [
@@ -351,13 +395,16 @@
"allowOverride": true
},
"PB_PackageVersionPropsUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
},
- "PACKAGEVERSIONPROPSURL": {
- "value": "$(PB_PackageVersionPropsUrl)"
+ "PB_RestoreSource": {
+ "value": "",
+ "isSecret": true
},
"PB_AssetRootUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
}
},
"demands": [
diff --git a/buildpipeline/DotNet-CoreFx-Trusted-Windows-NoTest.json b/buildpipeline/DotNet-CoreFx-Trusted-Windows-NoTest.json
index f58c2e92da..3e740ace10 100644
--- a/buildpipeline/DotNet-CoreFx-Trusted-Windows-NoTest.json
+++ b/buildpipeline/DotNet-CoreFx-Trusted-Windows-NoTest.json
@@ -4,10 +4,9 @@
"environment": {},
"enabled": true,
"continueOnError": true,
- "alwaysRun": false,
- "displayName": "Run AgentTools/Begin.ps1",
+ "displayName": "run begin.ps1",
"timeoutInMinutes": 0,
- "condition": "succeededOrFailed()",
+ "alwaysRun": true,
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "2.*",
@@ -17,7 +16,7 @@
"targetType": "inline",
"filePath": "",
"arguments": "",
- "script": "if (Test-Path \"$(AgentToolsPath)\\Begin.ps1\") {\n \"Begin.ps1 script found. Executing...\"\n cd $(AgentToolsPath)\n & $(AgentToolsPath)\\Begin.ps1\n} else {\n \"Begin.ps1 script does not exist. Moving on...\"\n}",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\begin.ps1\") {\n \"$Env:AgentToolsPath\\begin.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\begin.ps1\n} else {\n \"$Env:AgentToolsPath\\begin.ps1 script does not exist. Moving on...\"\n}",
"errorActionPreference": "continue",
"failOnStderr": "false",
"ignoreLASTEXITCODE": "true",
@@ -129,7 +128,9 @@
}
},
{
- "environment": {},
+ "environment": {
+ "PACKAGEVERSIONPROPSURL": "$(PB_PackageVersionPropsUrl)"
+ },
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
@@ -296,9 +297,8 @@
"enabled": true,
"continueOnError": true,
"alwaysRun": true,
- "displayName": "Run AgentTools/End.ps1",
+ "displayName": "run end.ps1",
"timeoutInMinutes": 0,
- "condition": "succeededOrFailed()",
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "2.*",
@@ -308,7 +308,7 @@
"targetType": "inline",
"filePath": "",
"arguments": "",
- "script": "if (Test-Path \"$(AgentToolsPath)\\End.ps1\") {\n \"End.ps1 script found. Executing...\"\n cd $(AgentToolsPath)\n & $(AgentToolsPath)\\End.ps1\n} else {\n \"End.ps1 script does not exist. Moving on...\"\n}",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\end.ps1\") {\n \"$Env:AgentToolsPath\\end.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\end.ps1\n} else {\n \"$Env:AgentToolsPath\\end.ps1 script does not exist. Moving on...\"\n}",
"errorActionPreference": "continue",
"failOnStderr": "false",
"ignoreLASTEXITCODE": "true",
@@ -446,13 +446,16 @@
"allowOverride": true
},
"PB_PackageVersionPropsUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
},
- "PACKAGEVERSIONPROPSURL": {
- "value": "$(PB_PackageVersionPropsUrl)"
+ "PB_RestoreSource": {
+ "value": "",
+ "isSecret": true
},
"PB_AssetRootUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
},
"PB_UseEsrpSigning": {
"value": "false",
diff --git a/buildpipeline/DotNet-CoreFx-Trusted-Windows.json b/buildpipeline/DotNet-CoreFx-Trusted-Windows.json
index c74e9234f7..93f4d0e574 100644
--- a/buildpipeline/DotNet-CoreFx-Trusted-Windows.json
+++ b/buildpipeline/DotNet-CoreFx-Trusted-Windows.json
@@ -4,10 +4,9 @@
"environment": {},
"enabled": true,
"continueOnError": true,
- "alwaysRun": false,
- "displayName": "Run AgentTools/Begin.ps1",
+ "displayName": "run begin.ps1",
"timeoutInMinutes": 0,
- "condition": "succeededOrFailed()",
+ "alwaysRun": true,
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "2.*",
@@ -17,7 +16,7 @@
"targetType": "inline",
"filePath": "",
"arguments": "",
- "script": "if (Test-Path \"$(AgentToolsPath)\\Begin.ps1\") {\n \"Begin.ps1 script found. Executing...\"\n cd $(AgentToolsPath)\n & $(AgentToolsPath)\\Begin.ps1\n} else {\n \"Begin.ps1 script does not exist. Moving on...\"\n}",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\begin.ps1\") {\n \"$Env:AgentToolsPath\\begin.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\begin.ps1\n} else {\n \"$Env:AgentToolsPath\\begin.ps1 script does not exist. Moving on...\"\n}",
"errorActionPreference": "continue",
"failOnStderr": "false",
"ignoreLASTEXITCODE": "true",
@@ -129,7 +128,9 @@
}
},
{
- "environment": {},
+ "environment": {
+ "PACKAGEVERSIONPROPSURL": "$(PB_PackageVersionPropsUrl)"
+ },
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
@@ -347,9 +348,8 @@
"enabled": true,
"continueOnError": true,
"alwaysRun": true,
- "displayName": "Run AgentTools/End.ps1",
+ "displayName": "run end.ps1",
"timeoutInMinutes": 0,
- "condition": "succeededOrFailed()",
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "2.*",
@@ -359,7 +359,7 @@
"targetType": "inline",
"filePath": "",
"arguments": "",
- "script": "if (Test-Path \"$(AgentToolsPath)\\End.ps1\") {\n \"End.ps1 script found. Executing...\"\n cd $(AgentToolsPath)\n & $(AgentToolsPath)\\End.ps1\n} else {\n \"End.ps1 script does not exist. Moving on...\"\n}",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\end.ps1\") {\n \"$Env:AgentToolsPath\\end.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\end.ps1\n} else {\n \"$Env:AgentToolsPath\\end.ps1 script does not exist. Moving on...\"\n}",
"errorActionPreference": "continue",
"failOnStderr": "false",
"ignoreLASTEXITCODE": "true",
@@ -523,13 +523,16 @@
"allowOverride": true
},
"PB_PackageVersionPropsUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
},
- "PACKAGEVERSIONPROPSURL": {
- "value": "$(PB_PackageVersionPropsUrl)"
+ "PB_RestoreSource": {
+ "value": "",
+ "isSecret": true
},
"PB_AssetRootUrl": {
- "value": ""
+ "value": "",
+ "isSecret": true
},
"PB_UseEsrpSigning": {
"value": "false",
diff --git a/buildpipeline/DotNet-Trusted-Publish-Symbols.json b/buildpipeline/DotNet-Trusted-Publish-Symbols.json
index d3ce64e7ac..06dbfcfbfa 100644
--- a/buildpipeline/DotNet-Trusted-Publish-Symbols.json
+++ b/buildpipeline/DotNet-Trusted-Publish-Symbols.json
@@ -1,6 +1,29 @@
{
"build": [
{
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "displayName": "run begin.ps1",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
+ "versionSpec": "2.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "targetType": "inline",
+ "filePath": "",
+ "arguments": "",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\begin.ps1\") {\n \"$Env:AgentToolsPath\\begin.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\begin.ps1\n} else {\n \"$Env:AgentToolsPath\\begin.ps1 script does not exist. Moving on...\"\n}",
+ "errorActionPreference": "continue",
+ "failOnStderr": "false",
+ "ignoreLASTEXITCODE": "true",
+ "workingDirectory": ""
+ }
+ },
+ {
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
@@ -119,6 +142,29 @@
"failOnStandardError": "false"
}
},
+ {
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "alwaysRun": true,
+ "displayName": "run end.ps1",
+ "timeoutInMinutes": 0,
+ "task": {
+ "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
+ "versionSpec": "2.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "targetType": "inline",
+ "filePath": "",
+ "arguments": "",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\end.ps1\") {\n \"$Env:AgentToolsPath\\end.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\end.ps1\n} else {\n \"$Env:AgentToolsPath\\end.ps1 script does not exist. Moving on...\"\n}",
+ "errorActionPreference": "continue",
+ "failOnStderr": "false",
+ "ignoreLASTEXITCODE": "true",
+ "workingDirectory": ""
+ }
+ }
],
"options": [
{
@@ -254,7 +300,7 @@
},
"PB_SymbolExpirationInDays": {
"value": "30"
- },
+ }
},
"retentionRules": [
{
diff --git a/buildpipeline/DotNet-Trusted-Publish.json b/buildpipeline/DotNet-Trusted-Publish.json
index 4409689455..8facc2013a 100644
--- a/buildpipeline/DotNet-Trusted-Publish.json
+++ b/buildpipeline/DotNet-Trusted-Publish.json
@@ -3,6 +3,29 @@
{
"environment": {},
"enabled": true,
+ "continueOnError": true,
+ "displayName": "run begin.ps1",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
+ "versionSpec": "2.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "targetType": "inline",
+ "filePath": "",
+ "arguments": "",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\begin.ps1\") {\n \"$Env:AgentToolsPath\\begin.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\begin.ps1\n} else {\n \"$Env:AgentToolsPath\\begin.ps1 script does not exist. Moving on...\"\n}",
+ "errorActionPreference": "continue",
+ "failOnStderr": "false",
+ "ignoreLASTEXITCODE": "true",
+ "workingDirectory": ""
+ }
+ },
+ {
+ "environment": {},
+ "enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Install Signing Plugin",
@@ -267,6 +290,29 @@
"definitionType": "task"
},
"inputs": {}
+ },
+ {
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "alwaysRun": true,
+ "displayName": "run end.ps1",
+ "timeoutInMinutes": 0,
+ "task": {
+ "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
+ "versionSpec": "2.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "targetType": "inline",
+ "filePath": "",
+ "arguments": "",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\end.ps1\") {\n \"$Env:AgentToolsPath\\end.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\end.ps1\n} else {\n \"$Env:AgentToolsPath\\end.ps1 script does not exist. Moving on...\"\n}",
+ "errorActionPreference": "continue",
+ "failOnStderr": "false",
+ "ignoreLASTEXITCODE": "true",
+ "workingDirectory": ""
+ }
}
],
"options": [
diff --git a/buildpipeline/DotNet-Trusted-Tests-Publish.json b/buildpipeline/DotNet-Trusted-Tests-Publish.json
index b794ec6ab2..7b6d50b462 100644
--- a/buildpipeline/DotNet-Trusted-Tests-Publish.json
+++ b/buildpipeline/DotNet-Trusted-Tests-Publish.json
@@ -1,6 +1,29 @@
{
"build": [
{
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "displayName": "run begin.ps1",
+ "timeoutInMinutes": 0,
+ "alwaysRun": true,
+ "task": {
+ "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
+ "versionSpec": "2.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "targetType": "inline",
+ "filePath": "",
+ "arguments": "",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\begin.ps1\") {\n \"$Env:AgentToolsPath\\begin.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\begin.ps1\n} else {\n \"$Env:AgentToolsPath\\begin.ps1 script does not exist. Moving on...\"\n}",
+ "errorActionPreference": "continue",
+ "failOnStderr": "false",
+ "ignoreLASTEXITCODE": "true",
+ "workingDirectory": ""
+ }
+ },
+ {
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
@@ -113,6 +136,29 @@
"detailedLog": "false",
"usePat": "false"
}
+ },
+ {
+ "environment": {},
+ "enabled": true,
+ "continueOnError": true,
+ "alwaysRun": true,
+ "displayName": "run end.ps1",
+ "timeoutInMinutes": 0,
+ "task": {
+ "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
+ "versionSpec": "2.*",
+ "definitionType": "task"
+ },
+ "inputs": {
+ "targetType": "inline",
+ "filePath": "",
+ "arguments": "",
+ "script": "if (Test-Path \"$Env:AgentToolsPath\\end.ps1\") {\n \"$Env:AgentToolsPath\\end.ps1 script found. Executing...\"\n & $Env:AgentToolsPath\\end.ps1\n} else {\n \"$Env:AgentToolsPath\\end.ps1 script does not exist. Moving on...\"\n}",
+ "errorActionPreference": "continue",
+ "failOnStderr": "false",
+ "ignoreLASTEXITCODE": "true",
+ "workingDirectory": ""
+ }
}
],
"options": [
@@ -261,4 +307,4 @@
"state": "wellFormed",
"revision": 418097423
}
-} \ No newline at end of file
+}
diff --git a/buildpipeline/alpine.3.6.groovy b/buildpipeline/linux-musl.groovy
index 08ed7cb4af..7f5b41103f 100644
--- a/buildpipeline/alpine.3.6.groovy
+++ b/buildpipeline/linux-musl.groovy
@@ -17,13 +17,13 @@ simpleDockerNode('microsoft/dotnet-buildtools-prereqs:alpine-3.6-3148f11-2017111
}
stage ('Generate version assets') {
// Generate the version assets. Do we need to even do this for non-official builds?
- sh "./build-managed.sh -runtimeos=alpine.3.6 -- /t:GenerateVersionSourceFile /p:GenerateVersionSourceFile=true /p:PortableBuild=false"
+ sh "./build-managed.sh -runtimeos=linux-musl -- /t:GenerateVersionSourceFile /p:GenerateVersionSourceFile=true /p:PortableBuild=false"
}
stage ('Sync') {
- sh "./sync.sh -p -runtimeos=alpine.3.6 -- /p:ArchGroup=x64 /p:PortableBuild=false"
+ sh "./sync.sh -p -runtimeos=linux-musl -- /p:ArchGroup=x64 /p:PortableBuild=false"
}
stage ('Build Product') {
- sh "./build.sh -buildArch=x64 -runtimeos=alpine.3.6 -${params.CGroup} -- /p:PortableBuild=false"
+ sh "./build.sh -buildArch=x64 -runtimeos=linux-musl -${params.CGroup} -- /p:PortableBuild=false"
}
stage ('Build Tests') {
def additionalArgs = ''
diff --git a/buildpipeline/pipeline.json b/buildpipeline/pipeline.json
index f415f7d086..edbda97fd9 100644
--- a/buildpipeline/pipeline.json
+++ b/buildpipeline/pipeline.json
@@ -52,22 +52,6 @@
"Name": "DotNet-CoreFx-Trusted-Linux",
"Parameters": {
"PB_DockerTag": "alpine-3.6-3148f11-20171119021156",
- "PB_BuildArguments": "-buildArch=x64 -$(PB_ConfigurationGroup) -stripSymbols -RuntimeOS=alpine.3.6 -- /p:PortableBuild=false /p:StabilizePackageVersion=$(PB_IsStable) /p:PackageVersionStamp=$(PB_VersionStamp)",
- "PB_BuildTestsArguments": "-buildArch=x64 -$(PB_ConfigurationGroup) -SkipTests -Outerloop -RuntimeOS=alpine.3.6 -- /p:ArchiveTests=true /p:EnableDumpling=true /p:PortableBuild=false",
- "PB_SyncArguments": "-p -BuildTests=false -RuntimeOS=alpine.3.6 -- /p:ArchGroup=x64 /p:PortableBuild=false /p:DotNetRestoreSources=$(PB_RestoreSource) /p:DotNetAssetRootUrl=$(PB_AssetRootUrl)",
- "PB_TargetQueue": "Alpine.36.Amd64",
- "PB_CreateHelixArguments": "/p:ArchGroup=x64 /p:ConfigurationGroup=$(PB_ConfigurationGroup) /p:TestProduct=corefx /p:TimeoutInSeconds=1200 /p:TargetOS=Linux"
- },
- "ReportingParameters": {
- "OperatingSystem": "Alpine3.6",
- "Platform": "x64",
- "Type": "build/product/"
- }
- },
- {
- "Name": "DotNet-CoreFx-Trusted-Linux",
- "Parameters": {
- "PB_DockerTag": "alpine-3.6-3148f11-20171119021156",
"PB_BuildArguments": "-buildArch=x64 -$(PB_ConfigurationGroup) -stripSymbols -RuntimeOS=linux-musl -- /p:PortableBuild=false /p:StabilizePackageVersion=$(PB_IsStable) /p:PackageVersionStamp=$(PB_VersionStamp)",
"PB_BuildTestsArguments": "-buildArch=x64 -$(PB_ConfigurationGroup) -SkipTests -Outerloop -RuntimeOS=linux-musl -- /p:ArchiveTests=true /p:EnableDumpling=true /p:PortableBuild=false",
"PB_SyncArguments": "-p -BuildTests=false -RuntimeOS=linux-musl -- /p:ArchGroup=x64 /p:PortableBuild=false /p:DotNetRestoreSources=$(PB_RestoreSource) /p:DotNetAssetRootUrl=$(PB_AssetRootUrl)",
diff --git a/buildpipeline/pipelinejobs.groovy b/buildpipeline/pipelinejobs.groovy
index b5b174a2c8..9173030414 100644
--- a/buildpipeline/pipelinejobs.groovy
+++ b/buildpipeline/pipelinejobs.groovy
@@ -17,7 +17,7 @@ def branch = GithubBranchName
def linPipeline = Pipeline.createPipelineForGithub(this, project, branch, 'buildpipeline/linux.groovy')
def linArm64Pipeline = Pipeline.createPipelineForGithub(this, project, branch, 'buildpipeline/linux.arm64.groovy')
def centos6Pipeline = Pipeline.createPipelineForGithub(this, project, branch, 'buildpipeline/centos.6.groovy')
-def alpine36Pipeline = Pipeline.createPipelineForGithub(this, project, branch, 'buildpipeline/alpine.3.6.groovy')
+def linmuslPipeline = Pipeline.createPipelineForGithub(this, project, branch, 'buildpipeline/linux-musl.groovy')
def osxPipeline = Pipeline.createPipelineForGithub(this, project, branch, 'buildpipeline/osx.groovy')
def winPipeline = Pipeline.createPipelineForGithub(this, project, branch, 'buildpipeline/windows.groovy')
@@ -25,7 +25,7 @@ def configurations = [
['TGroup':"netcoreapp", 'Pipeline':linPipeline, 'Name':'Linux' ,'ForPR':"Release-x64", 'Arch':['x64']],
['TGroup':"netcoreapp", 'Pipeline':linArm64Pipeline, 'Name':'Linux' ,'ForPR':"Release-arm64", 'Arch':['arm64']],
['TGroup':"netcoreapp", 'Pipeline':centos6Pipeline, 'Name':'CentOS.6' ,'ForPR':"", 'Arch':['x64']],
- ['TGroup':"netcoreapp", 'Pipeline':alpine36Pipeline, 'Name':'Alpine.3.6' ,'ForPR':"Debug-x64", 'Arch':['x64']],
+ ['TGroup':"netcoreapp", 'Pipeline':linmuslPipeline, 'Name':'Linux-musl' ,'ForPR':"Debug-x64", 'Arch':['x64']],
['TGroup':"netcoreapp", 'Pipeline':osxPipeline, 'Name':'OSX', 'ForPR':"Debug-x64", 'Arch':['x64']],
['TGroup':"netcoreapp", 'Pipeline':winPipeline, 'Name':'Windows' , 'ForPR':"Debug-x64|Release-x86"],
['TGroup':"netfx", 'Pipeline':winPipeline, 'Name':'NETFX', 'ForPR':"Release-x86"],
diff --git a/dependencies.props b/dependencies.props
index 908c7dd150..ce5433e708 100644
--- a/dependencies.props
+++ b/dependencies.props
@@ -9,15 +9,15 @@
These ref versions are pulled from https://github.com/dotnet/versions.
-->
<PropertyGroup>
- <CoreFxCurrentRef>eff554f39ee29c9f2b470bf7755b83ceaaf2b1a1</CoreFxCurrentRef>
- <CoreClrCurrentRef>eff554f39ee29c9f2b470bf7755b83ceaaf2b1a1</CoreClrCurrentRef>
- <CoreSetupCurrentRef>eff554f39ee29c9f2b470bf7755b83ceaaf2b1a1</CoreSetupCurrentRef>
+ <CoreFxCurrentRef>88565452637e4312f259161d5006ef24870858c7</CoreFxCurrentRef>
+ <CoreClrCurrentRef>88565452637e4312f259161d5006ef24870858c7</CoreClrCurrentRef>
+ <CoreSetupCurrentRef>88565452637e4312f259161d5006ef24870858c7</CoreSetupCurrentRef>
<ExternalCurrentRef>96dc7805f5df4a70a55783964ce69dcd91bfca80</ExternalCurrentRef>
<ProjectNTfsCurrentRef>ccd922b62227c43ed2dac6bcb737321dd2b07be0</ProjectNTfsCurrentRef>
<ProjectNTfsTestILCCurrentRef>ccd922b62227c43ed2dac6bcb737321dd2b07be0</ProjectNTfsTestILCCurrentRef>
<SniCurrentRef>8bd1ec5fac9f0eec34ff6b34b1d878b4359e02dd</SniCurrentRef>
<StandardCurrentRef>eff554f39ee29c9f2b470bf7755b83ceaaf2b1a1</StandardCurrentRef>
- <BuildToolsCurrentRef>eff554f39ee29c9f2b470bf7755b83ceaaf2b1a1</BuildToolsCurrentRef>
+ <BuildToolsCurrentRef>923fc4e4aade5e96f0ebdbd76edfa36dd0a2985c</BuildToolsCurrentRef>
</PropertyGroup>
<!-- Product dependency versions. -->
@@ -31,15 +31,15 @@
<!-- Tests/infrastructure dependency versions. -->
<PropertyGroup>
- <CoreFxExpectedPrerelease>rc1-26419-03</CoreFxExpectedPrerelease>
- <MicrosoftNETCorePlatformsPackageVersion>2.1.0-rc1-26419-03</MicrosoftNETCorePlatformsPackageVersion>
- <MicrosoftNETCoreRuntimeCoreCLRPackageVersion>2.1.0-rc1-26419-03</MicrosoftNETCoreRuntimeCoreCLRPackageVersion>
+ <CoreFxExpectedPrerelease>rtm-26508-03</CoreFxExpectedPrerelease>
+ <MicrosoftNETCorePlatformsPackageVersion>2.1.0-rtm-26508-03</MicrosoftNETCorePlatformsPackageVersion>
+ <MicrosoftNETCoreRuntimeCoreCLRPackageVersion>2.1.0-rtm-26508-04</MicrosoftNETCoreRuntimeCoreCLRPackageVersion>
<ProjectNTfsExpectedPrerelease>beta-26413-00</ProjectNTfsExpectedPrerelease>
<ProjectNTfsTestILCExpectedPrerelease>beta-26413-00</ProjectNTfsTestILCExpectedPrerelease>
<ProjectNTfsTestILCPackageVersion>1.0.0-beta-26413-00</ProjectNTfsTestILCPackageVersion>
- <MicrosoftNETCoreDotNetHostPackageVersion>2.1.0-rc1-26419-02</MicrosoftNETCoreDotNetHostPackageVersion>
- <MicrosoftNETCoreDotNetHostPolicyPackageVersion>2.1.0-rc1-26419-02</MicrosoftNETCoreDotNetHostPolicyPackageVersion>
- <MicrosoftNETCoreAppPackageVersion>2.1.0-rc1-26419-02</MicrosoftNETCoreAppPackageVersion>
+ <MicrosoftNETCoreDotNetHostPackageVersion>2.1.0-rtm-26508-02</MicrosoftNETCoreDotNetHostPackageVersion>
+ <MicrosoftNETCoreDotNetHostPolicyPackageVersion>2.1.0-rtm-26508-02</MicrosoftNETCoreDotNetHostPolicyPackageVersion>
+ <MicrosoftNETCoreAppPackageVersion>2.1.0-rtm-26508-02</MicrosoftNETCoreAppPackageVersion>
<!-- CoreFX-built SNI identity package -->
<RuntimeNativeSystemDataSqlClientSniPackageVersion>4.4.0</RuntimeNativeSystemDataSqlClientSniPackageVersion>
@@ -47,7 +47,7 @@
<AppXRunnerVersion>1.0.3-prerelease-00921-01</AppXRunnerVersion>
<XunitPerfAnalysisPackageVersion>1.0.0-beta-build0018</XunitPerfAnalysisPackageVersion>
<TraceEventPackageVersion>2.0.5</TraceEventPackageVersion>
- <XunitNetcoreExtensionsVersion>2.1.0-rc1-02719-01</XunitNetcoreExtensionsVersion>
+ <XunitNetcoreExtensionsVersion>2.1.0-rc1-02804-05</XunitNetcoreExtensionsVersion>
<!-- Roslyn optimization data package version -->
<OptimizationDataVersion>2.0.0-rc-61101-17</OptimizationDataVersion>
@@ -56,7 +56,7 @@
<!-- Package versions used as toolsets -->
<PropertyGroup>
<FeedTasksPackage>Microsoft.DotNet.Build.Tasks.Feed</FeedTasksPackage>
- <FeedTasksPackageVersion>2.1.0-rc1-02719-01</FeedTasksPackageVersion>
+ <FeedTasksPackageVersion>2.1.0-rc1-02804-05</FeedTasksPackageVersion>
</PropertyGroup>
<!-- Publish symbol build task package -->
diff --git a/external/runtime/runtime.depproj b/external/runtime/runtime.depproj
index 24003d9ab2..120512d435 100644
--- a/external/runtime/runtime.depproj
+++ b/external/runtime/runtime.depproj
@@ -3,8 +3,6 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<NugetRuntimeIdentifier>$(PackageRID)</NugetRuntimeIdentifier>
- <!-- Set to alpine until we get a published linux-musl runtime package -->
- <NugetRuntimeIdentifier Condition="'$(RuntimeOS)' == 'linux-musl'">alpine.3.6-x64</NugetRuntimeIdentifier>
<RidSpecificAssets>true</RidSpecificAssets>
<NoWarn>$(NoWarn);NU1603;NU1605</NoWarn>
</PropertyGroup>
diff --git a/init-tools.sh b/init-tools.sh
index 0f5caaafe2..4d656defe2 100755
--- a/init-tools.sh
+++ b/init-tools.sh
@@ -94,9 +94,7 @@ if [ ! -e "$__DOTNET_PATH" ]; then
if [ -e /etc/os-release ]; then
source /etc/os-release
if [[ $ID == "alpine" ]]; then
- # remove the last version digit
- VERSION_ID=${VERSION_ID%.*}
- __PKG_RID=alpine.$VERSION_ID
+ __PKG_RID=linux-musl
fi
elif [ -e /etc/redhat-release ]; then
redhatRelease=$(</etc/redhat-release)
diff --git a/pkg/Microsoft.Private.CoreFx.NETCoreApp/netcoreapp.rids.props b/pkg/Microsoft.Private.CoreFx.NETCoreApp/netcoreapp.rids.props
index 6299f2de24..06bdbc7696 100644
--- a/pkg/Microsoft.Private.CoreFx.NETCoreApp/netcoreapp.rids.props
+++ b/pkg/Microsoft.Private.CoreFx.NETCoreApp/netcoreapp.rids.props
@@ -10,7 +10,6 @@
<OfficialBuildRID Include="linux-x64" />
<OfficialBuildRID Include="linux-musl-x64" />
<OfficialBuildRID Include="rhel.6-x64" />
- <OfficialBuildRID Include="alpine.3.6-x64" />
<OfficialBuildRID Include="osx-x64" />
<OfficialBuildRID Include="win-arm">
<Platform>arm</Platform>
diff --git a/pkg/dir.props b/pkg/dir.props
index 495fa71341..81edaa295d 100644
--- a/pkg/dir.props
+++ b/pkg/dir.props
@@ -5,8 +5,8 @@
<PropertyGroup>
<!-- Used to determine if we should build some packages only once across multiple official build legs.
For offline builds we still set OfficialBuildId but we need to build all the packages for a single
- leg only, so we also take DotNetBuildOffline into account. -->
- <BuildingAnOfficialBuildLeg Condition="'$(BuildingAnOfficialBuildLeg)' == '' AND '$(OfficialBuildId)' != '' AND '$(DotNetBuildOffline)' != 'true'">true</BuildingAnOfficialBuildLeg>
+ leg only, so we also take DotNetBuildFromSource into account. -->
+ <BuildingAnOfficialBuildLeg Condition="'$(BuildingAnOfficialBuildLeg)' == '' AND '$(OfficialBuildId)' != '' AND '$(DotNetBuildFromSource)' != 'true'">true</BuildingAnOfficialBuildLeg>
</PropertyGroup>
<!-- Packages opt-in to automatic RID-specific builds by placing a *.RID.props next to their project
diff --git a/pkg/test/frameworkSettings/netcoreapp2.1/settings.targets b/pkg/test/frameworkSettings/netcoreapp2.1/settings.targets
index 216e0446db..949dc4c30a 100644
--- a/pkg/test/frameworkSettings/netcoreapp2.1/settings.targets
+++ b/pkg/test/frameworkSettings/netcoreapp2.1/settings.targets
@@ -6,12 +6,4 @@
<!-- use the most recent MS.NETCore.App we have from upstack -->
<RuntimeFrameworkVersion>$(MicrosoftNETCoreAppPackageVersion)</RuntimeFrameworkVersion>
</PropertyGroup>
-
- <ItemGroup>
- <!-- Temporarily suppress checking closure of Memory and Threading.Tasks.Extensions
- These wil fail until we get an updated Microsoft.NETCore.App.
- https://github.com/dotnet/corefx/issues/29249 -->
- <IgnoredReference Include="System.Memory" />
- <IgnoredReference Include="System.Threading.Tasks.Extensions" />
- </ItemGroup>
</Project> \ No newline at end of file
diff --git a/pkg/test/testPackages.proj b/pkg/test/testPackages.proj
index dc29aac152..13f29fad81 100644
--- a/pkg/test/testPackages.proj
+++ b/pkg/test/testPackages.proj
@@ -28,6 +28,9 @@
<!-- no targeting pack was ever shipped for net463 -->
<TargetFrameworksToExclude Include="net463" />
<TargetFrameworksToExclude Include="net47" />
+
+ <!-- exclude netcoreapp2.2 in release branch for 2.1 -->
+ <TargetFrameworksToExclude Include="netcoreapp2.2" />
</ItemGroup>
<PropertyGroup>
diff --git a/src/Common/src/CoreLib/System/Number.Parsing.cs b/src/Common/src/CoreLib/System/Number.Parsing.cs
index 2ae06180d2..936a826c93 100644
--- a/src/Common/src/CoreLib/System/Number.Parsing.cs
+++ b/src/Common/src/CoreLib/System/Number.Parsing.cs
@@ -396,8 +396,12 @@ namespace System
return i;
}
- private static unsafe bool ParseNumber(ref char* str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo numfmt, bool parseDecimal)
+ private static unsafe bool ParseNumber(ref char* str, char* strEnd, NumberStyles options, ref NumberBuffer number, NumberFormatInfo numfmt, bool parseDecimal)
{
+ Debug.Assert(str != null);
+ Debug.Assert(strEnd != null);
+ Debug.Assert(str <= strEnd);
+
const int StateSign = 0x0001;
const int StateParens = 0x0002;
const int StateDigits = 0x0004;
@@ -430,7 +434,7 @@ namespace System
int state = 0;
char* p = str;
- char ch = *p;
+ char ch = p < strEnd ? *p : '\0';
char* next;
while (true)
@@ -439,7 +443,7 @@ namespace System
// "-Kr 1231.47" is legal but "- 1231.47" is not.
if (!IsWhite(ch) || (options & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && numfmt.NumberNegativePattern != 2)))
{
- if ((((options & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || ((next = MatchChars(p, numfmt.NegativeSign)) != null && (number.sign = true))))
+ if ((((options & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, strEnd, numfmt.PositiveSign)) != null || ((next = MatchChars(p, strEnd, numfmt.NegativeSign)) != null && (number.sign = true))))
{
state |= StateSign;
p = next - 1;
@@ -449,7 +453,7 @@ namespace System
state |= StateSign | StateParens;
number.sign = true;
}
- else if (currSymbol != null && (next = MatchChars(p, currSymbol)) != null)
+ else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null)
{
state |= StateCurrency;
currSymbol = null;
@@ -462,7 +466,7 @@ namespace System
break;
}
}
- ch = *++p;
+ ch = ++p < strEnd ? *p : '\0';
}
int digCount = 0;
int digEnd = 0;
@@ -493,12 +497,12 @@ namespace System
number.scale--;
}
}
- else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberDecimalSeparator)) != null))
+ else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, numfmt.NumberDecimalSeparator)) != null))
{
state |= StateDecimal;
p = next - 1;
}
- else if (((options & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, groupSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberGroupSeparator)) != null))
+ else if (((options & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, strEnd, groupSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, strEnd, numfmt.NumberGroupSeparator)) != null))
{
p = next - 1;
}
@@ -506,7 +510,7 @@ namespace System
{
break;
}
- ch = *++p;
+ ch = ++p < strEnd ? *p : '\0';
}
bool negExp = false;
@@ -517,14 +521,14 @@ namespace System
if ((ch == 'E' || ch == 'e') && ((options & NumberStyles.AllowExponent) != 0))
{
char* temp = p;
- ch = *++p;
- if ((next = MatchChars(p, numfmt.positiveSign)) != null)
+ ch = ++p < strEnd ? *p : '\0';
+ if ((next = MatchChars(p, strEnd, numfmt.positiveSign)) != null)
{
- ch = *(p = next);
+ ch = (p = next) < strEnd ? *p : '\0';
}
- else if ((next = MatchChars(p, numfmt.negativeSign)) != null)
+ else if ((next = MatchChars(p, strEnd, numfmt.negativeSign)) != null)
{
- ch = *(p = next);
+ ch = (p = next) < strEnd ? *p : '\0';
negExp = true;
}
if (ch >= '0' && ch <= '9')
@@ -533,13 +537,13 @@ namespace System
do
{
exp = exp * 10 + (ch - '0');
- ch = *++p;
+ ch = ++p < strEnd ? *p : '\0';
if (exp > 1000)
{
exp = 9999;
while (ch >= '0' && ch <= '9')
{
- ch = *++p;
+ ch = ++p < strEnd ? *p : '\0';
}
}
} while (ch >= '0' && ch <= '9');
@@ -552,14 +556,14 @@ namespace System
else
{
p = temp;
- ch = *p;
+ ch = p < strEnd ? *p : '\0';
}
}
while (true)
{
if (!IsWhite(ch) || (options & NumberStyles.AllowTrailingWhite) == 0)
{
- if (((options & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0)) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || (((next = MatchChars(p, numfmt.NegativeSign)) != null) && (number.sign = true))))
+ if (((options & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0)) && ((next = MatchChars(p, strEnd, numfmt.PositiveSign)) != null || (((next = MatchChars(p, strEnd, numfmt.NegativeSign)) != null) && (number.sign = true))))
{
state |= StateSign;
p = next - 1;
@@ -568,7 +572,7 @@ namespace System
{
state &= ~StateParens;
}
- else if (currSymbol != null && (next = MatchChars(p, currSymbol)) != null)
+ else if (currSymbol != null && (next = MatchChars(p, strEnd, currSymbol)) != null)
{
currSymbol = null;
p = next - 1;
@@ -578,7 +582,7 @@ namespace System
break;
}
}
- ch = *++p;
+ ch = ++p < strEnd ? *p : '\0';
}
if ((state & StateParens) == 0)
{
@@ -859,7 +863,7 @@ namespace System
fixed (char* stringPointer = &MemoryMarshal.GetReference(str))
{
char* p = stringPointer;
- if (!ParseNumber(ref p, options, ref number, info, parseDecimal)
+ if (!ParseNumber(ref p, p + str.Length, options, ref number, info, parseDecimal)
|| (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
{
throw new FormatException(SR.Format_InvalidString);
@@ -873,7 +877,7 @@ namespace System
fixed (char* stringPointer = &MemoryMarshal.GetReference(str))
{
char* p = stringPointer;
- if (!ParseNumber(ref p, options, ref number, numfmt, parseDecimal)
+ if (!ParseNumber(ref p, p + str.Length, options, ref number, numfmt, parseDecimal)
|| (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
{
return false;
@@ -897,17 +901,17 @@ namespace System
return true;
}
- private static unsafe char* MatchChars(char* p, string str)
+ private static unsafe char* MatchChars(char* p, char* pEnd, string str)
{
fixed (char* stringPointer = str)
{
- return MatchChars(p, stringPointer);
+ return MatchChars(p, pEnd, stringPointer);
}
}
- private static unsafe char* MatchChars(char* p, char* str)
+ private static unsafe char* MatchChars(char* p, char* pEnd, char* str)
{
- Debug.Assert(p != null && str != null);
+ Debug.Assert(p != null && pEnd != null && p <= pEnd && str != null);
if (*str == '\0')
{
@@ -917,8 +921,13 @@ namespace System
// We only hurt the failure case
// This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 as a
// space character we use 0x20 space character instead to mean the same.
- while (*p == *str || (*str == '\u00a0' && *p == '\u0020'))
+ while (true)
{
+ char cp = p < pEnd ? *p : '\0';
+ if (cp != *str && !(*str == '\u00a0' && cp == '\u0020'))
+ {
+ break;
+ }
p++;
str++;
if (*str == '\0') return p;
diff --git a/src/Common/src/Interop/Unix/System.Native/Interop.WaitId.cs b/src/Common/src/Interop/Unix/System.Native/Interop.WaitId.cs
index a8a0df58a8..3bf9e82e11 100644
--- a/src/Common/src/Interop/Unix/System.Native/Interop.WaitId.cs
+++ b/src/Common/src/Interop/Unix/System.Native/Interop.WaitId.cs
@@ -10,17 +10,14 @@ internal static partial class Interop
internal static partial class Sys
{
/// <summary>
- /// Waits for terminated child processes.
+ /// Returns the pid of a terminated child without reaping it.
/// </summary>
- /// <param name="pid">The PID of a child process. -1 for any child.</param>
- /// <param name="status">The output exit status of the process</param>
- /// <param name="keepWaitable">Tells the OS to leave the child waitable or reap it.</param>
/// <returns>
/// 1) returns the process id of a terminated child process
- /// 2) if no children are waiting, 0 is returned
+ /// 2) if no children are terminated, 0 is returned
/// 3) on error, -1 is returned
/// </returns>
- [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_WaitIdExitedNoHang", SetLastError = true)]
- internal static extern int WaitIdExitedNoHang(int pid, out int exitCode, bool keepWaitable);
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_WaitIdAnyExitedNoHangNoWait", SetLastError = true)]
+ internal static extern int WaitIdAnyExitedNoHangNoWait();
}
}
diff --git a/src/Common/src/Interop/Unix/System.Native/Interop.WaitPid.cs b/src/Common/src/Interop/Unix/System.Native/Interop.WaitPid.cs
new file mode 100644
index 0000000000..8292971d48
--- /dev/null
+++ b/src/Common/src/Interop/Unix/System.Native/Interop.WaitPid.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ /// <summary>
+ /// Reaps a terminated child.
+ /// </summary>
+ /// <returns>
+ /// 1) when a child is reaped, its process id is returned
+ /// 2) if pid is not a child or there are no unwaited-for children, -1 is returned (errno=ECHILD)
+ /// 3) if the child has not yet terminated, 0 is returned
+ /// 4) on error, -1 is returned.
+ /// </returns>
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_WaitPidExitedNoHang", SetLastError = true)]
+ internal static extern int WaitPidExitedNoHang(int pid, out int exitCode);
+ }
+}
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.Print.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.Print.cs
index fbaab0ae80..12199563c8 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.Print.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.Print.cs
@@ -26,6 +26,7 @@ internal static partial class Interop
if (asn1String.IsInvalid)
{
+ Interop.Crypto.ErrClearError();
return null;
}
@@ -54,6 +55,8 @@ internal static partial class Interop
using (SafeBioHandle bio = CreateMemoryBio())
{
+ CheckValidOpenSslHandle(bio);
+
int len = asn1StringPrintEx(bio, asn1String, Asn1StringPrintFlags.ASN1_STRFLGS_UTF8_CONVERT);
if (len < 0)
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.cs
index 1b251fb3a2..962eaa426f 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.ASN1.cs
@@ -20,7 +20,17 @@ internal static partial class Interop
private static extern unsafe int ObjObj2Txt(byte* buf, int buf_len, IntPtr a);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_GetObjectDefinitionByName", CharSet = CharSet.Ansi)]
- internal static extern IntPtr GetObjectDefinitionByName(string friendlyName);
+ private static extern IntPtr CryptoNative_GetObjectDefinitionByName(string friendlyName);
+ internal static IntPtr GetObjectDefinitionByName(string friendlyName)
+ {
+ IntPtr ret = CryptoNative_GetObjectDefinitionByName(friendlyName);
+ if (ret == IntPtr.Zero)
+ {
+ ErrClearError();
+ }
+
+ return ret;
+ }
// Returns shared pointers, should not be tracked as a SafeHandle.
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_ObjNid2Obj")]
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Bignum.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Bignum.cs
index 8896380c7d..6faf7f8915 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Bignum.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Bignum.cs
@@ -29,7 +29,14 @@ internal static partial class Interop
return IntPtr.Zero;
}
- return BigNumFromBinary(bigEndianValue, bigEndianValue.Length);
+ IntPtr ret = BigNumFromBinary(bigEndianValue, bigEndianValue.Length);
+
+ if (ret == IntPtr.Zero)
+ {
+ throw CreateOpenSslCryptographicException();
+ }
+
+ return ret;
}
internal static SafeBignumHandle CreateBignum(byte[] bigEndianValue)
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Crypto.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Crypto.cs
index 13d82c5d09..cfcac7d7dc 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Crypto.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Crypto.cs
@@ -16,7 +16,18 @@ internal static partial class Interop
private delegate int NegativeSizeReadMethod<in THandle>(THandle handle, byte[] buf, int cBuf);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_BioTell")]
- internal static extern int BioTell(SafeBioHandle bio);
+ internal static extern int CryptoNative_BioTell(SafeBioHandle bio);
+
+ internal static int BioTell(SafeBioHandle bio)
+ {
+ int ret = CryptoNative_BioTell(bio);
+ if (ret < 0)
+ {
+ throw CreateOpenSslCryptographicException();
+ }
+
+ return ret;
+ }
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_BioSeek")]
internal static extern int BioSeek(SafeBioHandle bio, int pos);
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Dsa.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Dsa.cs
index bb610f60f3..8d69e89577 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Dsa.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Dsa.cs
@@ -73,8 +73,19 @@ internal static partial class Interop
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DsaSign(SafeDsaHandle dsa, ref byte hash, int hashLength, ref byte refSignature, out int outSignatureLength);
- internal static bool DsaVerify(SafeDsaHandle dsa, ReadOnlySpan<byte> hash, int hashLength, ReadOnlySpan<byte> signature, int signatureLength) =>
- DsaVerify(dsa, ref MemoryMarshal.GetReference(hash), hashLength, ref MemoryMarshal.GetReference(signature), signatureLength);
+ internal static bool DsaVerify(SafeDsaHandle dsa, ReadOnlySpan<byte> hash, ReadOnlySpan<byte> signature)
+ {
+ bool ret = DsaVerify(
+ dsa,
+ ref MemoryMarshal.GetReference(hash),
+ hash.Length,
+ ref MemoryMarshal.GetReference(signature),
+ signature.Length);
+
+ // Error queue already cleaned on the native function.
+
+ return ret;
+ }
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_DsaVerify")]
[return: MarshalAs(UnmanagedType.Bool)]
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.ImportExport.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.ImportExport.cs
index acd32d3cf5..5c079ae1d7 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.ImportExport.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.ImportExport.cs
@@ -33,8 +33,9 @@ internal static partial class Interop
int rc = EcKeyCreateByKeyParameters(out key, oid, qx, qxLength, qy, qyLength, d, dLength);
if (rc == -1)
{
- if (key != null)
- key.Dispose();
+ key?.Dispose();
+ Interop.Crypto.ErrClearError();
+
throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, oid));
}
return key;
@@ -92,6 +93,10 @@ internal static partial class Interop
throw Interop.Crypto.CreateOpenSslCryptographicException();
}
+ // EcKeyCreateByExplicitParameters may have polluted the error queue, but key was good in the end.
+ // Clean up the error queue.
+ Interop.Crypto.ErrClearError();
+
return key;
}
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.cs
index 91c1beab99..17c1232f24 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.cs
@@ -17,8 +17,22 @@ internal static partial class Interop
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EcDsaSign(ref byte dgst, int dlen, ref byte sig, [In, Out] ref int siglen, SafeEcKeyHandle ecKey);
- internal static unsafe int EcDsaVerify(ReadOnlySpan<byte> dgst, int dgst_len, ReadOnlySpan<byte> sigbuf, int sig_len, SafeEcKeyHandle ecKey) =>
- EcDsaVerify(ref MemoryMarshal.GetReference(dgst), dgst_len, ref MemoryMarshal.GetReference(sigbuf), sig_len, ecKey);
+ internal static int EcDsaVerify(ReadOnlySpan<byte> dgst, ReadOnlySpan<byte> sigbuf, SafeEcKeyHandle ecKey)
+ {
+ int ret = EcDsaVerify(
+ ref MemoryMarshal.GetReference(dgst),
+ dgst.Length,
+ ref MemoryMarshal.GetReference(sigbuf),
+ sigbuf.Length,
+ ecKey);
+
+ if (ret < 0)
+ {
+ ErrClearError();
+ }
+
+ return ret;
+ }
/*-
* returns
@@ -31,6 +45,18 @@ internal static partial class Interop
// returns the maximum length of a DER encoded ECDSA signature created with this key.
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcDsaSize")]
- internal static extern int EcDsaSize(SafeEcKeyHandle ecKey);
+ private static extern int CryptoNative_EcDsaSize(SafeEcKeyHandle ecKey);
+
+ internal static int EcDsaSize(SafeEcKeyHandle ecKey)
+ {
+ int ret = CryptoNative_EcDsaSize(ecKey);
+
+ if (ret == 0)
+ {
+ throw CreateOpenSslCryptographicException();
+ }
+
+ return ret;
+ }
}
}
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcKey.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcKey.cs
index d57f04f891..2ac112933f 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcKey.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcKey.cs
@@ -12,7 +12,17 @@ internal static partial class Interop
internal static partial class Crypto
{
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyCreateByOid")]
- internal static extern SafeEcKeyHandle EcKeyCreateByOid(string oid);
+ private static extern SafeEcKeyHandle CryptoNative_EcKeyCreateByOid(string oid);
+ internal static SafeEcKeyHandle EcKeyCreateByOid(string oid)
+ {
+ SafeEcKeyHandle handle = CryptoNative_EcKeyCreateByOid(oid);
+ if (handle == null || handle.IsInvalid)
+ {
+ ErrClearError();
+ }
+
+ return handle;
+ }
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyDestroy")]
internal static extern void EcKeyDestroy(IntPtr a);
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Encode.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Encode.cs
index 747a32998c..27861a263e 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Encode.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Encode.cs
@@ -28,8 +28,18 @@ internal static partial class Interop
byte[] data = new byte[size];
int size2 = encode(handle, data);
- Debug.Assert(size == size2);
+ if (size2 < 1)
+ {
+ Debug.Fail(
+ $"{nameof(OpenSslEncode)}: {nameof(getSize)} succeeded ({size}) and {nameof(encode)} failed ({size2})");
+ // If it ever happens, ensure the error queue gets cleared.
+ // And since it didn't write the data, reporting an exception is good too.
+ throw CreateOpenSslCryptographicException();
+ }
+
+ Debug.Assert(size == size2);
+
return data;
}
}
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs
index 1962389401..1f9530594c 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs
@@ -79,6 +79,7 @@ internal static partial class Interop
if (!Ssl.SetEncryptionPolicy(innerContext, policy))
{
+ Crypto.ErrClearError();
throw new PlatformNotSupportedException(SR.Format(SR.net_ssl_encryptionpolicy_notsupported, policy));
}
@@ -129,7 +130,10 @@ internal static partial class Interop
string punyCode = s_idnMapping.GetAscii(sslAuthenticationOptions.TargetHost);
// Similar to windows behavior, set SNI on openssl by default for client context, ignore errors.
- Ssl.SslSetTlsExtHostName(context, punyCode);
+ if (!Ssl.SslSetTlsExtHostName(context, punyCode))
+ {
+ Crypto.ErrClearError();
+ }
}
if (hasCertificateAndKey)
@@ -210,7 +214,7 @@ internal static partial class Interop
if (sendCount <= 0)
{
// Make sure we clear out the error that is stored in the queue
- Crypto.ErrGetError();
+ Crypto.ErrClearError();
sendBuf = null;
sendCount = 0;
}
@@ -227,6 +231,10 @@ internal static partial class Interop
internal static int Encrypt(SafeSslHandle context, ReadOnlyMemory<byte> input, ref byte[] output, out Ssl.SslErrorCode errorCode)
{
+#if DEBUG
+ ulong assertNoError = Crypto.ErrPeekError();
+ Debug.Assert(assertNoError == 0, "OpenSsl error queue is not empty, run: 'openssl errstr " + assertNoError.ToString("X") + "' for original error.");
+#endif
errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;
int retVal;
@@ -267,7 +275,7 @@ internal static partial class Interop
if (retVal <= 0)
{
// Make sure we clear out the error that is stored in the queue
- Crypto.ErrGetError();
+ Crypto.ErrClearError();
}
}
@@ -276,6 +284,10 @@ internal static partial class Interop
internal static int Decrypt(SafeSslHandle context, byte[] outBuffer, int offset, int count, out Ssl.SslErrorCode errorCode)
{
+#if DEBUG
+ ulong assertNoError = Crypto.ErrPeekError();
+ Debug.Assert(assertNoError == 0, "OpenSsl error queue is not empty, run: 'openssl errstr " + assertNoError.ToString("X") + "' for original error.");
+#endif
errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;
int retVal = BioWrite(context.InputBio, outBuffer, offset, count);
@@ -505,7 +517,9 @@ internal static partial class Interop
internal static SslException CreateSslException(string message)
{
- ulong errorVal = Crypto.ErrGetError();
+ // Capture last error to be consistent with CreateOpenSslCryptographicException
+ ulong errorVal = Crypto.ErrPeekLastError();
+ Crypto.ErrClearError();
string msg = SR.Format(message, Marshal.PtrToStringAnsi(Crypto.ErrReasonErrorString(errorVal)));
return new SslException(msg, (int)errorVal);
}
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
index b6d6b66244..296b9f18b5 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
@@ -96,8 +96,24 @@ internal static partial class Interop
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool RsaSign(int type, ref byte m, int m_len, ref byte sigret, out int siglen, SafeRsaHandle rsa);
- internal static bool RsaVerify(int type, ReadOnlySpan<byte> m, int m_len, ReadOnlySpan<byte> sigbuf, int siglen, SafeRsaHandle rsa) =>
- RsaVerify(type, ref MemoryMarshal.GetReference(m), m_len, ref MemoryMarshal.GetReference(sigbuf), siglen, rsa);
+ internal static bool RsaVerify(int type, ReadOnlySpan<byte> m, ReadOnlySpan<byte> sigbuf, SafeRsaHandle rsa)
+ {
+ bool ret = RsaVerify(
+ type,
+ ref MemoryMarshal.GetReference(m),
+ m.Length,
+ ref MemoryMarshal.GetReference(sigbuf),
+ sigbuf.Length,
+ rsa);
+
+ if (!ret)
+ {
+ ErrClearError();
+ }
+
+ return ret;
+ }
+
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaVerify")]
[return: MarshalAs(UnmanagedType.Bool)]
@@ -171,7 +187,8 @@ internal static partial class Interop
out IntPtr iqmp);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SetRsaParameters")]
- internal static extern void SetRsaParameters(
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static extern bool SetRsaParameters(
SafeRsaHandle key,
byte[] n,
int nLength,
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs
index 59d332038d..8e9db6fb66 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs
@@ -49,7 +49,8 @@ internal static partial class Interop
private static extern IntPtr SslGetVersion(SafeSslHandle ssl);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSetTlsExtHostName")]
- internal static extern int SslSetTlsExtHostName(SafeSslHandle ssl, string host);
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static extern bool SslSetTlsExtHostName(SafeSslHandle ssl, string host);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslGet0AlpnSelected")]
internal static extern void SslGetAlpnSelected(SafeSslHandle ssl, out IntPtr protocol, out int len);
@@ -125,6 +126,7 @@ internal static partial class Interop
internal static extern int SslGetFinished(SafeSslHandle ssl, IntPtr buf, int count);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSessionReused")]
+ [return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SslSessionReused(SafeSslHandle ssl);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslAddExtraChainCert")]
@@ -158,6 +160,7 @@ internal static partial class Interop
Crypto.CheckValidOpenSslHandle(dupCertHandle);
if (!SslAddExtraChainCert(sslContext, dupCertHandle))
{
+ Crypto.ErrClearError();
dupCertHandle.Dispose(); // we still own the safe handle; clean it up
return false;
}
diff --git a/src/Common/src/System/Security/Cryptography/Asn1V2.Serializer.cs b/src/Common/src/System/Security/Cryptography/Asn1V2.Serializer.cs
index c6b2ea69b5..018cc3c5d1 100644
--- a/src/Common/src/System/Security/Cryptography/Asn1V2.Serializer.cs
+++ b/src/Common/src/System/Security/Cryptography/Asn1V2.Serializer.cs
@@ -879,7 +879,7 @@ namespace System.Security.Cryptography.Asn1
try
{
- if (reader.TryCopyBitStringBytes(rented, out _, out int bytesWritten))
+ if (reader.TryCopyBitStringBytes(expectedTag, rented, out _, out int bytesWritten))
{
return new ReadOnlyMemory<byte>(rented.AsSpan(0, bytesWritten).ToArray());
}
@@ -910,7 +910,7 @@ namespace System.Security.Cryptography.Asn1
try
{
- if (reader.TryCopyOctetStringBytes(rented, out int bytesWritten))
+ if (reader.TryCopyOctetStringBytes(expectedTag, rented, out int bytesWritten))
{
return new ReadOnlyMemory<byte>(rented.AsSpan(0, bytesWritten).ToArray());
}
diff --git a/src/Common/src/System/Security/Cryptography/DSAOpenSsl.cs b/src/Common/src/System/Security/Cryptography/DSAOpenSsl.cs
index 35de009005..31bb5f9ec0 100644
--- a/src/Common/src/System/Security/Cryptography/DSAOpenSsl.cs
+++ b/src/Common/src/System/Security/Cryptography/DSAOpenSsl.cs
@@ -282,7 +282,7 @@ namespace System.Security.Cryptography
byte[] openSslFormat = AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature);
- return Interop.Crypto.DsaVerify(key, hash, hash.Length, openSslFormat, openSslFormat.Length);
+ return Interop.Crypto.DsaVerify(key, hash, openSslFormat);
}
private void SetKey(SafeDsaHandle newKey)
diff --git a/src/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs b/src/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs
index fda44274c7..e89992b359 100644
--- a/src/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs
+++ b/src/Common/src/System/Security/Cryptography/ECDsaOpenSsl.cs
@@ -149,7 +149,7 @@ namespace System.Security.Cryptography
byte[] openSslFormat = AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature);
SafeEcKeyHandle key = _key.Value;
- int verifyResult = Interop.Crypto.EcDsaVerify(hash, hash.Length, openSslFormat, openSslFormat.Length, key);
+ int verifyResult = Interop.Crypto.EcDsaVerify(hash, openSslFormat, key);
return verifyResult == 1;
}
diff --git a/src/Common/src/System/Security/Cryptography/ECOpenSsl.ImportExport.cs b/src/Common/src/System/Security/Cryptography/ECOpenSsl.ImportExport.cs
index 050c610a74..0c0616f9c7 100644
--- a/src/Common/src/System/Security/Cryptography/ECOpenSsl.ImportExport.cs
+++ b/src/Common/src/System/Security/Cryptography/ECOpenSsl.ImportExport.cs
@@ -42,6 +42,10 @@ namespace System.Security.Cryptography
throw Interop.Crypto.CreateOpenSslCryptographicException();
}
+ // The Import* methods above may have polluted the error queue even if in the end they succeeded.
+ // Clean up the error queue.
+ Interop.Crypto.ErrClearError();
+
FreeKey();
_key = new Lazy<SafeEcKeyHandle>(key);
return KeySize;
diff --git a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
index e3758e28cb..2fe3666161 100644
--- a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
+++ b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
@@ -355,7 +355,7 @@ namespace System.Security.Cryptography
try
{
- Interop.Crypto.SetRsaParameters(
+ if (!Interop.Crypto.SetRsaParameters(
key,
parameters.Modulus,
parameters.Modulus != null ? parameters.Modulus.Length : 0,
@@ -372,7 +372,10 @@ namespace System.Security.Cryptography
parameters.DQ,
parameters.DQ != null ? parameters.DQ.Length : 0,
parameters.InverseQ,
- parameters.InverseQ != null ? parameters.InverseQ.Length : 0);
+ parameters.InverseQ != null ? parameters.InverseQ.Length : 0))
+ {
+ throw Interop.Crypto.CreateOpenSslCryptographicException();
+ }
imported = true;
}
@@ -694,7 +697,7 @@ namespace System.Security.Cryptography
{
int algorithmNid = GetAlgorithmNid(hashAlgorithm);
SafeRsaHandle rsa = _key.Value;
- return Interop.Crypto.RsaVerify(algorithmNid, hash, hash.Length, signature, signature.Length, rsa);
+ return Interop.Crypto.RsaVerify(algorithmNid, hash, signature, rsa);
}
else if (padding == RSASignaturePadding.Pss)
{
@@ -748,6 +751,7 @@ namespace System.Security.Cryptography
if (nid == Interop.Crypto.NID_undef)
{
+ Interop.Crypto.ErrClearError();
throw new CryptographicException(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmName.Name);
}
diff --git a/src/Microsoft.XmlSerializer.Generator/pkg/build/Microsoft.XmlSerializer.Generator.targets b/src/Microsoft.XmlSerializer.Generator/pkg/build/Microsoft.XmlSerializer.Generator.targets
index d439baaae1..3d581e3d56 100644
--- a/src/Microsoft.XmlSerializer.Generator/pkg/build/Microsoft.XmlSerializer.Generator.targets
+++ b/src/Microsoft.XmlSerializer.Generator/pkg/build/Microsoft.XmlSerializer.Generator.targets
@@ -12,7 +12,7 @@
<Delete Condition="Exists('$(_SerializerPdbIntermediateFolder)') == 'true'" Files="$(_SerializerPdbIntermediateFolder)" ContinueOnError="true"/>
<Delete Condition="Exists('$(_SerializerCsIntermediateFolder)') == 'true'" Files="$(_SerializerCsIntermediateFolder)" ContinueOnError="true"/>
<Message Text="Running Serialization Tool" Importance="normal" />
- <Exec Command="dotnet Microsoft.XmlSerializer.Generator $(IntermediateOutputPath)$(AssemblyName)$(TargetExt) --force --quiet --reference @(Reference)" ContinueOnError="true"/>
+ <Exec Command="dotnet Microsoft.XmlSerializer.Generator &quot;$(IntermediateOutputPath)$(AssemblyName)$(TargetExt)&quot; --force --quiet --reference &quot;@(Reference)&quot;" ContinueOnError="true"/>
<Warning Condition="Exists('$(_SerializerCsIntermediateFolder)') != 'true'" Text="$(_SGenWarningText)" />
<Csc Condition="Exists('$(_SerializerCsIntermediateFolder)') == 'true'" ContinueOnError="true" OutputAssembly="$(_SerializerDllIntermediateFolder)" References="@(ReferencePath);@(IntermediateAssembly)" EmitDebugInformation="$(DebugSymbols)" Sources="$(_SerializerCsIntermediateFolder)" TargetType="Library" ToolExe="$(CscToolExe)" ToolPath="$(CscToolPath)" DisabledWarnings="$(_SerializationAssemblyDisabledWarnings)"/>
<Warning Condition="Exists('$(_SerializerDllIntermediateFolder)') != 'true' And Exists('$(_SerializerCsIntermediateFolder)') == 'true'" Text="$(_SGenWarningText)"/>
@@ -43,7 +43,7 @@
<Delete Files="%(_ReferenceSerializerIntermediateFolder.Identity).cs" ContinueOnError="true"/>
<Delete Files="%(_ReferenceSerializerIntermediateFolder.Identity).pdb" ContinueOnError="true"/>
<Message Text="Running Serialization Tool for Reference Assembly" Importance="normal" />
- <Exec Command="dotnet Microsoft.XmlSerializer.Generator --force --quiet --reference @(Reference) --assembly %(_TargetSerializationAssembly.Identity) --type %(_TargetSerializationAssembly.SerializationTypes) --out $(IntermediateOutputPath)" ContinueOnError="true" />
+ <Exec Command="dotnet Microsoft.XmlSerializer.Generator --force --quiet --reference &quot;@(Reference)&quot; --assembly &quot;%(_TargetSerializationAssembly.Identity)&quot; --type %(_TargetSerializationAssembly.SerializationTypes) --out &quot;$(IntermediateOutputPath)&quot;" ContinueOnError="true" />
<Warning Condition="Exists('$(IntermediateOutputPath)%(_ReferenceSerializationAssemblyName.Identity).cs') != 'true'" Text="SGEN: Fail to generate %(_ReferenceSerializationAssemblyName.Identity)'. Please follow the instructions at https://go.microsoft.com/fwlink/?linkid=858594 and try again." />
<Csc Condition="Exists('$(IntermediateOutputPath)%(_ReferenceSerializationAssemblyName.Identity).cs') == 'true'" ContinueOnError="true" OutputAssembly="$(IntermediateOutputPath)%(_ReferenceSerializationAssemblyName.Identity).dll" References="@(ReferencePath);@(IntermediateAssembly)" EmitDebugInformation="$(DebugSymbols)" Sources="$(IntermediateOutputPath)%(_ReferenceSerializationAssemblyName.Identity).cs" TargetType="Library" ToolExe="$(CscToolExe)" ToolPath="$(CscToolPath)" DisabledWarnings="$(_SerializationAssemblyDisabledWarnings)"/>
<Warning Condition="Exists('$(IntermediateOutputPath)%(_ReferenceSerializationAssemblyName.Identity).dll') != 'true' And Exists('$(IntermediateOutputPath)%(_ReferenceSerializationAssemblyName.Identity).cs') == 'true'" Text="SGEN: Fail to compile %(_ReferenceSerializationAssemblyName.Identity).cs. Please follow the instructions at https://go.microsoft.com/fwlink/?linkid=858594 and try again." />
diff --git a/src/Microsoft.XmlSerializer.Generator/src/Sgen.cs b/src/Microsoft.XmlSerializer.Generator/src/Sgen.cs
index 7e75a55b72..70d8af88d0 100644
--- a/src/Microsoft.XmlSerializer.Generator/src/Sgen.cs
+++ b/src/Microsoft.XmlSerializer.Generator/src/Sgen.cs
@@ -296,6 +296,19 @@ namespace Microsoft.XmlSerializer.Generator
bool gac = assembly.GlobalAssemblyCache;
outputDirectory = outputDirectory == null ? (gac ? Environment.CurrentDirectory : Path.GetDirectoryName(assembly.Location)) : outputDirectory;
+
+ if (!Directory.Exists(outputDirectory))
+ {
+ //We need double quote the path to escpate the space in the path.
+ //However when a path ending with backslash, if followed by double quote, it becomes an escapte sequence
+ //e.g. "obj\Debug\netcoreapp2.0\", it will be converted as obj\Debug\netcoreapp2.0", which is not valid and not exist
+ //We need remove the ending quote for this situation
+ if (!outputDirectory.EndsWith("\"") || !Directory.Exists(outputDirectory.Remove(outputDirectory.Length - 1)))
+ {
+ throw new ArgumentException(SR.Format(SR.ErrDirectoryNotExists, outputDirectory));
+ }
+ }
+
string serializerName = GetXmlSerializerAssemblyName(serializableTypes[0], null);
string codePath = Path.Combine(outputDirectory, serializerName + ".cs");
@@ -310,11 +323,6 @@ namespace Microsoft.XmlSerializer.Generator
throw new InvalidOperationException(SR.Format(SR.ErrDirectoryExists, codePath));
}
- if (!Directory.Exists(outputDirectory))
- {
- throw new ArgumentException(SR.Format(SR.ErrDirectoryNotExists, codePath, outputDirectory));
- }
-
bool success = false;
bool toDeleteFile = true;
diff --git a/src/Native/Unix/Common/pal_config.h.in b/src/Native/Unix/Common/pal_config.h.in
index 6099d2f32c..157cb4bf78 100644
--- a/src/Native/Unix/Common/pal_config.h.in
+++ b/src/Native/Unix/Common/pal_config.h.in
@@ -28,6 +28,7 @@
#cmakedefine01 HAVE_TIOCGWINSZ
#cmakedefine01 HAVE_SCHED_GETAFFINITY
#cmakedefine01 HAVE_SCHED_SETAFFINITY
+#cmakedefine01 HAVE_ARC4RANDOM
#cmakedefine01 KEVENT_HAS_VOID_UDATA
#cmakedefine01 HAVE_FDS_BITS
#cmakedefine01 HAVE_PRIVATE_FDS_BITS
diff --git a/src/Native/Unix/System.Native/pal_process.cpp b/src/Native/Unix/System.Native/pal_process.cpp
index 0d627f4588..1790e76dea 100644
--- a/src/Native/Unix/System.Native/pal_process.cpp
+++ b/src/Native/Unix/System.Native/pal_process.cpp
@@ -450,34 +450,46 @@ extern "C" void SystemNative_SysLog(SysLogPriority priority, const char* message
syslog(static_cast<int>(priority), message, arg1);
}
-extern "C" int32_t SystemNative_WaitIdExitedNoHang(int32_t pid, int32_t* exitCode, int32_t keepWaitable)
+extern "C" int32_t SystemNative_WaitIdAnyExitedNoHangNoWait()
{
- assert(exitCode != nullptr);
-
siginfo_t siginfo;
int32_t result;
- idtype_t idtype = pid == -1 ? P_ALL : P_PID;
- int options = WEXITED | WNOHANG;
- if (keepWaitable != 0)
- {
- options |= WNOWAIT;
- }
- while (CheckInterrupted(result = waitid(idtype, static_cast<id_t>(pid), &siginfo, options)));
- if (idtype == P_ALL && result == -1 && errno == ECHILD)
+ while (CheckInterrupted(result = waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)));
+ if (result == -1 && errno == ECHILD)
{
+ // The calling process has no existing unwaited-for child processes.
result = 0;
}
else if (result == 0 && siginfo.si_signo == SIGCHLD)
{
- if (siginfo.si_code == CLD_EXITED)
+ result = siginfo.si_pid;
+ }
+ return result;
+}
+
+extern "C" int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode)
+{
+ assert(exitCode != nullptr);
+
+ int32_t result;
+ int status;
+ while (CheckInterrupted(result = waitpid(pid, &status, WNOHANG)));
+ if (result > 0)
+ {
+ if (WIFEXITED(status))
+ {
+ // the child terminated normally.
+ *exitCode = WEXITSTATUS(status);
+ }
+ else if (WIFSIGNALED(status))
{
- *exitCode = siginfo.si_status;
+ // child process was terminated by a signal.
+ *exitCode = 128 + WTERMSIG(status);
}
else
{
- *exitCode = 128 + siginfo.si_status;
+ assert(false);
}
- result = siginfo.si_pid;
}
return result;
}
diff --git a/src/Native/Unix/System.Native/pal_process.h b/src/Native/Unix/System.Native/pal_process.h
index 77698b7507..81ee2d0619 100644
--- a/src/Native/Unix/System.Native/pal_process.h
+++ b/src/Native/Unix/System.Native/pal_process.h
@@ -210,13 +210,23 @@ DLLEXPORT int32_t SystemNative_GetSid(int32_t pid);
DLLEXPORT void SystemNative_SysLog(SysLogPriority priority, const char* message, const char* arg1);
/**
- * Waits for terminated child processes.
+ * Returns the pid of a terminated child without reaping it.
*
* 1) returns the process id of a terminated child process
- * 2) if no children are waiting, 0 is returned
+ * 2) if no children are terminated, 0 is returned
* 3) on error, -1 is returned
*/
-DLLEXPORT int32_t SystemNative_WaitIdExitedNoHang(int32_t pid, int32_t* exitCode, int32_t keepWaitable);
+extern "C" int32_t SystemNative_WaitIdAnyExitedNoHangNoWait();
+
+/**
+ * Reaps a terminated child.
+ *
+ * 1) when a child is reaped, its process id is returned
+ * 2) if pid is not a child or there are no unwaited-for children, -1 is returned (errno=ECHILD)
+ * 3) if the child has not yet terminated, 0 is returned
+ * 4) on error, -1 is returned.
+ */
+extern "C" int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode);
/**
* Gets the configurable limit or variable for system path or file descriptor options.
diff --git a/src/Native/Unix/System.Native/pal_random.c b/src/Native/Unix/System.Native/pal_random.c
index dd583c8d9b..dfc81b03e0 100644
--- a/src/Native/Unix/System.Native/pal_random.c
+++ b/src/Native/Unix/System.Native/pal_random.c
@@ -12,8 +12,7 @@
#include <time.h>
#include <errno.h>
-#include "pal_random.h"
-
+#include "pal_config.h"
/*
Generate random bytes. The generated bytes are not cryptographically strong.
@@ -24,6 +23,9 @@ void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* buffer, int3
{
assert(buffer != NULL);
+#if HAVE_ARC4RANDOM
+ arc4random_buf(buffer, (size_t)bufferLength);
+#else
static volatile int rand_des = -1;
long num = 0;
static bool sMissingDevURandom;
@@ -97,4 +99,5 @@ void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* buffer, int3
*(buffer + i) ^= num;
num >>= 8;
}
+#endif // HAS_ARC4RANDOM
}
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp
index 50c53e315a..af9ce59d64 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_dsa.cpp
@@ -99,7 +99,8 @@ extern "C" int32_t CryptoNative_DsaVerify(
{
if (success == -1)
{
- // Clear the queue, as we don't check the error information
+ // Clear the queue, as we don't check the error information.
+ // Managed caller expects the error queue to be cleared in case of error.
ERR_clear_error();
}
return 0;
@@ -141,7 +142,7 @@ extern "C" int32_t CryptoNative_GetDsaParameters(
return 1;
}
-static void SetDsaParameter(BIGNUM** dsaFieldAddress, uint8_t* buffer, int32_t bufferLength)
+static int32_t SetDsaParameter(BIGNUM** dsaFieldAddress, uint8_t* buffer, int32_t bufferLength)
{
assert(dsaFieldAddress != nullptr);
if (dsaFieldAddress)
@@ -149,13 +150,18 @@ static void SetDsaParameter(BIGNUM** dsaFieldAddress, uint8_t* buffer, int32_t b
if (!buffer || !bufferLength)
{
*dsaFieldAddress = nullptr;
+ return 1;
}
else
{
BIGNUM* bigNum = BN_bin2bn(buffer, bufferLength, nullptr);
*dsaFieldAddress = bigNum;
+
+ return bigNum != nullptr;
}
}
+
+ return 0;
}
extern "C" int32_t CryptoNative_DsaKeyCreateByExplicitParameters(
@@ -185,11 +191,10 @@ extern "C" int32_t CryptoNative_DsaKeyCreateByExplicitParameters(
DSA* dsa = *outDsa;
- SetDsaParameter(&dsa->p, p, pLength);
- SetDsaParameter(&dsa->q, q, qLength);
- SetDsaParameter(&dsa->g, g, gLength);
- SetDsaParameter(&dsa->pub_key, y, yLength);
- SetDsaParameter(&dsa->priv_key, x, xLength);
-
- return 1;
+ return
+ SetDsaParameter(&dsa->p, p, pLength) &&
+ SetDsaParameter(&dsa->q, q, qLength) &&
+ SetDsaParameter(&dsa->g, g, gLength) &&
+ SetDsaParameter(&dsa->pub_key, y, yLength) &&
+ SetDsaParameter(&dsa->priv_key, x, xLength);
}
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp
index 7b3f56bed6..9ad896aa72 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.cpp
@@ -215,7 +215,7 @@ extern "C" int32_t CryptoNative_GetRsaParameters(const RSA* rsa,
return 1;
}
-static void SetRsaParameter(BIGNUM** rsaFieldAddress, uint8_t* buffer, int32_t bufferLength)
+static int32_t SetRsaParameter(BIGNUM** rsaFieldAddress, uint8_t* buffer, int32_t bufferLength)
{
assert(rsaFieldAddress != nullptr);
if (rsaFieldAddress)
@@ -223,16 +223,21 @@ static void SetRsaParameter(BIGNUM** rsaFieldAddress, uint8_t* buffer, int32_t b
if (!buffer || !bufferLength)
{
*rsaFieldAddress = nullptr;
+ return 1;
}
else
{
BIGNUM* bigNum = BN_bin2bn(buffer, bufferLength, nullptr);
*rsaFieldAddress = bigNum;
+
+ return bigNum != nullptr;
}
}
+
+ return 0;
}
-extern "C" void CryptoNative_SetRsaParameters(RSA* rsa,
+extern "C" int32_t CryptoNative_SetRsaParameters(RSA* rsa,
uint8_t* n,
int32_t nLength,
uint8_t* e,
@@ -253,15 +258,16 @@ extern "C" void CryptoNative_SetRsaParameters(RSA* rsa,
if (!rsa)
{
assert(false);
- return;
+ return 0;
}
- SetRsaParameter(&rsa->n, n, nLength);
- SetRsaParameter(&rsa->e, e, eLength);
- SetRsaParameter(&rsa->d, d, dLength);
- SetRsaParameter(&rsa->p, p, pLength);
- SetRsaParameter(&rsa->dmp1, dmp1, dmp1Length);
- SetRsaParameter(&rsa->q, q, qLength);
- SetRsaParameter(&rsa->dmq1, dmq1, dmq1Length);
- SetRsaParameter(&rsa->iqmp, iqmp, iqmpLength);
+ return
+ SetRsaParameter(&rsa->n, n, nLength) &&
+ SetRsaParameter(&rsa->e, e, eLength) &&
+ SetRsaParameter(&rsa->d, d, dLength) &&
+ SetRsaParameter(&rsa->p, p, pLength) &&
+ SetRsaParameter(&rsa->dmp1, dmp1, dmp1Length) &&
+ SetRsaParameter(&rsa->q, q, qLength) &&
+ SetRsaParameter(&rsa->dmq1, dmq1, dmq1Length) &&
+ SetRsaParameter(&rsa->iqmp, iqmp, iqmpLength);
}
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
index 162f21ef5c..c4a2737ced 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
@@ -126,7 +126,7 @@ extern "C" int32_t CryptoNative_GetRsaParameters(const RSA* rsa,
/*
Sets all the parameters on the RSA instance.
*/
-extern "C" void CryptoNative_SetRsaParameters(RSA* rsa,
+extern "C" int32_t CryptoNative_SetRsaParameters(RSA* rsa,
uint8_t* n,
int32_t nLength,
uint8_t* e,
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp b/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp
index f0fb128166..40de77cbc4 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.cpp
@@ -102,7 +102,10 @@ extern "C" void CryptoNative_SetProtocolOptions(SSL_CTX* ctx, SslProtocols proto
#endif
SSL_CTX_set_options(ctx, protocolOptions);
- TrySetECDHNamedCurve(ctx);
+ if (TrySetECDHNamedCurve(ctx) == 0)
+ {
+ ERR_clear_error();
+ }
}
extern "C" SSL* CryptoNative_SslCreate(SSL_CTX* ctx)
diff --git a/src/Native/Unix/configure.cmake b/src/Native/Unix/configure.cmake
index 403895bc5a..45cd42af70 100644
--- a/src/Native/Unix/configure.cmake
+++ b/src/Native/Unix/configure.cmake
@@ -1 +1,5 @@
-# Any change in this file needs to be reflected into mono's configure.ac
+#
+# Any change in this file needs to be manually reflected into Mono's configure.ac
+#
+# The last reviewed revision: 6906dbfe66609dd606c84b09462dc1ce1936ef7e
+# \ No newline at end of file
diff --git a/src/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj
index 3aac492354..64c0400823 100644
--- a/src/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj
+++ b/src/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj
@@ -351,6 +351,9 @@
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.WaitId.cs">
<Link>Common\Interop\Unix\Interop.WaitId.cs</Link>
</Compile>
+ <Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.WaitPid.cs">
+ <Link>Common\Interop\Unix\Interop.WaitPid.cs</Link>
+ </Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetsLinux)' == 'true'">
<Compile Include="System\Diagnostics\Process.Linux.cs" />
diff --git a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs
index f9ab4d6475..bb5e79ca69 100644
--- a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs
+++ b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessWaitState.Unix.cs
@@ -527,7 +527,7 @@ namespace System.Diagnostics
// Try to get the state of the child process
int exitCode;
- int waitResult = Interop.Sys.WaitIdExitedNoHang(_processId, out exitCode, keepWaitable: false);
+ int waitResult = Interop.Sys.WaitPidExitedNoHang(_processId, out exitCode);
if (waitResult == _processId)
{
@@ -563,8 +563,7 @@ namespace System.Diagnostics
do
{
// Find a process that terminated without reaping it yet.
- int exitCode;
- pid = Interop.Sys.WaitIdExitedNoHang(-1, out exitCode, keepWaitable: true);
+ pid = Interop.Sys.WaitIdAnyExitedNoHangNoWait();
if (pid > 0)
{
if (s_childProcessWaitStates.TryGetValue(pid, out ProcessWaitState pws))
@@ -638,7 +637,7 @@ namespace System.Diagnostics
do
{
int exitCode;
- pid = Interop.Sys.WaitIdExitedNoHang(-1, out exitCode, keepWaitable: false);
+ pid = Interop.Sys.WaitPidExitedNoHang(-1, out exitCode);
} while (pid > 0);
}
}
diff --git a/src/System.Diagnostics.Process/tests/ProcessTests.Unix.cs b/src/System.Diagnostics.Process/tests/ProcessTests.Unix.cs
index c8a652f268..226aa0e273 100644
--- a/src/System.Diagnostics.Process/tests/ProcessTests.Unix.cs
+++ b/src/System.Diagnostics.Process/tests/ProcessTests.Unix.cs
@@ -387,6 +387,21 @@ namespace System.Diagnostics.Tests
Assert.Throws<Win32Exception>(() => p.Start());
}
+ [Fact]
+ public void TestExitCodeKilledChild()
+ {
+ using (Process p = CreateProcessLong())
+ {
+ p.Start();
+ p.Kill();
+ p.WaitForExit();
+
+ // SIGKILL may change per platform
+ const int SIGKILL = 9; // Linux, macOS, FreeBSD, ...
+ Assert.Equal(128 + SIGKILL, p.ExitCode);
+ }
+ }
+
/// <summary>
/// Tests when running as a normal user and starting a new process as the same user
/// works as expected.
diff --git a/src/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj b/src/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj
index 39130ab370..3e0635d18e 100644
--- a/src/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj
+++ b/src/System.Diagnostics.StackTrace/src/System.Diagnostics.StackTrace.csproj
@@ -35,7 +35,7 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp' or '$(TargetGroup)' == 'uap'">
<Compile Include="System\Diagnostics\StackTraceSymbols.CoreCLR.cs" />
- <ProjectReference Include="..\..\System.Collections\src\System.Collections.csproj" />
+ <ProjectReference Include="..\..\System.Collections.Concurrent\src\System.Collections.Concurrent.csproj" />
<ProjectReference Include="..\..\System.Diagnostics.Debug\src\System.Diagnostics.Debug.csproj" />
<ProjectReference Include="..\..\System.IO\src\System.IO.csproj" />
<ProjectReference Include="..\..\System.IO.FileSystem\src\System.IO.FileSystem.csproj" />
@@ -57,4 +57,4 @@
<Reference Include="mscorlib" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/System.Diagnostics.StackTrace/src/System/Diagnostics/StackTraceSymbols.CoreCLR.cs b/src/System.Diagnostics.StackTrace/src/System/Diagnostics/StackTraceSymbols.CoreCLR.cs
index 3542fdbeaf..29dad032dd 100644
--- a/src/System.Diagnostics.StackTrace/src/System/Diagnostics/StackTraceSymbols.CoreCLR.cs
+++ b/src/System.Diagnostics.StackTrace/src/System/Diagnostics/StackTraceSymbols.CoreCLR.cs
@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Collections.Generic;
+using System.Collections.Concurrent;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@@ -12,14 +12,14 @@ namespace System.Diagnostics
{
internal class StackTraceSymbols : IDisposable
{
- private readonly Dictionary<IntPtr, MetadataReaderProvider> _metadataCache;
+ private readonly ConcurrentDictionary<IntPtr, MetadataReaderProvider> _metadataCache;
/// <summary>
/// Create an instance of this class.
/// </summary>
public StackTraceSymbols()
{
- _metadataCache = new Dictionary<IntPtr, MetadataReaderProvider>();
+ _metadataCache = new ConcurrentDictionary<IntPtr, MetadataReaderProvider>();
}
/// <summary>
@@ -29,7 +29,7 @@ namespace System.Diagnostics
{
foreach (MetadataReaderProvider provider in _metadataCache.Values)
{
- provider.Dispose();
+ provider?.Dispose();
}
_metadataCache.Clear();
@@ -123,20 +123,21 @@ namespace System.Diagnostics
MetadataReaderProvider provider;
if (_metadataCache.TryGetValue(cacheKey, out provider))
{
- return provider.GetMetadataReader();
+ return provider?.GetMetadataReader();
}
provider = (inMemoryPdbAddress != IntPtr.Zero) ?
TryOpenReaderForInMemoryPdb(inMemoryPdbAddress, inMemoryPdbSize) :
TryOpenReaderFromAssemblyFile(assemblyPath, loadedPeAddress, loadedPeSize);
+ // This may fail as another thread might have beaten us to it, but it doesn't matter
+ _metadataCache.TryAdd(cacheKey, provider);
+
if (provider == null)
{
return null;
}
- _metadataCache.Add(cacheKey, provider);
-
// The reader has already been open, so this doesn't throw:
return provider.GetMetadataReader();
}
diff --git a/src/System.IO.FileSystem/src/System.IO.FileSystem.csproj b/src/System.IO.FileSystem/src/System.IO.FileSystem.csproj
index 35b1396e06..df9ff7154e 100644
--- a/src/System.IO.FileSystem/src/System.IO.FileSystem.csproj
+++ b/src/System.IO.FileSystem/src/System.IO.FileSystem.csproj
@@ -19,6 +19,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Windows_NT-Release|AnyCPU'" />
<ItemGroup>
+ <Compile Include="System\IO\Enumeration\FileSystemEntry.cs" />
<Compile Include="System\IO\Enumeration\FileSystemEnumerable.cs" />
<Compile Include="System\IO\Enumeration\FileSystemEnumerableFactory.cs" />
<Compile Include="System\IO\Enumeration\FileSystemEnumerator.cs" />
diff --git a/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
index e554bc8538..90179923ca 100644
--- a/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
+++ b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Unix.cs
@@ -9,7 +9,7 @@ namespace System.IO.Enumeration
/// <summary>
/// Lower level view of FileSystemInfo used for processing and filtering find results.
/// </summary>
- public unsafe ref struct FileSystemEntry
+ public unsafe ref partial struct FileSystemEntry
{
private const int FileNameBufferSize = 256;
internal Interop.Sys.DirectoryEntry _directoryEntry;
@@ -44,10 +44,14 @@ namespace System.IO.Enumeration
// We know it's a directory.
isDirectory = true;
}
- else if ((directoryEntry.InodeType == Interop.Sys.NodeType.DT_LNK)
- && Interop.Sys.Stat(entry.FullPath, out Interop.Sys.FileStatus targetStatus) >= 0)
+ else if ((directoryEntry.InodeType == Interop.Sys.NodeType.DT_LNK
+ || directoryEntry.InodeType == Interop.Sys.NodeType.DT_UNKNOWN)
+ && (Interop.Sys.Stat(entry.FullPath, out Interop.Sys.FileStatus targetStatus) >= 0
+ || Interop.Sys.LStat(entry.FullPath, out targetStatus) >= 0))
{
- // It's a symlink: stat to it to see if we can resolve it to a directory.
+ // Symlink or unknown: Stat to it to see if we can resolve it to a directory. If Stat fails,
+ // it could be because the symlink is broken, we don't have permissions, etc., in which
+ // case fall back to using LStat to evaluate based on the symlink itself.
isDirectory = (targetStatus.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR;
}
@@ -138,12 +142,6 @@ namespace System.IO.Enumeration
}
/// <summary>
- /// Returns the full path for find results, based on the initially provided path.
- /// </summary>
- public string ToSpecifiedFullPath() =>
- Path.Join(OriginalRootDirectory, Directory.Slice(RootDirectory.Length), FileName);
-
- /// <summary>
/// Returns the full path of the find result.
/// </summary>
public string ToFullPath() =>
diff --git a/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Windows.cs b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Windows.cs
index 0ce20d52ab..92754c684a 100644
--- a/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Windows.cs
+++ b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.Windows.cs
@@ -7,7 +7,7 @@ namespace System.IO.Enumeration
/// <summary>
/// Lower level view of FileSystemInfo used for processing and filtering find results.
/// </summary>
- public unsafe ref struct FileSystemEntry
+ public unsafe ref partial struct FileSystemEntry
{
internal static void Initialize(
ref FileSystemEntry entry,
@@ -76,12 +76,6 @@ namespace System.IO.Enumeration
=> FileSystemInfo.Create(Path.Join(Directory, FileName), ref this);
/// <summary>
- /// Returns the full path for find results, based on the initially provided path.
- /// </summary>
- public string ToSpecifiedFullPath() =>
- Path.Join(OriginalRootDirectory, Directory.Slice(RootDirectory.Length), FileName);
-
- /// <summary>
/// Returns the full path of the find result.
/// </summary>
public string ToFullPath() =>
diff --git a/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.cs b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.cs
new file mode 100644
index 0000000000..1c1650c632
--- /dev/null
+++ b/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEntry.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.IO.Enumeration
+{
+ public ref partial struct FileSystemEntry
+ {
+ /// <summary>
+ /// Returns the full path for find results, based on the initially provided path.
+ /// </summary>
+ public string ToSpecifiedFullPath()
+ {
+ // We want to provide the enumerated segment of the path appended to the originally specified path. This is
+ // the behavior of the various Directory APIs that return a list of strings.
+ //
+ // RootDirectory has the final separator trimmed, OriginalRootDirectory does not. Our legacy behavior would
+ // effectively account for this by appending subdirectory names as it recursed. As such we need to trim one
+ // separator when combining with the relative path (Directory.Slice(RootDirectory.Length)).
+ //
+ // Original => Root => Directory => FileName => relativePath => Specified
+ // C:\foo C:\foo C:\foo bar "" C:\foo\bar
+ // C:\foo\ C:\foo C:\foo bar "" C:\foo\bar
+ // C:\foo/ C:\foo C:\foo bar "" C:\foo/bar
+ // C:\foo\\ C:\foo C:\foo bar "" C:\foo\\bar
+ // C:\foo C:\foo C:\foo\bar jar "bar" C:\foo\bar\jar
+ // C:\foo\ C:\foo C:\foo\bar jar "bar" C:\foo\bar\jar
+ // C:\foo/ C:\foo C:\foo\bar jar "bar" C:\foo/bar\jar
+
+
+ // If we're at the top level directory the Directory and RootDirectory will be identical. As there are no
+ // trailing slashes in play, once we're in a subdirectory, slicing off the root will leave us with an
+ // initial separator. We need to trim that off if it exists, but it isn't needed if the original root
+ // didn't have a separator. Join() would handle it if we did trim it, not doing so is an optimization.
+
+ ReadOnlySpan<char> relativePath = Directory.Slice(RootDirectory.Length);
+ if (PathInternal.EndsInDirectorySeparator(OriginalRootDirectory) && PathInternal.StartsWithDirectorySeparator(relativePath))
+ relativePath = relativePath.Slice(1);
+
+ return Path.Join(OriginalRootDirectory, relativePath, FileName);
+ }
+ }
+}
diff --git a/src/System.IO.FileSystem/tests/Directory/GetFiles.cs b/src/System.IO.FileSystem/tests/Directory/GetFiles.cs
index 79c22762df..7a8a36bde6 100644
--- a/src/System.IO.FileSystem/tests/Directory/GetFiles.cs
+++ b/src/System.IO.FileSystem/tests/Directory/GetFiles.cs
@@ -147,6 +147,8 @@ namespace System.IO.Tests
public class Directory_GetFiles_str_str_so : Directory_GetFileSystemEntries_str_str_so
{
+ public virtual bool IsDirectoryInfo => false;
+
protected override bool TestFiles { get { return true; } }
protected override bool TestDirectories { get { return false; } }
@@ -164,5 +166,32 @@ namespace System.IO.Tests
{
return Directory.GetFiles(path, searchPattern, option);
}
+
+ [Theory, MemberData(nameof(TrailingSeparators))]
+ public void DirectoryWithTrailingSeparators(string trailing)
+ {
+ // When getting strings back we should retain the root path as specified for Directory.
+ // DirectoryInfo returns the normalized full path in all cases.
+
+ // Add the trailing separator up front for Directory as we want to validate against
+ // the path _with_ the separator on it. Creation doesn't care about trailing, and
+ // Path.Combine doesn't change the existing separators, it just adds the canonical
+ // separator if needed.
+ string root = GetTestFilePath() + (IsDirectoryInfo ? "" : trailing);
+ string rootFile = Path.Combine(root, GetTestFileName());
+ string subDirectory = Path.Combine(root, GetTestFileName());
+ string nestedFile = Path.Combine(subDirectory, GetTestFileName());
+
+ Directory.CreateDirectory(subDirectory);
+ File.Create(rootFile).Dispose();
+ File.Create(nestedFile).Dispose();
+
+ // Add the trailing separator if we haven't (for DI) so we can validate that we
+ // either retain (D) or don't retain (DI) the separators as we specified them.
+ // Note that some of the cases actually match canonical (one standard separator)
+ // so they never change.
+ string[] files = GetEntries(root + (IsDirectoryInfo ? trailing : ""), "*", SearchOption.AllDirectories);
+ FSAssert.EqualWhenOrdered(new string[] { rootFile, nestedFile }, files);
+ }
}
}
diff --git a/src/System.IO.FileSystem/tests/DirectoryInfo/EnumerableAPIs.cs b/src/System.IO.FileSystem/tests/DirectoryInfo/EnumerableAPIs.cs
index 8be99d828c..dd1875a2d5 100644
--- a/src/System.IO.FileSystem/tests/DirectoryInfo/EnumerableAPIs.cs
+++ b/src/System.IO.FileSystem/tests/DirectoryInfo/EnumerableAPIs.cs
@@ -32,6 +32,8 @@ namespace System.IO.Tests
public class DirectoryInfo_EnumerateFiles_str_str_so : Directory_GetFiles_str_str_so
{
+ public override bool IsDirectoryInfo => true;
+
public override string[] GetEntries(string path)
{
return ((new DirectoryInfo(path).EnumerateFiles("*", SearchOption.TopDirectoryOnly).Select(x => x.FullName)).ToArray());
diff --git a/src/System.IO.FileSystem/tests/DirectoryInfo/GetFiles.cs b/src/System.IO.FileSystem/tests/DirectoryInfo/GetFiles.cs
index 85fef80609..13970ae34d 100644
--- a/src/System.IO.FileSystem/tests/DirectoryInfo/GetFiles.cs
+++ b/src/System.IO.FileSystem/tests/DirectoryInfo/GetFiles.cs
@@ -30,6 +30,8 @@ namespace System.IO.Tests
public class DirectoryInfo_GetFiles_str_so : Directory_GetFiles_str_str_so
{
+ public override bool IsDirectoryInfo => true;
+
public override string[] GetEntries(string path)
{
return ((new DirectoryInfo(path).GetFiles("*", SearchOption.TopDirectoryOnly).Select(x => x.FullName)).ToArray());
diff --git a/src/System.IO.FileSystem/tests/FileSystemTest.cs b/src/System.IO.FileSystem/tests/FileSystemTest.cs
index 6f020a00f6..ff21035632 100644
--- a/src/System.IO.FileSystem/tests/FileSystemTest.cs
+++ b/src/System.IO.FileSystem/tests/FileSystemTest.cs
@@ -33,6 +33,26 @@ namespace System.IO.Tests
public static TheoryData ControlWhiteSpace = IOInputs.GetControlWhiteSpace().ToTheoryData();
public static TheoryData NonControlWhiteSpace = IOInputs.GetNonControlWhiteSpace().ToTheoryData();
+ public static TheoryData<string> TrailingSeparators
+ {
+ get
+ {
+ var data = new TheoryData<string>()
+ {
+ "",
+ "" + Path.DirectorySeparatorChar,
+ "" + Path.DirectorySeparatorChar + Path.DirectorySeparatorChar
+ };
+
+ if (PlatformDetection.IsWindows)
+ {
+ data.Add("" + Path.AltDirectorySeparatorChar);
+ }
+
+ return data;
+ }
+ }
+
/// <summary>
/// In some cases (such as when running without elevated privileges),
/// the symbolic link may fail to create. Only run this test if it creates
diff --git a/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs b/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
index 5400a562e8..fdf7d48e56 100644
--- a/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
+++ b/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs
@@ -104,7 +104,7 @@ namespace System.Net.Http
}
// We're only here if we need more data to make forward progress.
- await _connection.FillAsync();
+ await _connection.FillAsync().ConfigureAwait(false);
// Now that we have more, see if we can get any response data, and if
// we can we're done.
diff --git a/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs
index d89927a8aa..4047af354a 100644
--- a/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs
+++ b/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs
@@ -54,9 +54,7 @@ namespace System.Net.Http
saea.Initialize(cancellationToken);
// Configure which server to which to connect.
- saea.RemoteEndPoint = IPAddress.TryParse(host, out IPAddress address) ?
- (EndPoint)new IPEndPoint(address, port) :
- new DnsEndPoint(host, port);
+ saea.RemoteEndPoint = new DnsEndPoint(host, port);
// Initiate the connection.
if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, saea))
diff --git a/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
index 71015a6554..2bd2ff8145 100644
--- a/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
+++ b/src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs
@@ -385,7 +385,7 @@ namespace System.Net.Http
HttpRequestMessage tunnelRequest = new HttpRequestMessage(HttpMethod.Connect, _proxyUri);
tunnelRequest.Headers.Host = $"{_host}:{_port}"; // This specifies destination host/port to connect to
- HttpResponseMessage tunnelResponse = await _poolManager.SendProxyConnectAsync(tunnelRequest, _proxyUri, cancellationToken);
+ HttpResponseMessage tunnelResponse = await _poolManager.SendProxyConnectAsync(tunnelRequest, _proxyUri, cancellationToken).ConfigureAwait(false);
if (tunnelResponse.StatusCode != HttpStatusCode.OK)
{
diff --git a/src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs b/src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs
index 0e0a7782d0..f01377578a 100644
--- a/src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs
+++ b/src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs
@@ -265,9 +265,10 @@ namespace System.Net.Security
}
readBytes = await FillBufferAsync(adapter, SecureChannel.ReadHeaderSize + payloadBytes).ConfigureAwait(false);
- if (readBytes < 0)
+ Debug.Assert(readBytes >= 0);
+ if (readBytes == 0)
{
- throw new IOException(SR.net_frame_read_size);
+ throw new IOException(SR.net_io_eof);
}
// At this point, readBytes contains the size of the header plus body.
diff --git a/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs b/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs
index 7910342a36..3e0d6ed171 100644
--- a/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs
+++ b/src/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs
@@ -409,6 +409,50 @@ namespace System.Net.Security.Tests
}
}
+ [Fact]
+ public async Task SslStream_StreamToStream_EOFDuringFrameRead_ThrowsIOException()
+ {
+ var network = new VirtualNetwork();
+ using (var clientNetworkStream = new VirtualNetworkStream(network, isServer: false))
+ using (var serverNetworkStream = new VirtualNetworkStream(network, isServer: true))
+ {
+ int readMode = 0;
+ var serverWrappedNetworkStream = new DelegateStream(
+ canWriteFunc: () => true,
+ canReadFunc: () => true,
+ writeFunc: (buffer, offset, count) => serverNetworkStream.Write(buffer, offset, count),
+ readFunc: (buffer, offset, count) =>
+ {
+ // Do normal reads as requested until the read mode is set
+ // to 1. Then do a single read of only 10 bytes to read only
+ // part of the message, and subsequently return EOF.
+ if (readMode == 0)
+ {
+ return serverNetworkStream.Read(buffer, offset, count);
+ }
+ else if (readMode == 1)
+ {
+ readMode = 2;
+ return serverNetworkStream.Read(buffer, offset, 10); // read at least header but less than full frame
+ }
+ else
+ {
+ return 0;
+ }
+ });
+
+
+ using (var clientSslStream = new SslStream(clientNetworkStream, false, AllowAnyServerCertificate))
+ using (var serverSslStream = new SslStream(serverWrappedNetworkStream))
+ {
+ await DoHandshake(clientSslStream, serverSslStream);
+ await clientSslStream.WriteAsync(new byte[20], 0, 20);
+ readMode = 1;
+ await Assert.ThrowsAsync<IOException>(() => serverSslStream.ReadAsync(new byte[1], 0, 1));
+ }
+ }
+ }
+
private bool VerifyOutput(byte[] actualBuffer, byte[] expectedBuffer)
{
return expectedBuffer.SequenceEqual(actualBuffer);
diff --git a/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj
index c758241a3b..bdf707b62d 100644
--- a/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj
+++ b/src/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj
@@ -42,6 +42,9 @@
<Compile Include="ServiceNameCollectionTest.cs" />
<Compile Include="NegotiateStreamKerberosTest.cs" />
<!-- Common test files -->
+ <Compile Include="$(CommonTestPath)\System\IO\DelegateStream.cs">
+ <Link>Common\System\IO\DelegateStream.cs</Link>
+ </Compile>
<Compile Include="$(CommonTestPath)\System\Net\Capability.Security.cs">
<Link>Common\System\Net\Capability.Security.cs</Link>
</Compile>
diff --git a/src/System.Private.Xml/src/Resources/Strings.resx b/src/System.Private.Xml/src/Resources/Strings.resx
index 073ceecb21..a95f77a85f 100644
--- a/src/System.Private.Xml/src/Resources/Strings.resx
+++ b/src/System.Private.Xml/src/Resources/Strings.resx
@@ -3358,7 +3358,7 @@
<value>Cannot generate serialization code '{0}' because a directory with the same name already exists.</value>
</data>
<data name="ErrDirectoryNotExists" xml:space="preserve">
- <value>Cannot generate serialization code '{0}' because directory {1} doesn't exist.</value>
+ <value>Cannot generate serialization code because directory {0} doesn't exist.</value>
</data>
<data name="ErrInvalidArgument" xml:space="preserve">
<value>Ignoring invalid command line argument: '{0}'.</value>
diff --git a/src/System.Runtime/tests/System/BooleanTests.netcoreapp.cs b/src/System.Runtime/tests/System/BooleanTests.netcoreapp.cs
index c812391b9e..95bd5a3d72 100644
--- a/src/System.Runtime/tests/System/BooleanTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/BooleanTests.netcoreapp.cs
@@ -2,19 +2,31 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using Xunit;
namespace System.Tests
{
public partial class BooleanTests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1] };
+ }
+
+ yield return new object[] { " \0 \0 TrueFalse \0 ", 6, 4, true };
+ yield return new object[] { " \0 \0 TrueFalse \0 ", 10, 5, false };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, bool expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, bool expected)
{
- Assert.Equal(expected, bool.Parse(value.AsSpan()));
+ Assert.Equal(expected, bool.Parse(value.AsSpan(offset, count)));
- Assert.True(bool.TryParse(value.AsSpan(), out bool result));
+ Assert.True(bool.TryParse(value.AsSpan(offset, count), out bool result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/ByteTests.netcoreapp.cs b/src/System.Runtime/tests/System/ByteTests.netcoreapp.cs
index b60f1a2ac9..08b6b8e9bc 100644
--- a/src/System.Runtime/tests/System/ByteTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/ByteTests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,30 @@ namespace System.Tests
{
public partial class ByteTests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (byte)12 };
+ yield return new object[] { "+123", 0, 2, NumberStyles.Integer, null, (byte)1 };
+ yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (byte)123 };
+ yield return new object[] { " 123 ", 4, 1, NumberStyles.Integer, null, (byte)3 };
+ yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (byte)0x2 };
+ yield return new object[] { "10", 0, 1, NumberStyles.AllowThousands, null, (byte)1 };
+ yield return new object[] { "$100", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (byte)1 };
+ }
+
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, byte expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, byte expected)
{
- Assert.Equal(expected, byte.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, byte.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(byte.TryParse(value.AsSpan(), style, provider, out byte result));
+ Assert.True(byte.TryParse(value.AsSpan(offset, count), style, provider, out byte result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs b/src/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs
index 97d677ac4a..0f6ad1da95 100644
--- a/src/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/DateTimeOffsetTests.netcoreapp.cs
@@ -25,6 +25,24 @@ namespace System.Tests
Assert.Equal(expectedString, actual.ToString());
}
+ [Theory]
+ [InlineData("r")]
+ [InlineData("o")]
+ public static void ToString_Slice_ParseSpan_RoundtripsSuccessfully(string roundtripFormat)
+ {
+ string expectedString = DateTimeOffset.UtcNow.ToString(roundtripFormat);
+ ReadOnlySpan<char> expectedSpan = ("abcd" + expectedString + "1234").AsSpan("abcd".Length, expectedString.Length);
+
+ Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan).ToString(roundtripFormat));
+ Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan, null).ToString(roundtripFormat));
+ Assert.Equal(expectedString, DateTimeOffset.Parse(expectedSpan, null, DateTimeStyles.None).ToString(roundtripFormat));
+
+ Assert.True(DateTimeOffset.TryParse(expectedSpan, out DateTimeOffset actual));
+ Assert.Equal(expectedString, actual.ToString(roundtripFormat));
+ Assert.True(DateTimeOffset.TryParse(expectedSpan, null, DateTimeStyles.None, out actual));
+ Assert.Equal(expectedString, actual.ToString(roundtripFormat));
+ }
+
[Fact]
public static void ToString_ParseExactSpan_RoundtripsSuccessfully()
{
diff --git a/src/System.Runtime/tests/System/DecimalTests.netcoreapp.cs b/src/System.Runtime/tests/System/DecimalTests.netcoreapp.cs
index 28855c99f3..01fd648214 100644
--- a/src/System.Runtime/tests/System/DecimalTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/DecimalTests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,9 +10,24 @@ namespace System.Tests
{
public partial class DecimalTests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "-123", 1, 3, NumberStyles.Number, null, 123m };
+ yield return new object[] { "-123", 0, 3, NumberStyles.Number, null, -12m };
+ yield return new object[] { 1000.ToString("N0"), 0, 4, NumberStyles.AllowThousands, null, 100m };
+ yield return new object[] { 1000.ToString("N0"), 2, 3, NumberStyles.AllowThousands, null, 0m };
+ yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 123m };
+ yield return new object[] { "1234567890123456789012345.678456", 1, 4, NumberStyles.Number, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 2345m };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, decimal expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, decimal expected)
{
bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
decimal result;
@@ -20,18 +36,18 @@ namespace System.Tests
// Use Parse(string) or Parse(string, IFormatProvider)
if (isDefaultProvider)
{
- Assert.True(decimal.TryParse(value.AsSpan(), out result));
+ Assert.True(decimal.TryParse(value.AsSpan(offset, count), out result));
Assert.Equal(expected, result);
- Assert.Equal(expected, decimal.Parse(value.AsSpan()));
+ Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count)));
}
- Assert.Equal(expected, decimal.Parse(value.AsSpan(), provider: provider));
+ Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count), provider: provider));
}
- Assert.Equal(expected, decimal.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, decimal.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(decimal.TryParse(value.AsSpan(), style, provider, out result));
+ Assert.True(decimal.TryParse(value.AsSpan(offset, count), style, provider, out result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/DoubleTests.netcoreapp.cs b/src/System.Runtime/tests/System/DoubleTests.netcoreapp.cs
index 0e4dfbffc5..16b5dc5013 100644
--- a/src/System.Runtime/tests/System/DoubleTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/DoubleTests.netcoreapp.cs
@@ -87,9 +87,24 @@ namespace System.Tests
Assert.Equal(expected, double.IsSubnormal(d));
}
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ const NumberStyles DefaultStyle = NumberStyles.Float | NumberStyles.AllowThousands;
+ yield return new object[] { "-123", 0, 3, DefaultStyle, null, (double)-12 };
+ yield return new object[] { "-123", 1, 3, DefaultStyle, null, (double)123 };
+ yield return new object[] { "1E23", 0, 3, DefaultStyle, null, 1E2 };
+ yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, 123 };
+ yield return new object[] { "-Infinity", 1, 8, NumberStyles.Any, NumberFormatInfo.InvariantInfo, double.PositiveInfinity };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, double expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, double expected)
{
bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
double result;
@@ -98,18 +113,18 @@ namespace System.Tests
// Use Parse(string) or Parse(string, IFormatProvider)
if (isDefaultProvider)
{
- Assert.True(double.TryParse(value.AsSpan(), out result));
+ Assert.True(double.TryParse(value.AsSpan(offset, count), out result));
Assert.Equal(expected, result);
- Assert.Equal(expected, double.Parse(value.AsSpan()));
+ Assert.Equal(expected, double.Parse(value.AsSpan(offset, count)));
}
- Assert.Equal(expected, double.Parse(value.AsSpan(), provider: provider));
+ Assert.Equal(expected, double.Parse(value.AsSpan(offset, count), provider: provider));
}
- Assert.Equal(expected, double.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, double.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(double.TryParse(value.AsSpan(), style, provider, out result));
+ Assert.True(double.TryParse(value.AsSpan(offset, count), style, provider, out result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/Int16Tests.netcoreapp.cs b/src/System.Runtime/tests/System/Int16Tests.netcoreapp.cs
index a03398fb60..175b1fdcff 100644
--- a/src/System.Runtime/tests/System/Int16Tests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/Int16Tests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,30 @@ namespace System.Tests
{
public partial class Int16Tests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "-32767", 1, 5, NumberStyles.Integer, null, (short)32767 };
+ yield return new object[] { "-32768", 0, 5, NumberStyles.Integer, null, (short)-3276 };
+ yield return new object[] { "abc", 0, 2, NumberStyles.HexNumber, null, (short)0xab };
+ yield return new object[] { "abc", 1, 2, NumberStyles.HexNumber, null, (short)0xbc };
+ yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (short)123 };
+ yield return new object[] { "123", 0, 1, NumberStyles.Integer, new NumberFormatInfo(), (short)1 };
+ yield return new object[] { "$1,000", 1, 5, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (short)1000 };
+ yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (short)1 };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, short expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, short expected)
{
- Assert.Equal(expected, short.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, short.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(short.TryParse(value.AsSpan(), style, provider, out short result));
+ Assert.True(short.TryParse(value.AsSpan(offset, count), style, provider, out short result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/Int32Tests.netcoreapp.cs b/src/System.Runtime/tests/System/Int32Tests.netcoreapp.cs
index 6cb12dd8eb..37e928d893 100644
--- a/src/System.Runtime/tests/System/Int32Tests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/Int32Tests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,77 @@ namespace System.Tests
{
public partial class Int32Tests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ NumberFormatInfo samePositiveNegativeFormat = new NumberFormatInfo()
+ {
+ PositiveSign = "|",
+ NegativeSign = "|"
+ };
+
+ NumberFormatInfo emptyPositiveFormat = new NumberFormatInfo() { PositiveSign = "" };
+ NumberFormatInfo emptyNegativeFormat = new NumberFormatInfo() { NegativeSign = "" };
+
+ // None
+ yield return new object[] { "2147483647", 1, 9, NumberStyles.None, null, 147483647 };
+ yield return new object[] { "2147483647", 1, 1, NumberStyles.None, null, 1 };
+ yield return new object[] { "123\0\0", 2, 2, NumberStyles.None, null, 3 };
+
+ // Hex
+ yield return new object[] { "abc", 0, 1, NumberStyles.HexNumber, null, 0xa };
+ yield return new object[] { "ABC", 1, 1, NumberStyles.HexNumber, null, 0xB };
+ yield return new object[] { "FFFFFFFF", 6, 2, NumberStyles.HexNumber, null, 0xFF };
+ yield return new object[] { "FFFFFFFF", 0, 1, NumberStyles.HexNumber, null, 0xF };
+
+ // Currency
+ yield return new object[] { "-$1000", 1, 5, NumberStyles.Currency, new NumberFormatInfo()
+ {
+ CurrencySymbol = "$",
+ CurrencyGroupSeparator = "|",
+ NumberGroupSeparator = "/"
+ }, 1000 };
+
+ NumberFormatInfo emptyCurrencyFormat = new NumberFormatInfo() { CurrencySymbol = "" };
+ yield return new object[] { "100", 1, 2, NumberStyles.Currency, emptyCurrencyFormat, 0 };
+ yield return new object[] { "100", 0, 1, NumberStyles.Currency, emptyCurrencyFormat, 1 };
+
+ // If CurrencySymbol and Negative are the same, NegativeSign is preferred
+ NumberFormatInfo sameCurrencyNegativeSignFormat = new NumberFormatInfo()
+ {
+ NegativeSign = "|",
+ CurrencySymbol = "|"
+ };
+ yield return new object[] { "1000", 1, 3, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowLeadingSign, sameCurrencyNegativeSignFormat, 0 };
+ yield return new object[] { "|1000", 0, 2, NumberStyles.AllowCurrencySymbol | NumberStyles.AllowLeadingSign, sameCurrencyNegativeSignFormat, -1 };
+
+ // Any
+ yield return new object[] { "123", 0, 2, NumberStyles.Any, null, 12 };
+
+ // AllowLeadingSign
+ yield return new object[] { "-2147483648", 0, 10, NumberStyles.AllowLeadingSign, null, -214748364 };
+
+ // AllowTrailingSign
+ yield return new object[] { "123-", 0, 3, NumberStyles.AllowTrailingSign, null, 123 };
+
+ // AllowExponent
+ yield return new object[] { "1E2", 0, 1, NumberStyles.AllowExponent, null, 1 };
+ yield return new object[] { "1E+2", 3, 1, NumberStyles.AllowExponent, null, 2 };
+ yield return new object[] { "(1E2)", 1, 3, NumberStyles.AllowExponent | NumberStyles.AllowParentheses, null, 1E2 };
+ yield return new object[] { "-1E2", 1, 3, NumberStyles.AllowExponent | NumberStyles.AllowLeadingSign, null, 1E2 };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, int expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, int expected)
{
- Assert.Equal(expected, int.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, int.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(int.TryParse(value.AsSpan(), style, provider, out int result));
+ Assert.True(int.TryParse(value.AsSpan(offset, count), style, provider, out int result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/Int64Tests.netcoreapp.cs b/src/System.Runtime/tests/System/Int64Tests.netcoreapp.cs
index 94f55b14e7..d831e0bb1d 100644
--- a/src/System.Runtime/tests/System/Int64Tests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/Int64Tests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,28 @@ namespace System.Tests
{
public partial class Int64Tests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "-9223372036854775808", 0, 19, NumberStyles.Integer, null, -922337203685477580 };
+ yield return new object[] { "09223372036854775807", 1, 19, NumberStyles.Integer, null, 9223372036854775807 };
+ yield return new object[] { "9223372036854775807", 0, 1, NumberStyles.Integer, null, 9 };
+ yield return new object[] { "ABC", 0, 2, NumberStyles.HexNumber, null, (long)0xAB };
+ yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (long)123 };
+ yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (long)1 };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, long expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, long expected)
{
- Assert.Equal(expected, long.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, long.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(long.TryParse(value.AsSpan(), style, provider, out long result));
+ Assert.True(long.TryParse(value.AsSpan(offset, count), style, provider, out long result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/SByteTests.netcoreapp.cs b/src/System.Runtime/tests/System/SByteTests.netcoreapp.cs
index 9b451b31f9..f95a6daae3 100644
--- a/src/System.Runtime/tests/System/SByteTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/SByteTests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,28 @@ namespace System.Tests
{
public partial class SByteTests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "-123", 0, 2, NumberStyles.Integer, null, (sbyte)-1 };
+ yield return new object[] { "-123", 1, 3, NumberStyles.Integer, null, (sbyte)123 };
+ yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (sbyte)0x1 };
+ yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (sbyte)0x2 };
+ yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, null, (sbyte)123 };
+ yield return new object[] { "$100", 1, 1, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (sbyte)1 };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, sbyte expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, sbyte expected)
{
- Assert.Equal(expected, sbyte.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, sbyte.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(sbyte.TryParse(value.AsSpan(), style, provider, out sbyte result));
+ Assert.True(sbyte.TryParse(value.AsSpan(offset, count), style, provider, out sbyte result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/SingleTests.netcoreapp.cs b/src/System.Runtime/tests/System/SingleTests.netcoreapp.cs
index cb58cef151..50382e5ccc 100644
--- a/src/System.Runtime/tests/System/SingleTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/SingleTests.netcoreapp.cs
@@ -87,9 +87,27 @@ namespace System.Tests
Assert.Equal(expected, float.IsSubnormal(d));
}
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ const NumberStyles DefaultStyle = NumberStyles.Float | NumberStyles.AllowThousands;
+
+ yield return new object[] { "-123", 1, 3, DefaultStyle, null, (float)123 };
+ yield return new object[] { "-123", 0, 3, DefaultStyle, null, (float)-12 };
+ yield return new object[] { "1E23", 0, 3, DefaultStyle, null, (float)1E2 };
+ yield return new object[] { "123", 0, 2, NumberStyles.Float, new NumberFormatInfo(), (float)12 };
+ yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$", CurrencyGroupSeparator = "," }, (float)10 };
+ yield return new object[] { "(123)", 1, 3, NumberStyles.AllowParentheses, new NumberFormatInfo() { NumberDecimalSeparator = "." }, (float)123 };
+ yield return new object[] { "-Infinity", 1, 8, NumberStyles.Any, NumberFormatInfo.InvariantInfo, float.PositiveInfinity };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, float expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, float expected)
{
bool isDefaultProvider = provider == null || provider == NumberFormatInfo.CurrentInfo;
float result;
@@ -98,18 +116,18 @@ namespace System.Tests
// Use Parse(string) or Parse(string, IFormatProvider)
if (isDefaultProvider)
{
- Assert.True(float.TryParse(value.AsSpan(), out result));
+ Assert.True(float.TryParse(value.AsSpan(offset, count), out result));
Assert.Equal(expected, result);
- Assert.Equal(expected, float.Parse(value.AsSpan()));
+ Assert.Equal(expected, float.Parse(value.AsSpan(offset, count)));
}
- Assert.Equal(expected, float.Parse(value.AsSpan(), provider: provider));
+ Assert.Equal(expected, float.Parse(value.AsSpan(offset, count), provider: provider));
}
- Assert.Equal(expected, float.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, float.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(float.TryParse(value.AsSpan(), style, provider, out result));
+ Assert.True(float.TryParse(value.AsSpan(offset, count), style, provider, out result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs b/src/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs
index 18a46a8752..1478e6855f 100644
--- a/src/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/TimeSpanTests.netcoreapp.cs
@@ -111,11 +111,27 @@ namespace System.Tests
AssertExtensions.Throws<ArgumentException>("divisor", () => TimeSpan.FromDays(1).Divide(double.NaN));
}
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2] };
+ }
+
+ yield return new object[] { " 12:24:02 ", 5, 8, null, new TimeSpan(0, 12, 24, 2, 0) };
+ yield return new object[] { " 12:24:02 ", 6, 7, null, new TimeSpan(0, 2, 24, 2, 0) };
+ yield return new object[] { " 12:24:02 ", 6, 6, null, new TimeSpan(0, 2, 24, 0, 0) };
+ yield return new object[] { "12:24:02.01", 0, 8, CultureInfo.InvariantCulture, new TimeSpan(0, 12, 24, 2, 0) };
+ yield return new object[] { "1:1:1.00000001", 0, 7, CultureInfo.InvariantCulture, new TimeSpan(1, 1, 1) };
+ yield return new object[] { "1:1:.00000001", 0, 6, CultureInfo.InvariantCulture, new TimeSpan(36600000000) };
+ yield return new object[] { "24:00:00", 1, 7, null, new TimeSpan(4, 0, 0) };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span(string inputString, IFormatProvider provider, TimeSpan expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span(string inputString, int offset, int count, IFormatProvider provider, TimeSpan expected)
{
- ReadOnlySpan<char> input = inputString.AsSpan();
+ ReadOnlySpan<char> input = inputString.AsSpan(offset, count);
TimeSpan result;
Assert.Equal(expected, TimeSpan.Parse(input, provider));
@@ -125,7 +141,7 @@ namespace System.Tests
// Also negate
if (!char.IsWhiteSpace(input[0]))
{
- input = ("-" + inputString).AsSpan();
+ input = ("-" + inputString.Substring(offset, count)).AsSpan();
expected = -expected;
Assert.Equal(expected, TimeSpan.Parse(input, provider));
diff --git a/src/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs b/src/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs
index aab8121bfc..4d7cc00547 100644
--- a/src/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/UInt16Tests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,29 @@ namespace System.Tests
{
public partial class UInt16Tests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (ushort)12 };
+ yield return new object[] { "123", 1, 2, NumberStyles.Integer, null, (ushort)23 };
+ yield return new object[] { "+123", 0, 2, NumberStyles.Integer, null, (ushort)1 };
+ yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (ushort)123 };
+ yield return new object[] { "AJK", 0, 1, NumberStyles.HexNumber, new NumberFormatInfo(), (ushort)0XA };
+ yield return new object[] { "$1,000", 0, 2, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ushort)1 };
+ yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ushort)10 };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, ushort expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, ushort expected)
{
- Assert.Equal(expected, ushort.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, ushort.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(ushort.TryParse(value.AsSpan(), style, provider, out ushort result));
+ Assert.True(ushort.TryParse(value.AsSpan(offset, count), style, provider, out ushort result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs b/src/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs
index e021c22055..19ade4bf5e 100644
--- a/src/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/UInt32Tests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,29 @@ namespace System.Tests
{
public partial class UInt32Tests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "123", 0, 2, NumberStyles.Integer, null, (uint)12 };
+ yield return new object[] { "123", 1, 2, NumberStyles.Integer, null, (uint)23 };
+ yield return new object[] { "4294967295", 0, 1, NumberStyles.Integer, null, 4 };
+ yield return new object[] { "4294967295", 9, 1, NumberStyles.Integer, null, 5 };
+ yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (uint)0x1 };
+ yield return new object[] { "12", 1, 1, NumberStyles.HexNumber, null, (uint)0x2 };
+ yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (uint)10 };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, uint expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, uint expected)
{
- Assert.Equal(expected, uint.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, uint.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(uint.TryParse(value.AsSpan(), style, provider, out uint result));
+ Assert.True(uint.TryParse(value.AsSpan(offset, count), style, provider, out uint result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs b/src/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs
index 6060db3ef3..37d3b1883d 100644
--- a/src/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/UInt64Tests.netcoreapp.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using System.Globalization;
using Xunit;
@@ -9,13 +10,28 @@ namespace System.Tests
{
public partial class UInt64Tests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1], inputs[2], inputs[3] };
+ }
+
+ yield return new object[] { "+123", 1, 3, NumberStyles.Integer, null, (ulong)123 };
+ yield return new object[] { "+123", 0, 3, NumberStyles.Integer, null, (ulong)12 };
+ yield return new object[] { " 123 ", 1, 2, NumberStyles.Integer, null, (ulong)1 };
+ yield return new object[] { "12", 0, 1, NumberStyles.HexNumber, null, (ulong)0x1 };
+ yield return new object[] { "ABC", 1, 1, NumberStyles.HexNumber, null, (ulong)0xb };
+ yield return new object[] { "$1,000", 1, 3, NumberStyles.Currency, new NumberFormatInfo() { CurrencySymbol = "$" }, (ulong)10 };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_Valid(string value, NumberStyles style, IFormatProvider provider, ulong expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_Valid(string value, int offset, int count, NumberStyles style, IFormatProvider provider, ulong expected)
{
- Assert.Equal(expected, ulong.Parse(value.AsSpan(), style, provider));
+ Assert.Equal(expected, ulong.Parse(value.AsSpan(offset, count), style, provider));
- Assert.True(ulong.TryParse(value.AsSpan(), style, provider, out ulong result));
+ Assert.True(ulong.TryParse(value.AsSpan(offset, count), style, provider, out ulong result));
Assert.Equal(expected, result);
}
diff --git a/src/System.Runtime/tests/System/VersionTests.netcoreapp.cs b/src/System.Runtime/tests/System/VersionTests.netcoreapp.cs
index 2d75d18df6..f33a046e3f 100644
--- a/src/System.Runtime/tests/System/VersionTests.netcoreapp.cs
+++ b/src/System.Runtime/tests/System/VersionTests.netcoreapp.cs
@@ -2,24 +2,38 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Collections.Generic;
using Xunit;
namespace System.Tests
{
public partial class VersionTests
{
+ public static IEnumerable<object[]> Parse_ValidWithOffsetCount_TestData()
+ {
+ foreach (object[] inputs in Parse_Valid_TestData())
+ {
+ yield return new object[] { inputs[0], 0, ((string)inputs[0]).Length, inputs[1] };
+ }
+
+ yield return new object[] { "1.2.3", 0, 3, new Version(1, 2) };
+ yield return new object[] { "1.2.3", 2, 3, new Version(2, 3) };
+ yield return new object[] { "2 .3. 4. \t\r\n15 ", 0, 11, new Version(2, 3, 4) };
+ yield return new object[] { "+1.+2.+3.+4", 3, 5, new Version(2, 3) };
+ }
+
[Theory]
- [MemberData(nameof(Parse_Valid_TestData))]
- public static void Parse_Span_ValidInput_ReturnsExpected(string input, Version expected)
+ [MemberData(nameof(Parse_ValidWithOffsetCount_TestData))]
+ public static void Parse_Span_ValidInput_ReturnsExpected(string input, int offset, int count, Version expected)
{
if (input == null)
{
return;
}
- Assert.Equal(expected, Version.Parse(input.AsSpan()));
+ Assert.Equal(expected, Version.Parse(input.AsSpan(offset, count)));
- Assert.True(Version.TryParse(input.AsSpan(), out Version version));
+ Assert.True(Version.TryParse(input.AsSpan(offset, count), out Version version));
Assert.Equal(expected, version);
}
diff --git a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs
index 815c6fda30..44ecb4a2ca 100644
--- a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs
+++ b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs
@@ -32,6 +32,9 @@ namespace Internal.Cryptography
throw Interop.Crypto.CreateOpenSslCryptographicException();
default:
Debug.Assert(result == 0, "LookupFriendlyNameByOid returned unexpected result " + result);
+
+ // The lookup may have left errors in this case, clean up for precaution.
+ Interop.Crypto.ErrClearError();
return null;
}
}
diff --git a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OpenSslAsnFormatter.cs b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OpenSslAsnFormatter.cs
index 2e6e710a54..c38116b786 100644
--- a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OpenSslAsnFormatter.cs
+++ b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OpenSslAsnFormatter.cs
@@ -23,44 +23,63 @@ namespace Internal.Cryptography
// or to return null and let rawData get hex-encoded. CryptographicException should not
// be raised.
- using (SafeAsn1ObjectHandle asnOid = Interop.Crypto.ObjTxt2Obj(oid.Value))
- using (SafeAsn1OctetStringHandle octetString = Interop.Crypto.Asn1OctetStringNew())
+ bool clearErrors = true;
+ try
{
- if (asnOid.IsInvalid || octetString.IsInvalid)
+ using (SafeAsn1ObjectHandle asnOid = Interop.Crypto.ObjTxt2Obj(oid.Value))
+ using (SafeAsn1OctetStringHandle octetString = Interop.Crypto.Asn1OctetStringNew())
{
- return null;
- }
-
- if (!Interop.Crypto.Asn1OctetStringSet(octetString, rawData, rawData.Length))
- {
- return null;
- }
-
- using (SafeBioHandle bio = Interop.Crypto.CreateMemoryBio())
- using (SafeX509ExtensionHandle x509Ext = Interop.Crypto.X509ExtensionCreateByObj(asnOid, false, octetString))
- {
- if (bio.IsInvalid || x509Ext.IsInvalid)
+ if (asnOid.IsInvalid || octetString.IsInvalid)
{
return null;
}
- if (!Interop.Crypto.X509V3ExtPrint(bio, x509Ext))
+ if (!Interop.Crypto.Asn1OctetStringSet(octetString, rawData, rawData.Length))
{
return null;
}
- int printLen = Interop.Crypto.GetMemoryBioSize(bio);
+ using (SafeBioHandle bio = Interop.Crypto.CreateMemoryBio())
+ using (SafeX509ExtensionHandle x509Ext = Interop.Crypto.X509ExtensionCreateByObj(asnOid, false, octetString))
+ {
+ if (bio.IsInvalid || x509Ext.IsInvalid)
+ {
+ return null;
+ }
- // Account for the null terminator that it'll want to write.
- var buf = new byte[printLen + 1];
- int read = Interop.Crypto.BioGets(bio, buf, buf.Length);
+ if (!Interop.Crypto.X509V3ExtPrint(bio, x509Ext))
+ {
+ return null;
+ }
- if (read < 0)
- {
- throw Interop.Crypto.CreateOpenSslCryptographicException();
- }
+ // X509V3ExtPrint might contaminate the error queue on success, always clear now.
+ Interop.Crypto.ErrClearError();
- return Encoding.UTF8.GetString(buf, 0, read);
+ // Errors past here are handled by throws, don't need to double-lock
+ // the success path.
+ clearErrors = false;
+
+ int printLen = Interop.Crypto.GetMemoryBioSize(bio);
+
+ // Account for the null terminator that it'll want to write.
+ var buf = new byte[printLen + 1];
+ int read = Interop.Crypto.BioGets(bio, buf, buf.Length);
+
+ if (read < 0)
+ {
+ throw Interop.Crypto.CreateOpenSslCryptographicException();
+ }
+
+ return Encoding.UTF8.GetString(buf, 0, read);
+ }
+ }
+ }
+ finally
+ {
+ // All of the return null paths might have errors that we are ignoring.
+ if (clearErrors)
+ {
+ Interop.Crypto.ErrClearError();
}
}
}
diff --git a/src/System.Security.Cryptography.Encoding/tests/Asn1/Serializer/SimpleDeserialize.cs b/src/System.Security.Cryptography.Encoding/tests/Asn1/Serializer/SimpleDeserialize.cs
index 1b19ddd670..e61f3ac4a6 100644
--- a/src/System.Security.Cryptography.Encoding/tests/Asn1/Serializer/SimpleDeserialize.cs
+++ b/src/System.Security.Cryptography.Encoding/tests/Asn1/Serializer/SimpleDeserialize.cs
@@ -470,6 +470,34 @@ namespace System.Security.Cryptography.Tests.Asn1
Assert.Throws<CryptographicException>(
() => AsnSerializer.Deserialize<OptionalValues>(inputData, AsnEncodingRules.BER));
}
+
+ [Fact]
+ public static void ReadIndefiniteLengthCustomTaggedStrings()
+ {
+ byte[] inputData = (
+ // (constructed) SEQUENCE (indefinite)
+ "3080" +
+ // (constructed) CONTEXT-SPECIFIC 0 (indefinite)
+ "A080" +
+ // OCTET STRING (3): 020100
+ "0403020100" +
+ // EoC ([0])
+ "0000" +
+ // (constructed) CONTEXT-SPECIFIC 1 (indefinite)
+ "A180" +
+ // BIT STRING (4) (0 unused bits): 010203
+ "030400010203" +
+ // EoC ([1])
+ "0000" +
+ // EoC (SEQUENCE)
+ "0000").HexToByteArray();
+
+ CustomTaggedBinaryStrings parsed =
+ AsnSerializer.Deserialize<CustomTaggedBinaryStrings>(inputData, AsnEncodingRules.BER);
+
+ Assert.Equal("020100", parsed.OctetString.ByteArrayToHex());
+ Assert.Equal("010203", parsed.BitString.ByteArrayToHex());
+ }
}
// RFC 3280 / ITU-T X.509
@@ -841,4 +869,16 @@ namespace System.Security.Cryptography.Tests.Asn1
[IA5String, OptionalValue]
public string IA5String;
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CustomTaggedBinaryStrings
+ {
+ [OctetString]
+ [ExpectedTag(0)]
+ public ReadOnlyMemory<byte> OctetString;
+
+ [BitString]
+ [ExpectedTag(1)]
+ public ReadOnlyMemory<byte> BitString;
+ }
}
diff --git a/src/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs b/src/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs
index 4769dbeb80..51468612c1 100644
--- a/src/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs
+++ b/src/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/SignerInfo.cs
@@ -312,7 +312,9 @@ namespace System.Security.Cryptography.Pkcs
{
writer.PushSetOf();
- AsnReader reader = new AsnReader(modifiedAttr.AttrValues, writer.RuleSet);
+ AsnReader outerReader = new AsnReader(modifiedAttr.AttrValues, writer.RuleSet);
+ AsnReader reader = outerReader.ReadSetOf();
+ outerReader.ThrowIfNotEmpty();
int i = 0;
diff --git a/src/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs b/src/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs
index 2ecd2d5f98..8b7b616941 100644
--- a/src/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs
+++ b/src/System.Security.Cryptography.Pkcs/tests/EnvelopedCms/GeneralTests.cs
@@ -113,6 +113,46 @@ namespace System.Security.Cryptography.Pkcs.EnvelopedCmsTests.Tests
Assert.Equal<string>(expectedIssuers, actualIssuers);
}
+
+ [Fact]
+ public static void DecodeAllIndefinite()
+ {
+ byte[] encrypted = Convert.FromBase64String(
+ @"
+MIAGCSqGSIb3DQEHA6CAMIACAQAxggFXMIIBUwIBADA7MDMxGTAXBgNVBAoMEERh
+dGEgSW50ZXJjaGFuZ2UxFjAUBgNVBAMMDVVubyBUZXN0IFJvb3QCBFqG6RQwDQYJ
+KoZIhvcNAQEBBQAEggEAUPilAHUe67HG5vDCO/JBmof44G/XnDLtiDrbxD4QekGq
+mdPqazZiLDKEewlBy2uFJr/JijeYx6qNKTXs/EShw/lYnKisaK5ue6JZ7ssMunM9
+HpkiDfM+iyN7PxnC1riZ/Kg2JExY8pf5R1Zuvu29JSLhM9ajWk9C1pBzQRJ4vkY2
+OvFKR2th0Vgw7mTmc2X6HUK4tosB3LGKDVNd6BVoMQMvfkseCqeZOe1KIiBFmhyk
+E+B2UZcD6Z6kLnCk4LNGyoyxW6Thv5s/lwP9p7trVVbPXbuep1l8uMCGj6vjTD66
+AamEIRmTFvEVHzyO2MGG9V0bM+8UpqPAVFNCXOm6mjCABgkqhkiG9w0BBwEwFAYI
+KoZIhvcNAwcECJ01qtX2EKx6oIAEEM7op+R2U3GQbYwlEj5X+h0AAAAAAAAAAAAA
+");
+ EnvelopedCms cms = new EnvelopedCms();
+ cms.Decode(encrypted);
+
+ RecipientInfoCollection recipientInfos = cms.RecipientInfos;
+
+ Assert.Equal(1, recipientInfos.Count);
+ Assert.Equal(
+ SubjectIdentifierType.IssuerAndSerialNumber,
+ recipientInfos[0].RecipientIdentifier.Type);
+
+ string expectedContentHex = "CEE8A7E4765371906D8C25123E57FA1D";
+
+ if (PlatformDetection.IsFullFramework)
+ {
+ // .NET Framework over-counts encrypted content.
+ expectedContentHex += "000000000000";
+ }
+
+ // Still encrypted.
+ Assert.Equal(
+ expectedContentHex,
+ cms.ContentInfo.Content.ByteArrayToHex());
+ }
+
[Fact]
public static void TestGetContentTypeEnveloped()
{
diff --git a/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs b/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs
index 7d0e1fbe06..8301399913 100644
--- a/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs
+++ b/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedDocuments.cs
@@ -233,6 +233,102 @@ namespace System.Security.Cryptography.Pkcs.Tests
"0CBBC68CE5A4AC671298C0A07C7223522E0E7FFF15CEDBAB55AAA99588517674" +
"671691065EB083FB729D1E9C04B2BF99A9953DAA5E").HexToByteArray();
+ public static byte[] RsaPkcs1TwoCounterSignaturesInSingleAttribute = (
+ "30820BBA06092A864886F70D010702A0820BAB30820BA7020101310D300B0609" +
+ "608648016503040201301406092A864886F70D010701A00704050102030405A0" +
+ "82081D308201583081FFA003020102021035428F3B3C5107AD49E776D6E74C4D" +
+ "C8300A06082A8648CE3D04030230153113301106035504030C0A454344534120" +
+ "54657374301E170D3135303530313030333730335A170D313630353031303035" +
+ "3730335A30153113301106035504030C0A454344534120546573743059301306" +
+ "072A8648CE3D020106082A8648CE3D030107034200047590F69CA114E92927E0" +
+ "34C997B7C882A8C992AC00CEFB4EB831901536F291E1B515263BCD20E1EA3249" +
+ "6FDAC84E2D8D1B703266A9088F6EAF652549D9BB63D5A331302F300E0603551D" +
+ "0F0101FF040403020388301D0603551D0E0416041411218A92C5EB12273B3C5C" +
+ "CFB8220CCCFDF387DB300A06082A8648CE3D040302034800304502201AFE595E" +
+ "19F1AE4B6A4B231E8851926438C55B5DDE632E6ADF13C1023A65898E022100CB" +
+ "DF434FDD197D8B594E8026E44263BADE773C2BEBD060CC4109484A498E7C7E30" +
+ "82032C30820214A003020102020900E0D8AB6819D7306E300D06092A864886F7" +
+ "0D01010B05003038313630340603550403132D54776F2074686F7573616E6420" +
+ "666F7274792065696768742062697473206F662052534120676F6F646E657373" +
+ "301E170D3137313130333233353131355A170D3138313130333233353131355A" +
+ "3038313630340603550403132D54776F2074686F7573616E6420666F72747920" +
+ "65696768742062697473206F662052534120676F6F646E65737330820122300D" +
+ "06092A864886F70D01010105000382010F003082010A028201010096C114A589" +
+ "8D09133EF859F89C1D848BA8CB5258793E05B92D499C55EEFACE274BBBC26803" +
+ "FB813B9C11C6898153CC1745DED2C4D2672F807F0B2D957BC4B65EBC9DDE26E2" +
+ "EA7B2A6FE9A7C4D8BD1EF6032B8F0BB6AA33C8B57248B3D5E3901D8A38A283D7" +
+ "E25FF8E6F522381EE5484234CFF7B30C174635418FA89E14C468AD89DCFCBBB5" +
+ "35E5AF53510F9EA7F9DA8C1B53375B6DAB95A291439A5648726EE1012E41388E" +
+ "100691642CF6917F5569D8351F2782F435A579014E8448EEA0C4AECAFF2F4767" +
+ "99D88457E2C8BCB56E5E128782B4FE26AFF0720D91D52CCAFE344255808F5271" +
+ "D09F784F787E8323182080915BE0AE15A71D66476D0F264DD084F30203010001" +
+ "A3393037301D0603551D0E04160414745B5F12EF962E84B897E246D399A2BADE" +
+ "A9C5AC30090603551D1304023000300B0603551D0F040403020780300D06092A" +
+ "864886F70D01010B0500038201010087A15DF37FBD6E9DED7A8FFF25E60B731F" +
+ "635469BA01DD14BC03B2A24D99EFD8B894E9493D63EC88C496CB04B33DF25222" +
+ "544F23D43F4023612C4D97B719C1F9431E4DB7A580CDF66A3E5F0DAF89A267DD" +
+ "187ABFFB08361B1F79232376AA5FC5AD384CC2F98FE36C1CEA0B943E1E396119" +
+ "0648889C8ABE8397A5A338843CBFB1D8B212BE46685ACE7B80475CC7C97FC037" +
+ "7936ABD5F664E9C09C463897726650711A1110FA9866BC1C278D95E5636AB96F" +
+ "AE95CCD67FD572A8C727E2C03E7B242457318BEC1BE52CA5BD9454A0A41140AE" +
+ "96ED1C56D220D1FD5DD3B1B4FB2AA0E04FC94F7E3C7D476F298962245563953A" +
+ "D7225EDCEAC8B8509E49292E62D8BF3082038D3082034AA003020102020900AB" +
+ "740A714AA83C92300B060960864801650304030230818D310B30090603550406" +
+ "13025553311330110603550408130A57617368696E67746F6E3110300E060355" +
+ "040713075265646D6F6E64311E301C060355040A13154D6963726F736F667420" +
+ "436F72706F726174696F6E3120301E060355040B13172E4E4554204672616D65" +
+ "776F726B2028436F7265465829311530130603550403130C313032342D626974" +
+ "20445341301E170D3135313132353134343030335A170D313531323235313434" +
+ "3030335A30818D310B3009060355040613025553311330110603550408130A57" +
+ "617368696E67746F6E3110300E060355040713075265646D6F6E64311E301C06" +
+ "0355040A13154D6963726F736F667420436F72706F726174696F6E3120301E06" +
+ "0355040B13172E4E4554204672616D65776F726B2028436F7265465829311530" +
+ "130603550403130C313032342D62697420445341308201B73082012C06072A86" +
+ "48CE3804013082011F02818100AEE3309FC7C9DB750D4C3797D333B3B9B234B4" +
+ "62868DB6FFBDED790B7FC8DDD574C2BD6F5E749622507AB2C09DF5EAAD84859F" +
+ "C0706A70BB8C9C8BE22B4890EF2325280E3A7F9A3CE341DBABEF6058D063EA67" +
+ "83478FF8B3B7A45E0CA3F7BAC9995DCFDDD56DF168E91349130F719A4E717351" +
+ "FAAD1A77EAC043611DC5CC5A7F021500D23428A76743EA3B49C62EF0AA17314A" +
+ "85415F0902818100853F830BDAA738465300CFEE02418E6B07965658EAFDA7E3" +
+ "38A2EB1531C0E0CA5EF1A12D9DDC7B550A5A205D1FF87F69500A4E4AF5759F3F" +
+ "6E7F0C48C55396B738164D9E35FB506BD50E090F6A497C70E7E868C61BD4477C" +
+ "1D62922B3DBB40B688DE7C175447E2E826901A109FAD624F1481B276BF63A665" +
+ "D99C87CEE9FD06330381840002818025B8E7078E149BAC352667623620029F5E" +
+ "4A5D4126E336D56F1189F9FF71EA671B844EBD351514F27B69685DDF716B32F1" +
+ "02D60EA520D56F544D19B2F08F5D9BDDA3CBA3A73287E21E559E6A07586194AF" +
+ "AC4F6E721EDCE49DE0029627626D7BD30EEB337311DB4FF62D7608997B6CC32E" +
+ "9C42859820CA7EF399590D5A388C48A330302E302C0603551D11042530238704" +
+ "7F00000187100000000000000000000000000000000182096C6F63616C686F73" +
+ "74300B0609608648016503040302033000302D021500B9316CC7E05C9F79197E" +
+ "0B41F6FD4E3FCEB72A8A0214075505CCAECB18B7EF4C00F9C069FA3BC78014DE" +
+ "3182035A3082035602010130453038313630340603550403132D54776F207468" +
+ "6F7573616E6420666F7274792065696768742062697473206F66205253412067" +
+ "6F6F646E657373020900E0D8AB6819D7306E300B060960864801650304020130" +
+ "0B06092A864886F70D01010104820100457E2996B3A1AE5C7DC2F4EF4D9010F4" +
+ "8B62B72DFB43F2EDC503FD32408A1058EE7BBCF4750CB4B4242B11A599C40792" +
+ "70D32D15A57FF791FF59836A027E634B9B97E1764173597A9A6155D5ED5365F6" +
+ "5DF14FDD15928ABD63E1409DBF2D1A713D20D80E09EE76BC63775F3FA8638A26" +
+ "ED3816FF87C7CDC8A9299485055BFC38AE158BB6577812AA98436FB54844544A" +
+ "C92CD449690B8107447044580FAE590D8A7326A8D139886C8A4AC8CEEACB0458" +
+ "1666D8447D267F1A9E9CAB20F155E05D5EC055AC863C047B5E1E3A98528EA766" +
+ "7C19B33AD98B2D33ABBD7E607C1DA18BCDB87C626554C277E069CE9EC489BC87" +
+ "2E7DEAED4C642DE5AB10BD2D558EAFB3A18201EA308201E606092A864886F70D" +
+ "010906318201D73082010D02010130819B30818D310B30090603550406130255" +
+ "53311330110603550408130A57617368696E67746F6E3110300E060355040713" +
+ "075265646D6F6E64311E301C060355040A13154D6963726F736F667420436F72" +
+ "706F726174696F6E3120301E060355040B13172E4E4554204672616D65776F72" +
+ "6B2028436F7265465829311530130603550403130C313032342D626974204453" +
+ "41020900AB740A714AA83C92300706052B0E03021AA025302306092A864886F7" +
+ "0D0109043116041409200943E2EDD3DD3B186C5839BDC9B1051903FF30090607" +
+ "2A8648CE380403042F302D0215009FDBE95176B1EC0697155ADDF335E5126A9F" +
+ "59D60214736F650C74E73BEA577151BCFD226FEDC06832E53081C30201013029" +
+ "30153113301106035504030C0A45434453412054657374021035428F3B3C5107" +
+ "AD49E776D6E74C4DC8300B0609608648016503040201A031302F06092A864886" +
+ "F70D01090431220420DF5D49DB775A8F94CAB3129038B200EDE9FCD2AE8F039D" +
+ "B1AB96D9B827D299D2300A06082A8648CE3D0403020447304502202327A60E1A" +
+ "5A798CD29B72C7C7991F968D29DB15C4865BEE83A7E2FD73326CA4022100899F" +
+ "000179F77BFE296783548EAE56BA7F53C0DB0563A27A36A149BAEC9C23AC").HexToByteArray();
+
public static readonly byte[] RsaPkcs1CounterSignedWithNoSignature = (
"308203E106092A864886F70D010702A08203D2308203CE020101310B30090605" +
"2B0E03021A0500302406092A864886F70D010701A01704154D6963726F736F66" +
diff --git a/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs b/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs
index e97223c1f7..f2f6559d18 100644
--- a/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs
+++ b/src/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs
@@ -451,6 +451,53 @@ namespace System.Security.Cryptography.Pkcs.Tests
() => signer.RemoveCounterSignature(0));
}
+ [Theory]
+ [InlineData(0)]
+ [InlineData(1)]
+ [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "NetFx bug")]
+ public static void RemoveCounterSignature_EncodedInSingleAttribute_ByIndex(int indexToRemove)
+ {
+ SignedCms cms = new SignedCms();
+ cms.Decode(SignedDocuments.RsaPkcs1TwoCounterSignaturesInSingleAttribute);
+ SignerInfo signerInfo = cms.SignerInfos[0];
+
+ Assert.Equal(2, signerInfo.CounterSignerInfos.Count);
+ signerInfo.RemoveCounterSignature(indexToRemove);
+ Assert.Equal(1, signerInfo.CounterSignerInfos.Count);
+
+ cms.CheckSignature(true);
+
+ byte[] encoded = cms.Encode();
+ cms.Decode(encoded);
+
+ Assert.Equal(1, cms.SignerInfos[0].CounterSignerInfos.Count);
+ cms.CheckSignature(true);
+ }
+
+ [Theory]
+ [InlineData(0)]
+ [InlineData(1)]
+ [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "NetFx bug")]
+ public static void RemoveCounterSignature_EncodedInSingleAttribute_BySignerInfo(int indexToRemove)
+ {
+ SignedCms cms = new SignedCms();
+ cms.Decode(SignedDocuments.RsaPkcs1TwoCounterSignaturesInSingleAttribute);
+ SignerInfo signerInfo = cms.SignerInfos[0];
+
+ SignerInfoCollection counterSigners = signerInfo.CounterSignerInfos;
+ Assert.Equal(2, counterSigners.Count);
+ signerInfo.RemoveCounterSignature(counterSigners[indexToRemove]);
+ Assert.Equal(1, signerInfo.CounterSignerInfos.Count);
+
+ cms.CheckSignature(true);
+
+ byte[] encoded = cms.Encode();
+ cms.Decode(encoded);
+
+ Assert.Equal(1, cms.SignerInfos[0].CounterSignerInfos.Count);
+ cms.CheckSignature(true);
+ }
+
[Fact]
public static void AddCounterSigner_DuplicateCert_RSA()
{
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs
index aa75ae4455..010fe58e55 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificateAssetDownloader.cs
@@ -54,10 +54,16 @@ namespace Internal.Cryptography.Pal
using (SafeBioHandle bio = Interop.Crypto.CreateMemoryBio())
{
+ Interop.Crypto.CheckValidOpenSslHandle(bio);
+
Interop.Crypto.BioWrite(bio, data, data.Length);
handle = Interop.Crypto.PemReadBioX509Crl(bio);
+ // DecodeX509Crl failed, so we need to clear its error.
+ // If PemReadBioX509Crl failed, clear that too.
+ Interop.Crypto.ErrClearError();
+
if (!handle.IsInvalid)
{
return handle;
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs
index 3e843363ec..6a69f24ceb 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CertificatePal.cs
@@ -118,7 +118,10 @@ namespace Internal.Cryptography.Pal
//
// Use BioSeek directly for the last seek attempt, because any failure here should instead
// report the already created (but not yet thrown) exception.
- Interop.Crypto.BioSeek(bio, bioPosition);
+ if (Interop.Crypto.BioSeek(bio, bioPosition) < 0)
+ {
+ Interop.Crypto.ErrClearError();
+ }
Debug.Assert(openSslException != null);
throw openSslException;
@@ -172,7 +175,11 @@ namespace Internal.Cryptography.Pal
{
Interop.Crypto.CheckValidOpenSslHandle(bio);
- Interop.Crypto.BioWrite(bio, rawData, rawData.Length);
+ if (Interop.Crypto.BioWrite(bio, rawData, rawData.Length) != rawData.Length)
+ {
+ Interop.Crypto.ErrClearError();
+ }
+
return TryReadX509Pem(bio, out certPal);
}
}
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs
index ed463f6ec7..fadf117627 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/CrlCache.cs
@@ -52,6 +52,7 @@ namespace Internal.Cryptography.Pal
{
if (bio.IsInvalid)
{
+ Interop.Crypto.ErrClearError();
return false;
}
@@ -61,6 +62,7 @@ namespace Internal.Cryptography.Pal
{
if (crl.IsInvalid)
{
+ Interop.Crypto.ErrClearError();
return false;
}
@@ -144,9 +146,10 @@ namespace Internal.Cryptography.Pal
using (SafeBioHandle bio = Interop.Crypto.BioNewFile(crlFile, "wb"))
{
- if (!bio.IsInvalid)
+ if (bio.IsInvalid || Interop.Crypto.PemWriteBioX509Crl(bio, crl) == 0)
{
- Interop.Crypto.PemWriteBioX509Crl(bio, crl);
+ // No bio, or write failed
+ Interop.Crypto.ErrClearError();
}
}
}
@@ -167,6 +170,11 @@ namespace Internal.Cryptography.Pal
// X509_issuer_name_hash returns "unsigned long", which is marshalled as ulong.
// But it only sets 32 bits worth of data, so force it down to uint just... in case.
ulong persistentHashLong = Interop.Crypto.X509IssuerNameHash(pal.SafeHandle);
+ if (persistentHashLong == 0)
+ {
+ Interop.Crypto.ErrClearError();
+ }
+
uint persistentHash = unchecked((uint)persistentHashLong);
// OpenSSL's hashed filename algorithm is the 8-character hex version of the 32-bit value
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs
index 6a63e9e71c..168ada2980 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/PkcsFormatReader.cs
@@ -30,7 +30,10 @@ namespace Internal.Cryptography.Pal
{
Interop.Crypto.CheckValidOpenSslHandle(bio);
- Interop.Crypto.BioWrite(bio, rawData, rawData.Length);
+ if (Interop.Crypto.BioWrite(bio, rawData, rawData.Length) != rawData.Length)
+ {
+ Interop.Crypto.ErrClearError();
+ }
using (SafePkcs7Handle pkcs7 = Interop.Crypto.PemReadBioPkcs7(bio))
{
@@ -179,7 +182,10 @@ namespace Internal.Cryptography.Pal
{
Interop.Crypto.CheckValidOpenSslHandle(bio);
- Interop.Crypto.BioWrite(bio, rawData, rawData.Length);
+ if (Interop.Crypto.BioWrite(bio, rawData, rawData.Length) != rawData.Length)
+ {
+ Interop.Crypto.ErrClearError();
+ }
return TryReadPkcs7Pem(bio, single, out certPal, out certPals);
}
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs
index a7a5d421f7..3c3cdb20c5 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/StorePal.cs
@@ -120,7 +120,10 @@ namespace Internal.Cryptography.Pal
//
// Use BioSeek directly for the last seek attempt, because any failure here should instead
// report the already created (but not yet thrown) exception.
- Interop.Crypto.BioSeek(bio, bioPosition);
+ if (Interop.Crypto.BioSeek(bio, bioPosition) < 0)
+ {
+ Interop.Crypto.ErrClearError();
+ }
Debug.Assert(openSslException != null);
throw openSslException;
@@ -251,6 +254,8 @@ namespace Internal.Cryptography.Pal
{
using (SafeBioHandle fileBio = Interop.Crypto.BioNewFile(file.FullName, "rb"))
{
+ Interop.Crypto.CheckValidOpenSslHandle(fileBio);
+
ICertificatePal pal;
while (CertificatePal.TryReadX509Pem(fileBio, out pal) ||
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.OpenSslDecode.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.OpenSslDecode.cs
index eeaca53b1f..0c03283475 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.OpenSslDecode.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/X500NameEncoder.OpenSslDecode.cs
@@ -23,6 +23,7 @@ namespace Internal.Cryptography.Pal
{
if (x509Name.IsInvalid)
{
+ Interop.Crypto.ErrClearError();
return "";
}
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CipherReference.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CipherReference.cs
index 079a5d09f7..5dd3dd2968 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CipherReference.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CipherReference.cs
@@ -74,7 +74,8 @@ namespace System.Security.Cryptography.Xml
throw new ArgumentNullException(nameof(value));
ReferenceType = value.LocalName;
- Uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
+ string uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
+ Uri = uri ?? throw new CryptographicException(SR.Cryptography_Xml_UriRequired);
// Transforms
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs
index a857475d3e..d73702fdac 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/CryptoHelpers.cs
@@ -2,15 +2,21 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Diagnostics.CodeAnalysis;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
namespace System.Security.Cryptography.Xml
{
internal static class CryptoHelpers
{
- [SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 needed for compat.")]
- [SuppressMessage("Microsoft.Security", "CA5351", Justification = "HMACMD5 needed for compat.")]
- public static object CreateFromName(string name)
+ private static readonly char[] _invalidChars = new char[] { ',', '`', '[', '*', '&' };
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5350", Justification = "SHA1 needed for compat.")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA5351", Justification = "HMACMD5 needed for compat.")]
+ public static object CreateFromKnownName(string name)
{
switch (name)
{
@@ -73,7 +79,23 @@ namespace System.Security.Cryptography.Xml
return TripleDES.Create();
}
- return CryptoConfig.CreateFromName(name);
+ return null;
+ }
+
+ public static T CreateFromName<T>(string name) where T : class
+ {
+ if (name == null || name.IndexOfAny(_invalidChars) >= 0)
+ {
+ return null;
+ }
+ try
+ {
+ return (CreateFromKnownName(name) ?? CryptoConfig.CreateFromName(name)) as T;
+ }
+ catch (Exception)
+ {
+ return null;
+ }
}
}
}
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs
index 4c74f878f4..ca0ff8d3e8 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/DSASignatureDescription.cs
@@ -20,7 +20,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
- var item = (AsymmetricSignatureDeformatter)CryptoHelpers.CreateFromName(DeformatterAlgorithm);
+ var item = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(HashAlgorithm);
return item;
@@ -28,7 +28,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
- var item = (AsymmetricSignatureFormatter)CryptoHelpers.CreateFromName(FormatterAlgorithm);
+ var item = (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(HashAlgorithm);
return item;
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs
index 4c8b5fddc5..0c92ff1c79 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedReference.cs
@@ -112,7 +112,11 @@ namespace System.Security.Cryptography.Xml
throw new ArgumentNullException(nameof(value));
ReferenceType = value.LocalName;
- Uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
+
+ string uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
+ if (uri == null)
+ throw new ArgumentNullException(SR.Cryptography_Xml_UriRequired);
+ Uri = uri;
// Transforms
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs
index 19202e33b2..574799c281 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/EncryptedXml.cs
@@ -197,21 +197,38 @@ namespace System.Security.Cryptography.Xml
if (cipherData.CipherReference.CipherValue != null)
return cipherData.CipherReference.CipherValue;
Stream decInputStream = null;
+ if (cipherData.CipherReference.Uri == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
+ }
// See if the CipherReference is a local URI
if (cipherData.CipherReference.Uri.Length == 0)
{
// self referenced Uri
string baseUri = (_document == null ? null : _document.BaseURI);
TransformChain tc = cipherData.CipherReference.TransformChain;
+ if (tc == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
+ }
decInputStream = tc.TransformToOctetStream(_document, _xmlResolver, baseUri);
}
else if (cipherData.CipherReference.Uri[0] == '#')
{
string idref = Utils.ExtractIdFromLocalUri(cipherData.CipherReference.Uri);
// Serialize
- inputStream = new MemoryStream(_encoding.GetBytes(GetIdElement(_document, idref).OuterXml));
+ XmlElement idElem = GetIdElement(_document, idref);
+ if (idElem == null || idElem.OuterXml == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
+ }
+ inputStream = new MemoryStream(_encoding.GetBytes(idElem.OuterXml));
string baseUri = (_document == null ? null : _document.BaseURI);
TransformChain tc = cipherData.CipherReference.TransformChain;
+ if (tc == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported);
+ }
decInputStream = tc.TransformToOctetStream(inputStream, _xmlResolver, baseUri);
}
else
@@ -361,7 +378,11 @@ namespace System.Security.Cryptography.Xml
if (key == null)
throw new CryptographicException(SR.Cryptography_Xml_MissingDecryptionKey);
- SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoHelpers.CreateFromName(symmetricAlgorithmUri);
+ SymmetricAlgorithm symAlg = CryptoHelpers.CreateFromName<SymmetricAlgorithm>(symmetricAlgorithmUri);
+ if (symAlg == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
+ }
symAlg.Key = key;
return symAlg;
}
@@ -394,6 +415,10 @@ namespace System.Security.Cryptography.Xml
object kek = _keyNameMapping[keyName];
if (kek != null)
{
+ if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
+ }
// kek is either a SymmetricAlgorithm or an RSA key, otherwise, we wouldn't be able to insert it in the hash table
if (kek is SymmetricAlgorithm)
return EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (SymmetricAlgorithm)kek);
@@ -414,6 +439,10 @@ namespace System.Security.Cryptography.Xml
{
if (privateKey != null)
{
+ if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
+ }
fOAEP = (encryptedKey.EncryptionMethod != null && encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl);
return EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, privateKey, fOAEP);
}
@@ -456,7 +485,16 @@ namespace System.Security.Cryptography.Xml
if (encryptionKey != null)
{
// this is a symmetric algorithm for sure
- SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoHelpers.CreateFromName(encryptedKey.EncryptionMethod.KeyAlgorithm);
+ SymmetricAlgorithm symAlg = CryptoHelpers.CreateFromName<SymmetricAlgorithm>(encryptedKey.EncryptionMethod.KeyAlgorithm);
+ if (symAlg == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
+ }
+ symAlg.Key = encryptionKey;
+ if (encryptedKey.CipherData == null || encryptedKey.CipherData.CipherValue == null)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_MissingAlgorithm);
+ }
symAlg.Key = encryptionKey;
return EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, symAlg);
}
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/KeyInfo.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/KeyInfo.cs
index 50ca8a5803..d69b0ef864 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/KeyInfo.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/KeyInfo.cs
@@ -71,6 +71,8 @@ namespace System.Security.Cryptography.Xml
XmlElement keyInfoElement = value;
_id = Utils.GetAttribute(keyInfoElement, "Id", SignedXml.XmlDsigNamespaceUrl);
+ if (!Utils.VerifyAttributes(keyInfoElement, "Id"))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo");
XmlNode child = keyInfoElement.FirstChild;
while (child != null)
@@ -83,6 +85,10 @@ namespace System.Security.Cryptography.Xml
// Special-case handling for KeyValue -- we have to go one level deeper
if (kicString == "http://www.w3.org/2000/09/xmldsig# KeyValue")
{
+ if (!Utils.VerifyAttributes(elem, (string[])null))
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo/KeyValue");
+ }
XmlNodeList nodeList2 = elem.ChildNodes;
foreach (XmlNode node2 in nodeList2)
{
@@ -94,7 +100,8 @@ namespace System.Security.Cryptography.Xml
}
}
}
- KeyInfoClause keyInfoClause = (KeyInfoClause)CryptoHelpers.CreateFromName(kicString);
+
+ KeyInfoClause keyInfoClause = CryptoHelpers.CreateFromName<KeyInfoClause>(kicString);
// if we don't know what kind of KeyInfoClause we're looking at, use a generic KeyInfoNode:
if (keyInfoClause == null)
keyInfoClause = new KeyInfoNode();
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs
index 2fc6a3d810..ab37fbd98e 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/RSAPKCS1SignatureDescription.cs
@@ -16,7 +16,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
{
- var item = (AsymmetricSignatureDeformatter)CryptoHelpers.CreateFromName(DeformatterAlgorithm);
+ var item = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(DigestAlgorithm);
return item;
@@ -24,7 +24,7 @@ namespace System.Security.Cryptography.Xml
public sealed override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
{
- var item = (AsymmetricSignatureFormatter)CryptoHelpers.CreateFromName(FormatterAlgorithm);
+ var item = (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
item.SetKey(key);
item.SetHashAlgorithm(DigestAlgorithm);
return item;
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs
index a34d3d492c..b608cf077a 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Reference.cs
@@ -219,25 +219,52 @@ namespace System.Security.Cryptography.Xml
_id = Utils.GetAttribute(value, "Id", SignedXml.XmlDsigNamespaceUrl);
_uri = Utils.GetAttribute(value, "URI", SignedXml.XmlDsigNamespaceUrl);
_type = Utils.GetAttribute(value, "Type", SignedXml.XmlDsigNamespaceUrl);
+ if (!Utils.VerifyAttributes(value, new string[] { "Id", "URI", "Type" }))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference");
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
// Transforms
+ bool hasTransforms = false;
TransformChain = new TransformChain();
- XmlElement transformsElement = value.SelectSingleNode("ds:Transforms", nsm) as XmlElement;
- if (transformsElement != null)
+ XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm);
+ if (transformsNodes != null && transformsNodes.Count != 0)
{
+ if (transformsNodes.Count > 1)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms");
+ }
+ hasTransforms = true;
+ XmlElement transformsElement = transformsNodes[0] as XmlElement;
+ if (!Utils.VerifyAttributes(transformsElement, (string[])null))
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms");
+ }
XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm);
if (transformNodes != null)
{
+ if (transformNodes.Count != transformsElement.SelectNodes("*").Count)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms");
+ }
+ if (transformNodes.Count > Utils.MaxTransformsPerReference)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms");
+ }
foreach (XmlNode transformNode in transformNodes)
{
XmlElement transformElement = transformNode as XmlElement;
string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
- Transform transform = CryptoHelpers.CreateFromName(algorithm) as Transform;
+ if (algorithm == null || !Utils.VerifyAttributes(transformElement, "Algorithm"))
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
+ Transform transform = CryptoHelpers.CreateFromName<Transform>(algorithm);
if (transform == null)
+ {
throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
AddTransform(transform);
// let the transform read the children of the transformElement for data
transform.LoadInnerXml(transformElement.ChildNodes);
@@ -267,16 +294,27 @@ namespace System.Security.Cryptography.Xml
}
// DigestMethod
- XmlElement digestMethodElement = value.SelectSingleNode("ds:DigestMethod", nsm) as XmlElement;
- if (digestMethodElement == null)
+ XmlNodeList digestMethodNodes = value.SelectNodes("ds:DigestMethod", nsm);
+ if (digestMethodNodes == null || digestMethodNodes.Count == 0 || digestMethodNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod");
+ XmlElement digestMethodElement = digestMethodNodes[0] as XmlElement;
_digestMethod = Utils.GetAttribute(digestMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
+ if (_digestMethod == null || !Utils.VerifyAttributes(digestMethodElement, "Algorithm"))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod");
+
// DigestValue
- XmlElement digestValueElement = value.SelectSingleNode("ds:DigestValue", nsm) as XmlElement;
- if (digestValueElement == null)
+ XmlNodeList digestValueNodes = value.SelectNodes("ds:DigestValue", nsm);
+ if (digestValueNodes == null || digestValueNodes.Count == 0 || digestValueNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue");
+ XmlElement digestValueElement = digestValueNodes[0] as XmlElement;
_digestValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(digestValueElement.InnerText));
+ if (!Utils.VerifyAttributes(digestValueElement, (string[])null))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue");
+ // Verify that there aren't any extra nodes that aren't allowed
+ int expectedChildNodeCount = hasTransforms ? 3 : 2;
+ if (value.SelectNodes("*").Count != expectedChildNodeCount)
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference");
// cache the Xml
_cachedXml = value;
@@ -304,7 +342,7 @@ namespace System.Security.Cryptography.Xml
{
// refList is a list of elements that might be targets of references
// Now's the time to create our hashing algorithm
- _hashAlgorithm = CryptoHelpers.CreateFromName(_digestMethod) as HashAlgorithm;
+ _hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(_digestMethod);
if (_hashAlgorithm == null)
throw new CryptographicException(SR.Cryptography_Xml_CreateHashAlgorithmFailed);
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Signature.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Signature.cs
index e023d983f5..d755de9e73 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Signature.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Signature.cs
@@ -148,37 +148,53 @@ namespace System.Security.Cryptography.Xml
// Id attribute -- optional
_id = Utils.GetAttribute(signatureElement, "Id", SignedXml.XmlDsigNamespaceUrl);
+ if (!Utils.VerifyAttributes(signatureElement, "Id"))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Signature");
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
+ int expectedChildNodes = 0;
// SignedInfo
- XmlElement signedInfoElement = signatureElement.SelectSingleNode("ds:SignedInfo", nsm) as XmlElement;
- if (signedInfoElement == null)
+ XmlNodeList signedInfoNodes = signatureElement.SelectNodes("ds:SignedInfo", nsm);
+ if (signedInfoNodes == null || signedInfoNodes.Count == 0 || signedInfoNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo");
+ XmlElement signedInfoElement = signedInfoNodes[0] as XmlElement;
+ expectedChildNodes += signedInfoNodes.Count;
SignedInfo = new SignedInfo();
SignedInfo.LoadXml(signedInfoElement);
// SignatureValue
- XmlElement signatureValueElement = signatureElement.SelectSingleNode("ds:SignatureValue", nsm) as XmlElement;
- if (signatureValueElement == null)
- throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/SignatureValue");
+ XmlNodeList signatureValueNodes = signatureElement.SelectNodes("ds:SignatureValue", nsm);
+ if (signatureValueNodes == null || signatureValueNodes.Count == 0 || signatureValueNodes.Count > 1)
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignatureValue");
+ XmlElement signatureValueElement = signatureValueNodes[0] as XmlElement;
+ expectedChildNodes += signatureValueNodes.Count;
_signatureValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(signatureValueElement.InnerText));
_signatureValueId = Utils.GetAttribute(signatureValueElement, "Id", SignedXml.XmlDsigNamespaceUrl);
+ if (!Utils.VerifyAttributes(signatureValueElement, "Id"))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignatureValue");
+ // KeyInfo - optional single element
XmlNodeList keyInfoNodes = signatureElement.SelectNodes("ds:KeyInfo", nsm);
_keyInfo = new KeyInfo();
if (keyInfoNodes != null)
{
+ if (keyInfoNodes.Count > 1)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfo");
+ }
foreach (XmlNode node in keyInfoNodes)
{
XmlElement keyInfoElement = node as XmlElement;
if (keyInfoElement != null)
_keyInfo.LoadXml(keyInfoElement);
}
+ expectedChildNodes += keyInfoNodes.Count;
}
+ // Object - zero or more elements allowed
XmlNodeList objectNodes = signatureElement.SelectNodes("ds:Object", nsm);
_embeddedObjects.Clear();
if (objectNodes != null)
@@ -193,6 +209,7 @@ namespace System.Security.Cryptography.Xml
_embeddedObjects.Add(dataObj);
}
}
+ expectedChildNodes += objectNodes.Count;
}
// Select all elements that have Id attributes
@@ -204,6 +221,11 @@ namespace System.Security.Cryptography.Xml
_referencedItems.Add(node);
}
}
+ // Verify that there aren't any extra nodes that aren't allowed
+ if (signatureElement.SelectNodes("*").Count != expectedChildNodes)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Signature");
+ }
}
public void AddObject(DataObject dataObject)
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedInfo.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedInfo.cs
index 30408790d4..f87416ec5a 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedInfo.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedInfo.cs
@@ -98,7 +98,7 @@ namespace System.Security.Cryptography.Xml
{
if (_canonicalizationMethodTransform == null)
{
- _canonicalizationMethodTransform = CryptoHelpers.CreateFromName(CanonicalizationMethod) as Transform;
+ _canonicalizationMethodTransform = CryptoHelpers.CreateFromName<Transform>(CanonicalizationMethod);
if (_canonicalizationMethodTransform == null)
throw new CryptographicException(string.Format(CultureInfo.CurrentCulture, SR.Cryptography_Xml_CreateTransformFailed, CanonicalizationMethod));
_canonicalizationMethodTransform.SignedXml = SignedXml;
@@ -213,24 +213,35 @@ namespace System.Security.Cryptography.Xml
XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
+ int expectedChildNodes = 0;
// Id attribute -- optional
_id = Utils.GetAttribute(signedInfoElement, "Id", SignedXml.XmlDsigNamespaceUrl);
+ if (!Utils.VerifyAttributes(signedInfoElement, "Id"))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo");
// CanonicalizationMethod -- must be present
- XmlElement canonicalizationMethodElement = signedInfoElement.SelectSingleNode("ds:CanonicalizationMethod", nsm) as XmlElement;
- if (canonicalizationMethodElement == null)
+ XmlNodeList canonicalizationMethodNodes = signedInfoElement.SelectNodes("ds:CanonicalizationMethod", nsm);
+ if (canonicalizationMethodNodes == null || canonicalizationMethodNodes.Count == 0 || canonicalizationMethodNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/CanonicalizationMethod");
+ XmlElement canonicalizationMethodElement = canonicalizationMethodNodes.Item(0) as XmlElement;
+ expectedChildNodes += canonicalizationMethodNodes.Count;
_canonicalizationMethod = Utils.GetAttribute(canonicalizationMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
+ if (_canonicalizationMethod == null || !Utils.VerifyAttributes(canonicalizationMethodElement, "Algorithm"))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/CanonicalizationMethod");
_canonicalizationMethodTransform = null;
if (canonicalizationMethodElement.ChildNodes.Count > 0)
CanonicalizationMethodObject.LoadInnerXml(canonicalizationMethodElement.ChildNodes);
// SignatureMethod -- must be present
- XmlElement signatureMethodElement = signedInfoElement.SelectSingleNode("ds:SignatureMethod", nsm) as XmlElement;
- if (signatureMethodElement == null)
+ XmlNodeList signatureMethodNodes = signedInfoElement.SelectNodes("ds:SignatureMethod", nsm);
+ if (signatureMethodNodes == null || signatureMethodNodes.Count == 0 || signatureMethodNodes.Count > 1)
throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/SignatureMethod");
+ XmlElement signatureMethodElement = signatureMethodNodes.Item(0) as XmlElement;
+ expectedChildNodes += signatureMethodNodes.Count;
_signatureMethod = Utils.GetAttribute(signatureMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
+ if (_signatureMethod == null || !Utils.VerifyAttributes(signatureMethodElement, "Algorithm"))
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/SignatureMethod");
// Now get the output length if we are using a MAC algorithm
XmlElement signatureLengthElement = signatureMethodElement.SelectSingleNode("ds:HMACOutputLength", nsm) as XmlElement;
@@ -240,9 +251,14 @@ namespace System.Security.Cryptography.Xml
// flush out any reference that was there
_references.Clear();
+ // Reference - 0 or more
XmlNodeList referenceNodes = signedInfoElement.SelectNodes("ds:Reference", nsm);
if (referenceNodes != null)
{
+ if (referenceNodes.Count > Utils.MaxReferencesPerSignedInfo)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo/Reference");
+ }
foreach (XmlNode node in referenceNodes)
{
XmlElement referenceElement = node as XmlElement;
@@ -250,6 +266,12 @@ namespace System.Security.Cryptography.Xml
AddReference(reference);
reference.LoadXml(referenceElement);
}
+ expectedChildNodes += referenceNodes.Count;
+ // Verify that there aren't any extra nodes that aren't allowed
+ if (signedInfoElement.SelectNodes("*").Count != expectedChildNodes)
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "SignedInfo");
+ }
}
// Save away the cached value
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs
index dfe3774358..b90f3fdd2f 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs
@@ -410,7 +410,7 @@ namespace System.Security.Cryptography.Xml
}
// See if there is a signature description class defined in the Config file
- SignatureDescription signatureDescription = CryptoHelpers.CreateFromName(SignedInfo.SignatureMethod) as SignatureDescription;
+ SignatureDescription signatureDescription = CryptoHelpers.CreateFromName<SignatureDescription>(SignedInfo.SignatureMethod);
if (signatureDescription == null)
throw new CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated);
HashAlgorithm hashAlg = signatureDescription.CreateDigest();
@@ -653,7 +653,7 @@ namespace System.Security.Cryptography.Xml
}
// See if we're signed witn an HMAC algorithm
- HMAC hmac = CryptoHelpers.CreateFromName(SignatureMethod) as HMAC;
+ HMAC hmac = CryptoHelpers.CreateFromName<HMAC>(SignatureMethod);
if (hmac == null)
{
// We aren't signed with an HMAC algorithm, so we cannot have a truncated HMAC
@@ -1017,7 +1017,7 @@ namespace System.Security.Cryptography.Xml
SignedXmlDebugLog.LogBeginCheckSignedInfo(this, m_signature.SignedInfo);
- SignatureDescription signatureDescription = CryptoHelpers.CreateFromName(SignatureMethod) as SignatureDescription;
+ SignatureDescription signatureDescription = CryptoHelpers.CreateFromName<SignatureDescription>(SignatureMethod);
if (signatureDescription == null)
throw new CryptographicException(SR.Cryptography_Xml_SignatureDescriptionNotCreated);
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs
index 299b8804de..ae678857a6 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs
@@ -698,6 +698,8 @@ namespace System.Security.Cryptography.Xml
if (VerboseLoggingEnabled)
{
+ HashAlgorithm hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(reference.DigestMethod);
+ string hashAlgorithmName = hashAlgorithm == null ? "null" : hashAlgorithm.GetType().Name;
string logMessage = string.Format(CultureInfo.InvariantCulture,
SR.Log_SigningReference,
GetObjectId(reference),
@@ -705,7 +707,7 @@ namespace System.Security.Cryptography.Xml
reference.Id,
reference.Type,
reference.DigestMethod,
- CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name);
+ hashAlgorithmName);
WriteLine(signedXml,
TraceEventType.Verbose,
@@ -831,11 +833,13 @@ namespace System.Security.Cryptography.Xml
if (VerboseLoggingEnabled)
{
+ HashAlgorithm hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(reference.DigestMethod);
+ string hashAlgorithmName = hashAlgorithm == null ? "null" : hashAlgorithm.GetType().Name;
string logMessage = string.Format(CultureInfo.InvariantCulture,
SR.Log_ReferenceHash,
GetObjectId(reference),
reference.DigestMethod,
- CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name,
+ hashAlgorithmName,
FormatBytes(actualHash),
FormatBytes(expectedHash));
@@ -1043,11 +1047,13 @@ namespace System.Security.Cryptography.Xml
if (InformationLoggingEnabled)
{
+ HashAlgorithm hashAlgorithm = CryptoHelpers.CreateFromName<HashAlgorithm>(reference.DigestMethod);
+ string hashAlgorithmName = hashAlgorithm == null ? "null" : hashAlgorithm.GetType().Name;
string logMessage = string.Format(CultureInfo.InvariantCulture,
SR.Log_SignedXmlRecursionLimit,
GetObjectId(reference),
reference.DigestMethod,
- CryptoHelpers.CreateFromName(reference.DigestMethod).GetType().Name);
+ hashAlgorithmName);
WriteLine(signedXml,
TraceEventType.Information,
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/TransformChain.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/TransformChain.cs
index 7c2530da77..3242910a3e 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/TransformChain.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/TransformChain.cs
@@ -200,7 +200,7 @@ namespace System.Security.Cryptography.Xml
{
XmlElement transformElement = (XmlElement)transformNodes.Item(i);
string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl);
- Transform transform = CryptoHelpers.CreateFromName(algorithm) as Transform;
+ Transform transform = CryptoHelpers.CreateFromName<Transform>(algorithm);
if (transform == null)
throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
// let the transform read the children of the transformElement for data
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs
index 0ec93ebdbe..4f0608c708 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/Utils.cs
@@ -81,6 +81,29 @@ namespace System.Security.Cryptography.Xml
return element.HasAttribute(localName) || element.HasAttribute(localName, namespaceURI);
}
+ internal static bool VerifyAttributes(XmlElement element, string expectedAttrName)
+ {
+ return VerifyAttributes(element, expectedAttrName == null ? null : new string[] { expectedAttrName });
+ }
+
+ internal static bool VerifyAttributes(XmlElement element, string[] expectedAttrNames)
+ {
+ foreach (XmlAttribute attr in element.Attributes)
+ {
+ // There are a few Xml Special Attributes that are always allowed on any node. Make sure we allow those here.
+ bool attrIsAllowed = attr.Name == "xmlns" || attr.Name.StartsWith("xmlns:") || attr.Name == "xml:space" || attr.Name == "xml:lang" || attr.Name == "xml:base";
+ int expectedInd = 0;
+ while (!attrIsAllowed && expectedAttrNames != null && expectedInd < expectedAttrNames.Length)
+ {
+ attrIsAllowed = attr.Name == expectedAttrNames[expectedInd];
+ expectedInd++;
+ }
+ if (!attrIsAllowed)
+ return false;
+ }
+ return true;
+ }
+
internal static bool IsNamespaceNode(XmlNode n)
{
return n.NodeType == XmlNodeType.Attribute && (n.Prefix.Equals("xmlns") || (n.Prefix.Length == 0 && n.LocalName.Equals("xmlns")));
@@ -774,5 +797,8 @@ namespace System.Security.Cryptography.Xml
{
return (AsymmetricAlgorithm)certificate.GetRSAPublicKey();
}
+
+ internal const int MaxTransformsPerReference = 10;
+ internal const int MaxReferencesPerSignedInfo = 100;
}
}
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDecryptionTransform.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDecryptionTransform.cs
index 7e6fb6a3f3..d721fb6fea 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDecryptionTransform.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDecryptionTransform.cs
@@ -98,14 +98,25 @@ namespace System.Security.Cryptography.Xml
foreach (XmlNode node in nodeList)
{
XmlElement elem = node as XmlElement;
- if (elem != null && elem.LocalName == "Except" && elem.NamespaceURI == XmlDecryptionTransformNamespaceUrl)
+ if (elem != null)
{
- // the Uri is required
- string uri = Utils.GetAttribute(elem, "URI", XmlDecryptionTransformNamespaceUrl);
- if (uri == null || uri.Length == 0 || uri[0] != '#')
- throw new CryptographicException(SR.Cryptography_Xml_UriRequired);
- string idref = Utils.ExtractIdFromLocalUri(uri);
- ExceptUris.Add(idref);
+ if (elem.LocalName == "Except" && elem.NamespaceURI == XmlDecryptionTransformNamespaceUrl)
+ {
+ // the Uri is required
+ string uri = Utils.GetAttribute(elem, "URI", XmlDecryptionTransformNamespaceUrl);
+ if (uri == null || uri.Length == 0 || uri[0] != '#')
+ throw new CryptographicException(SR.Cryptography_Xml_UriRequired);
+ if (!Utils.VerifyAttributes(elem, "URI"))
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
+ string idref = Utils.ExtractIdFromLocalUri(uri);
+ ExceptUris.Add(idref);
+ }
+ else
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
}
}
}
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigC14NTransform.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigC14NTransform.cs
index 0a67878804..b03d8424f1 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigC14NTransform.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigC14NTransform.cs
@@ -42,7 +42,11 @@ namespace System.Security.Cryptography.Xml
get { return _outputTypes; }
}
- public override void LoadInnerXml(XmlNodeList nodeList) { }
+ public override void LoadInnerXml(XmlNodeList nodeList)
+ {
+ if (nodeList != null && nodeList.Count > 0)
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
protected override XmlNodeList GetInnerXml()
{
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigEnvelopedSignatureTransform.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigEnvelopedSignatureTransform.cs
index 15dae41c9c..d1d98ed331 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigEnvelopedSignatureTransform.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigEnvelopedSignatureTransform.cs
@@ -52,7 +52,11 @@ namespace System.Security.Cryptography.Xml
}
// An enveloped signature has no inner XML elements
- public override void LoadInnerXml(XmlNodeList nodeList) { }
+ public override void LoadInnerXml(XmlNodeList nodeList)
+ {
+ if (nodeList != null && nodeList.Count > 0)
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
// An enveloped signature has no inner XML elements
protected override XmlNodeList GetInnerXml()
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigExcC14NTransform.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigExcC14NTransform.cs
index f861c5ff31..44373ee12a 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigExcC14NTransform.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigExcC14NTransform.cs
@@ -58,12 +58,23 @@ namespace System.Security.Cryptography.Xml
foreach (XmlNode n in nodeList)
{
XmlElement e = n as XmlElement;
- if (e != null && e.LocalName.Equals("InclusiveNamespaces") &&
- e.NamespaceURI.Equals(SignedXml.XmlDsigExcC14NTransformUrl) &&
- Utils.HasAttribute(e, "PrefixList", SignedXml.XmlDsigNamespaceUrl))
+ if (e != null)
{
- InclusiveNamespacesPrefixList = Utils.GetAttribute(e, "PrefixList", SignedXml.XmlDsigNamespaceUrl);
- return;
+ if (e.LocalName.Equals("InclusiveNamespaces")
+ && e.NamespaceURI.Equals(SignedXml.XmlDsigExcC14NTransformUrl) &&
+ Utils.HasAttribute(e, "PrefixList", SignedXml.XmlDsigNamespaceUrl))
+ {
+ if (!Utils.VerifyAttributes(e, "PrefixList"))
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
+ this.InclusiveNamespacesPrefixList = Utils.GetAttribute(e, "PrefixList", SignedXml.XmlDsigNamespaceUrl);
+ return;
+ }
+ else
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
}
}
}
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigXPathTransform.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigXPathTransform.cs
index 07c02d7c68..48812b908f 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigXPathTransform.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlDsigXPathTransform.cs
@@ -50,28 +50,39 @@ namespace System.Security.Cryptography.Xml
string prefix = null;
string namespaceURI = null;
XmlElement elem = node as XmlElement;
- if ((elem != null) && (elem.LocalName == "XPath"))
+ if (elem != null)
{
- _xpathexpr = elem.InnerXml.Trim(null);
- XmlNodeReader nr = new XmlNodeReader(elem);
- XmlNameTable nt = nr.NameTable;
- _nsm = new XmlNamespaceManager(nt);
- // Look for a namespace in the attributes
- foreach (XmlAttribute attrib in elem.Attributes)
+ if (elem.LocalName == "XPath")
{
- if (attrib.Prefix == "xmlns")
+ _xpathexpr = elem.InnerXml.Trim(null);
+ XmlNodeReader nr = new XmlNodeReader(elem);
+ XmlNameTable nt = nr.NameTable;
+ _nsm = new XmlNamespaceManager(nt);
+ if (!Utils.VerifyAttributes(elem, (string)null))
{
- prefix = attrib.LocalName;
- namespaceURI = attrib.Value;
- if (prefix == null)
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
+ // Look for a namespace in the attributes
+ foreach (XmlAttribute attrib in elem.Attributes)
+ {
+ if (attrib.Prefix == "xmlns")
{
- prefix = elem.Prefix;
- namespaceURI = elem.NamespaceURI;
+ prefix = attrib.LocalName;
+ namespaceURI = attrib.Value;
+ if (prefix == null)
+ {
+ prefix = elem.Prefix;
+ namespaceURI = elem.NamespaceURI;
+ }
+ _nsm.AddNamespace(prefix, namespaceURI);
}
- _nsm.AddNamespace(prefix, namespaceURI);
}
+ break;
+ }
+ else
+ {
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
}
- break;
}
}
diff --git a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlLicenseTransform.cs b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlLicenseTransform.cs
index bb1f49201b..0c45f2627b 100644
--- a/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlLicenseTransform.cs
+++ b/src/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/XmlLicenseTransform.cs
@@ -132,7 +132,11 @@ namespace System.Security.Cryptography.Xml
}
// License transform has no inner XML elements
- public override void LoadInnerXml(XmlNodeList nodeList) { }
+ public override void LoadInnerXml(XmlNodeList nodeList)
+ {
+ if (nodeList != null && nodeList.Count > 0)
+ throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform);
+ }
public override void LoadInput(object obj)
{
diff --git a/src/System.Security.Cryptography.Xml/tests/Configurations.props b/src/System.Security.Cryptography.Xml/tests/Configurations.props
index 3e1323e176..ea9ea79f78 100644
--- a/src/System.Security.Cryptography.Xml/tests/Configurations.props
+++ b/src/System.Security.Cryptography.Xml/tests/Configurations.props
@@ -2,7 +2,8 @@
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildConfigurations>
- netstandard
+ netcoreapp;
+ netstandard;
</BuildConfigurations>
</PropertyGroup>
</Project>
diff --git a/src/System.Security.Cryptography.Xml/tests/KeyInfo_ArbitraryElements.cs b/src/System.Security.Cryptography.Xml/tests/KeyInfo_ArbitraryElements.cs
new file mode 100644
index 0000000000..a05b09eb0e
--- /dev/null
+++ b/src/System.Security.Cryptography.Xml/tests/KeyInfo_ArbitraryElements.cs
@@ -0,0 +1,33 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml;
+using Xunit;
+
+namespace System.Security.Cryptography.Xml.Tests
+{
+ public class KeyInfo_ArbitraryElements
+ {
+ [Fact]
+ public static void ExtraData()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo>{arbitraryData}<KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.True(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void ExtraAttributes()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo extraAttr=""""><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void KeyValue_ExtraAttributes()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue extraAttr=""""><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Xml/tests/Reference_ArbitraryElements.cs b/src/System.Security.Cryptography.Xml/tests/Reference_ArbitraryElements.cs
new file mode 100644
index 0000000000..8a1f86daef
--- /dev/null
+++ b/src/System.Security.Cryptography.Xml/tests/Reference_ArbitraryElements.cs
@@ -0,0 +1,156 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml;
+using Xunit;
+
+namespace System.Security.Cryptography.Xml.Tests
+{
+ public class Reference_ArbitraryElements
+ {
+ [Fact]
+ public static void ExtraData()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI="""">{arbitraryData}<Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void OutOfOrder()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void DuplicateTransforms()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><Transforms>{arbitraryData}</Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void Transforms_ExtraData()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/>{arbitraryData}<Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void Transforms_ExtraData_CData_Text()
+ {
+ string arbitraryData = @"text";
+
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+<a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/>{arbitraryData}<Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void Transforms_ExtraData_XmlNotation()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+<a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><notation id='Transforms' name='Transforms' public='Transforms' system='Transforms' /><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void Transforms_ExtraData_XmlProcessingInstruction()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+<a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><?Transforms name='Transforms' ?><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void Transforms_ExtraAttributes()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms extraAttr=""""><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void DuplicateDigestMethod()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI="""">{arbitraryData}<Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestMethod>{arbitraryData}</DigestMethod><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void DuplicateDigestValue()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI="""">{arbitraryData}<Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue><DigestValue>{arbitraryData}</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes()
+ {
+ foreach (string includeID in new string[] { "", $@" Id=""""" })
+ foreach (string includeURI in new string[] { "", $@" URI=""""" })
+ foreach (string includeType in new string[] { "", $@" Type=""""" })
+ foreach (string includeExtra in new string[] { "", $@" extraattr=""cat""" })
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference{includeID}{includeURI}{includeExtra}{includeType}><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.Equal((includeExtra == "" && includeID == "" && includeURI != "" && includeType == ""), Helpers.VerifyCryptoExceptionOnLoad(xml, includeExtra != ""));
+ }
+ }
+
+ [Fact]
+ public static void DuplicateLegalAttributes()
+ {
+ foreach (string includeID in new string[] { "", $@" Id=""""", $@" Id="""" Id=""""" })
+ foreach (string includeURI in new string[] { "", $@" URI=""""", $@" URI="""" URI=""""" })
+ foreach (string includeType in new string[] { "", $@" Type=""""", $@" Type="""" Type=""""" })
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference{includeID}{includeURI}{includeType}><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ bool throwsXmlException = includeID.LastIndexOf("I") != includeID.IndexOf("I") || includeURI.LastIndexOf("U") != includeURI.IndexOf("U") || includeType.LastIndexOf("T") != includeType.IndexOf("T");
+ if (throwsXmlException)
+ Assert.Throws<XmlException>(() => Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ else
+ Assert.Equal(includeID == "" && includeURI != "" && includeType == "", Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+ }
+
+ [Fact]
+ public static void MissingAttribute_Transform()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue><DigestValue>{arbitraryData}</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Helpers.VerifyCryptoExceptionOnLoad(xml, true);
+ }
+
+ [Fact]
+ public static void ExtraAttribute_Transform()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""><Transform/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315"" extraattr=""""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue><DigestValue>{arbitraryData}</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Helpers.VerifyCryptoExceptionOnLoad(xml, true);
+ }
+
+ [Fact]
+ public static void MissingAttribute_DigestMethod()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod /><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue><DigestValue>{arbitraryData}</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Helpers.VerifyCryptoExceptionOnLoad(xml, true);
+ }
+
+ [Fact]
+ public static void ExtraAttribute_DigestMethod()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""><Transform/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1"" extraattr=""""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue><DigestValue>{arbitraryData}</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Helpers.VerifyCryptoExceptionOnLoad(xml, true);
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Xml/tests/Signature_ArbitraryElements.cs b/src/System.Security.Cryptography.Xml/tests/Signature_ArbitraryElements.cs
new file mode 100644
index 0000000000..eae7bac6bc
--- /dev/null
+++ b/src/System.Security.Cryptography.Xml/tests/Signature_ArbitraryElements.cs
@@ -0,0 +1,153 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml;
+using Xunit;
+
+namespace System.Security.Cryptography.Xml.Tests
+{
+ public class Signature_ArbitraryElements
+ {
+ [Fact]
+ public static void CorrectAttributes()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" Id=""id""><SignedInfo Id=""id""><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI="""" Id="""" Type=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue Id=""ID"">Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo Id=""ID""><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void DoubleSameAttribute_ID()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" Id=""id"" Id=""id""><SignedInfo Id=""id""><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI="""" Id="""" Type=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue Id=""ID"">Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo Id=""ID""><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.Throws<XmlException>(() => Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void DifferentSignatureXMLNS()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<ds:Signature xmlns:ds=""http://www.w3.org/2000/09/xmldsig#""><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><ds:SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><ds:Reference URI=""""><ds:Transforms><ds:Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><ds:Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></ds:Transforms><ds:DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><ds:DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</ds:SignatureValue><ds:KeyInfo><ds:KeyValue><ds:RSAKeyValue><ds:Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</ds:Modulus><ds:Exponent>AQAB</ds:Exponent></ds:RSAKeyValue></ds:KeyValue></ds:KeyInfo></ds:Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void ExtraAttributes()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" randomattr=""random""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_WeirdXMLNS()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" xmlns:lsj=""http://www.w3.org/2000/09/xmldsig#"" xmlns:fld=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.True(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_Preserve()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+<a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" xml:space=""preserve""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.True(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_Preserve_PlusExtraData()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+<a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" xml:space=""preserve""><a:tst xmlns:a=""mynamespace""> i ss u e</a:tst><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_Lang()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+ <a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" xml:lang='en'><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.True(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_Base()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+ <a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"" xml:base='en'><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.True(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_DigestValueWhenMissingDigestValue()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<ds:Signature xmlns:ds=""http://www.w3.org/2000/09/xmldsig#""><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><ds:SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><ds:Reference ds:DigestValue=""value"" URI=""""><ds:Transforms><ds:Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><ds:Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></ds:Transforms><ds:DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/></ds:Reference></ds:SignedInfo><ds:SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</ds:SignatureValue><ds:KeyInfo><ds:KeyValue><ds:RSAKeyValue><ds:Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</ds:Modulus><ds:Exponent>AQAB</ds:Exponent></ds:RSAKeyValue></ds:KeyValue></ds:KeyInfo></ds:Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_ExtraFirst()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature randomattr=""random"" xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_SignatureValue()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue randomattr=""random"">Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Theory]
+ [InlineData(@"<a:foo xmlns:a=""mynamespace"">lol</a:foo>", false, true)] // Element
+ [InlineData(@"<![CDATA[some stuff]]>", true, false)] //CData_CDataSection
+ [InlineData(@"<!-- comment -->", true, false)] //CData_Comment
+ [InlineData(@" ", true, false)] //CData_Whitespace
+ [InlineData(@"this", true, false)] //CData_Text
+ [InlineData(@"&amp;", true, false)] //EntityReference
+ [InlineData(@"<?xml-stylesheet type='text / xsl' href='style.xsl'?>", true, false)] //EntityReference
+ [InlineData(@"<?xml-stylesheet type='text / xsl' href='style.xsl'?>", true, false)] //EntityReference
+
+ public static void ExtraData(string arbitraryData, bool checkSignatureSucceeds, bool loadThrows)
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+ <a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#"">{arbitraryData}<SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ Assert.Equal(checkSignatureSucceeds, Helpers.VerifyCryptoExceptionOnLoad(xml, loadThrows));
+ }
+
+ [Fact]
+ public static void OutOfOrder()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.True(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void DuplicateSignedInfo()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignedInfo>{arbitraryData}</SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void DuplicateSignatureValue()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><SignatureValue>{arbitraryData}</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void DuplicateKeyInfo()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo><KeyInfo>{arbitraryData}</KeyInfo><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Xml/tests/SignedInfo_ArbitraryElements.cs b/src/System.Security.Cryptography.Xml/tests/SignedInfo_ArbitraryElements.cs
new file mode 100644
index 0000000000..9c6b03b078
--- /dev/null
+++ b/src/System.Security.Cryptography.Xml/tests/SignedInfo_ArbitraryElements.cs
@@ -0,0 +1,81 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml;
+using Xunit;
+
+namespace System.Security.Cryptography.Xml.Tests
+{
+ public class SignedInfo_ArbitraryElements
+ {
+ [Fact]
+ public static void ExtraData()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/>{arbitraryData}<SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void OutOfOrder()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, false));
+ }
+
+ [Fact]
+ public static void DuplicateCanonicalizationMethod()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><CanonicalizationMethod>{arbitraryData}</CanonicalizationMethod><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void DuplicateSignatureMethod()
+ {
+ string arbitraryData = @"<a:foo xmlns:a=""mynamespace"">lol</a:foo>";
+
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><SignatureMethod>{arbitraryData}</SignatureMethod><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo randomattr=""random""><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_CanonicalizationMethod()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315"" randomattr=""random""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void MissingAttributes_CanonicalizationMethod()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod /><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void ExtraAttributes_SignatureMethod()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#rsa-sha1"" randomattr=""random"" /><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+ }
+
+ [Fact]
+ public static void MissingAttributes_SignatureMethod()
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?><a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod /><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Assert.False(Helpers.VerifyCryptoExceptionOnLoad(xml, true));
+
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Xml/tests/SignedXml_Helpers.cs b/src/System.Security.Cryptography.Xml/tests/SignedXml_Helpers.cs
new file mode 100644
index 0000000000..2ca0131959
--- /dev/null
+++ b/src/System.Security.Cryptography.Xml/tests/SignedXml_Helpers.cs
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml;
+using System.Security.Cryptography.X509Certificates;
+using Xunit;
+
+namespace System.Security.Cryptography.Xml.Tests
+{
+ public static class Helpers
+ {
+ public static bool VerifyCryptoExceptionOnLoad(string xml, bool loadXmlThrows)
+ {
+ var xmlDoc = new XmlDocument();
+ xmlDoc.PreserveWhitespace = true;
+ xmlDoc.LoadXml(xml);
+
+ var signatureNode = (XmlElement)xmlDoc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl)[0];
+
+ SignedXml signedXml = new SignedXml(xmlDoc);
+ if (loadXmlThrows)
+ Assert.Throws<CryptographicException>(() => signedXml.LoadXml(signatureNode));
+ else
+ signedXml.LoadXml(signatureNode);
+
+ if (!loadXmlThrows)
+ {
+ bool checkSigResult = signedXml.CheckSignature();
+ return checkSigResult;
+ }
+ return false;
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Xml/tests/SignedXml_Limits.cs b/src/System.Security.Cryptography.Xml/tests/SignedXml_Limits.cs
new file mode 100644
index 0000000000..4f20978f5b
--- /dev/null
+++ b/src/System.Security.Cryptography.Xml/tests/SignedXml_Limits.cs
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml;
+using Xunit;
+
+namespace System.Security.Cryptography.Xml.Tests
+{
+ public class SignedXml_Limits
+ {
+ private const int MaxTransformsPerReference = 10;
+ private const int MaxReferencesPerSignedInfo = 100;
+
+ [Theory]
+ [InlineData(1, 1, false)]
+ [InlineData(MaxTransformsPerReference, 1, false)]
+ [InlineData(MaxTransformsPerReference + 1, 1, true)]
+ [InlineData(1, MaxReferencesPerSignedInfo, false)]
+ [InlineData(1, MaxReferencesPerSignedInfo + 1, true)]
+ [InlineData(MaxTransformsPerReference, MaxReferencesPerSignedInfo, false)]
+ [InlineData(MaxTransformsPerReference, MaxReferencesPerSignedInfo + 1, true)]
+ [InlineData(MaxTransformsPerReference + 1, MaxReferencesPerSignedInfo, true)]
+ [InlineData(MaxTransformsPerReference + 1, MaxReferencesPerSignedInfo + 1, true)]
+ public static void TestReferenceLimits(int numTransformsPerReference, int numReferencesPerSignedInfo, bool loadXmlThrows)
+ {
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+<a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#dsa-sha1""/>";
+ for (int i = 0; i < numReferencesPerSignedInfo; i++)
+ {
+ xml += $@"<Reference URI = """"><Transforms>";
+ for (int j = 0; j < numTransformsPerReference; j++)
+ {
+ xml += $@"<Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/>";
+ }
+ xml += $@"</Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference>";
+ }
+ xml += $@"</SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+ Helpers.VerifyCryptoExceptionOnLoad(xml, loadXmlThrows);
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Xml/tests/SignedXml_SignatureMethodAlgorithm.cs b/src/System.Security.Cryptography.Xml/tests/SignedXml_SignatureMethodAlgorithm.cs
new file mode 100644
index 0000000000..71af4cda6e
--- /dev/null
+++ b/src/System.Security.Cryptography.Xml/tests/SignedXml_SignatureMethodAlgorithm.cs
@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Xml;
+using Xunit;
+
+namespace System.Security.Cryptography.Xml.Tests
+{
+ public class SignedXml_SignatureMethodAlgorithm
+ {
+ [Fact]
+ public static void TestDummySignatureAlgorithm()
+ {
+ string objectToConstruct = typeof(DummyClass).AssemblyQualifiedName;
+ string xml = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
+ <a><b xmlns:ns1=""http://www.contoso.com/"">X<Signature xmlns=""http://www.w3.org/2000/09/xmldsig#""><SignedInfo><CanonicalizationMethod Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/><SignatureMethod Algorithm=""{objectToConstruct}""/><Reference URI=""""><Transforms><Transform Algorithm=""http://www.w3.org/2000/09/xmldsig#enveloped-signature""/><Transform Algorithm=""http://www.w3.org/TR/2001/REC-xml-c14n-20010315""/></Transforms><DigestMethod Algorithm=""http://www.w3.org/2000/09/xmldsig#sha1""/><DigestValue>ZVZLYkc1BAx+YtaqeYlxanb2cGI=</DigestValue></Reference></SignedInfo><SignatureValue>Kx8xs0of766gimu5girTqiTR5xoiWjN4XMx8uzDDhG70bIqpSzlhh6IA3iI54R5mpqCCPWrJJp85ps4jpQk8RGHe4KMejstbY6YXCfs7LtRPzkNzcoZB3vDbr3ijUSrbMk+0wTaZeyeYs8Z6cOicDIVN6bN6yC/Se5fbzTTCSmg=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>ww2w+NbXwY/GRBZfFcXqrAM2X+P1NQoU+QEvgLO1izMTB8kvx1i/bodBvHTrKMwAMGEO4kVATA1f1Vf5/lVnbqiCLMJPVRZU6rWKjOGD28T/VRaIGywTV+mC0HvMbe4DlEd3dBwJZLIMUNvOPsj5Ua+l9IS4EoszFNAg6F5Lsyk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo></Signature></b></a>";
+
+ var xmlDoc = new XmlDocument();
+ xmlDoc.PreserveWhitespace = true;
+ xmlDoc.LoadXml(xml);
+
+ var signatureNode = (XmlElement)xmlDoc.GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl)[0];
+
+ SignedXml signedXml = new SignedXml(xmlDoc);
+ signedXml.LoadXml(signatureNode);
+ Assert.Throws<CryptographicException>(() => signedXml.CheckSignature());
+ }
+
+ public class DummyClass
+ {
+ public DummyClass()
+ {
+ Assert.False(true);
+ }
+ }
+ }
+}
+
diff --git a/src/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj b/src/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj
index 3cb9cf6d35..64857aafcc 100644
--- a/src/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj
+++ b/src/System.Security.Cryptography.Xml/tests/System.Security.Cryptography.Xml.Tests.csproj
@@ -21,6 +21,7 @@
<Compile Include="EncryptedXmlTests.cs" />
<Compile Include="EncryptionPropertyCollectionTest.cs" />
<Compile Include="EncryptionPropertyTest.cs" />
+ <Compile Include="SignedXml_Helpers.cs" />
<Compile Include="KeyInfoNameTest.cs" />
<Compile Include="KeyInfoNodeTest.cs" />
<Compile Include="KeyInfoRetrievalMethodTest.cs" />
@@ -43,7 +44,6 @@
<Compile Include="TestHelpers.cs" />
<Compile Include="TransformChainTest.cs" />
<Compile Include="TransformTest.cs" />
- <Compile Include="XmlDecryptionTransformTest.cs" />
<Compile Include="XmlDsigBase64TransformTest.cs" />
<Compile Include="XmlDsigC14NTransformTest.cs" />
<Compile Include="XmlDsigC14NWithCommentsTransformTest.cs" />
@@ -55,6 +55,15 @@
<Compile Include="XmlLicenseEncryptedRef.cs" />
<Compile Include="XmlLicenseTransformTest.cs" />
</ItemGroup>
+ <ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
+ <Compile Include="KeyInfo_ArbitraryElements.cs" />
+ <Compile Include="Reference_ArbitraryElements.cs" />
+ <Compile Include="Signature_ArbitraryElements.cs" />
+ <Compile Include="SignedInfo_ArbitraryElements.cs" />
+ <Compile Include="SignedXml_Limits.cs" />
+ <Compile Include="SignedXml_SignatureMethodAlgorithm.cs" />
+ <Compile Include="XmlDecryptionTransformTest.cs" />
+ </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="EncryptedXmlSample3.xml" />
<EmbeddedResource Include="EncryptedXmlSample2.xml" />
@@ -64,7 +73,9 @@
<ItemGroup>
<EmbeddedResource Include="Resources\$(AssemblyName).rd.xml" />
</ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/System.Security.Cryptography.Xml/tests/XmlDecryptionTransformTest.cs b/src/System.Security.Cryptography.Xml/tests/XmlDecryptionTransformTest.cs
index 5b2051e3a6..70d86a8cea 100644
--- a/src/System.Security.Cryptography.Xml/tests/XmlDecryptionTransformTest.cs
+++ b/src/System.Security.Cryptography.Xml/tests/XmlDecryptionTransformTest.cs
@@ -110,7 +110,7 @@ namespace System.Security.Cryptography.Xml.Tests
XmlDocument doc = new XmlDocument();
doc.LoadXml("<a />");
- transform.LoadInnerXml(doc.ChildNodes);
+ Assert.Throws<CryptographicException>(() => transform.LoadInnerXml(doc.ChildNodes));
Assert.Null(transform.UnprotectedGetInnerXml());
}
diff --git a/src/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj b/src/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj
index 99991de4b5..3bd3efdb1d 100644
--- a/src/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj
+++ b/src/System.ServiceModel.Syndication/ref/System.ServiceModel.Syndication.csproj
@@ -3,6 +3,7 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<ProjectGuid>{E81F4C7C-2000-4449-BEE6-B2E84DE218F7}</ProjectGuid>
+ <IsPartialFacadeAssembly Condition="'$(TargetsNetFx)' == 'true'">true</IsPartialFacadeAssembly>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Release|AnyCPU'" />
@@ -28,6 +29,7 @@
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel" />
<Reference Include="System.Xml" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
diff --git a/src/System.ServiceModel.Syndication/src/Configurations.props b/src/System.ServiceModel.Syndication/src/Configurations.props
index c398e42e89..2ffb0a6458 100644
--- a/src/System.ServiceModel.Syndication/src/Configurations.props
+++ b/src/System.ServiceModel.Syndication/src/Configurations.props
@@ -3,6 +3,7 @@
<PropertyGroup>
<BuildConfigurations>
netstandard;
+ netfx-Windows_NT;
</BuildConfigurations>
</PropertyGroup>
</Project> \ No newline at end of file
diff --git a/src/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj b/src/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj
index b580434a36..a5e0b04c8d 100644
--- a/src/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj
+++ b/src/System.ServiceModel.Syndication/src/System.ServiceModel.Syndication.csproj
@@ -5,11 +5,19 @@
<AssemblyName>System.ServiceModel.Syndication</AssemblyName>
<ProjectGuid>{C2AB129B-E3EC-465B-B1B7-0F7D414B1E74}</ProjectGuid>
<NoWarn>$(NoWarn);1634;1691;649</NoWarn>
+ <IsPartialFacadeAssembly Condition="'$(TargetsNetFx)' == 'true'">true</IsPartialFacadeAssembly>
+ <OmitResources Condition="'$(TargetsNetFx)' == 'true'">true</OmitResources>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard-Release|AnyCPU'" />
- <ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netfx-Windows_NT-Debug|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netfx-Windows_NT-Release|AnyCPU'" />
+ <ItemGroup Condition="'$(TargetsNetFx)' != 'true'">
<Compile Include="$(MsBuildThisFileDirectory)\**\*.cs" />
</ItemGroup>
+ <ItemGroup Condition="'$(TargetsNetFx)' == 'true'">
+ <Reference Include="mscorlib" />
+ <Reference Include="System.ServiceModel" />
+ </ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project> \ No newline at end of file
diff --git a/src/System.ServiceModel.Syndication/tests/BasicScenarioTests.cs b/src/System.ServiceModel.Syndication/tests/BasicScenarioTests.cs
index 23c29822ce..26401efb91 100644
--- a/src/System.ServiceModel.Syndication/tests/BasicScenarioTests.cs
+++ b/src/System.ServiceModel.Syndication/tests/BasicScenarioTests.cs
@@ -255,6 +255,7 @@ namespace System.ServiceModel.Syndication.Tests
}
[Fact]
+ [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Disjoint items not supported on NetFX")]
public static void SyndicationFeed_Rss_TestDisjointItems()
{
using (XmlReader reader = XmlReader.Create(@"RssDisjointItems.xml"))
@@ -275,6 +276,7 @@ namespace System.ServiceModel.Syndication.Tests
[Fact]
+ [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Disjoint items not supported on NetFX")]
public static void SyndicationFeed_Atom_TestDisjointItems()
{
using (XmlReader reader = XmlReader.Create(@"AtomDisjointItems.xml"))
@@ -294,6 +296,7 @@ namespace System.ServiceModel.Syndication.Tests
}
[Fact]
+ [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Deferred date exception throwing not implemented on NetFX")]
public static void SyndicationFeed_Rss_WrongDateFormat()
{
// *** SETUP *** \\
diff --git a/src/packages.builds b/src/packages.builds
index fefdcc5505..41d3c937b7 100644
--- a/src/packages.builds
+++ b/src/packages.builds
@@ -31,13 +31,18 @@
BeforeTargets="BuildAllProjects"
Condition="'$(IncludePreReleaseLabelInPackageVersion)' != 'true'">
<ItemGroup>
- <PkgProjects Include="$(MSBuildThisFileDirectory)..\pkg\*\*.pkgproj" />
+ <!--
+ The private packages don't get stabilized so they don't need to be included
+ in the set of packages that we are gathering stable versions from.
+ -->
+ <PkgProjects Include="$(MSBuildThisFileDirectory)..\pkg\*\*.pkgproj" Exclude="$(MSBuildThisFileDirectory)..\pkg\*Private*\*.pkgproj" />
<PkgProjects Include="*\pkg\**\*.pkgproj" />
</ItemGroup>
<MSBuild Targets="GetPackageIdentityIfStable"
BuildInParallel="$(BuildInParallel)"
- Projects="@(PkgProjects)">
+ Projects="@(PkgProjects)"
+ RemoveProperties="Configuration">
<Output TaskParameter="TargetOutputs"
ItemName="_StablePackages" />
</MSBuild>
diff --git a/tools-local/ILAsmVersion.txt b/tools-local/ILAsmVersion.txt
index e548275c62..0717f3165e 100644
--- a/tools-local/ILAsmVersion.txt
+++ b/tools-local/ILAsmVersion.txt
@@ -1 +1 @@
-2.1.0-rc1-26419-03 \ No newline at end of file
+2.1.0-rtm-26508-04 \ No newline at end of file