summaryrefslogtreecommitdiff
path: root/src/binder/assemblybinder.cpp
diff options
context:
space:
mode:
authorKoundinya Veluri <kouvel@microsoft.com>2017-08-17 00:05:21 -0700
committerGitHub <noreply@github.com>2017-08-17 00:05:21 -0700
commit0825741447c14a6a70c60b7c429e16f95214e74e (patch)
tree1d1b10c39c05fd3bac87649514aa2b3f4f8a448d /src/binder/assemblybinder.cpp
parent0010efc91e3834affd878f122e44dc961e93f851 (diff)
downloadcoreclr-0825741447c14a6a70c60b7c429e16f95214e74e.tar.gz
coreclr-0825741447c14a6a70c60b7c429e16f95214e74e.tar.bz2
coreclr-0825741447c14a6a70c60b7c429e16f95214e74e.zip
Fix AssemblyName(string) constructor's version parsing (#13373)
Fix AssemblyName(string) constructor's version parsing Functional fix for https://github.com/dotnet/corefx/issues/22663 - Allow fewer version components - Match .NET Framework behavior in several cases. Major and minor version must be specified for the version to be used. - Used zero for unspecified build/revision. This is different from .NET Framework but the loader also behaves differently. Details are in code comments.
Diffstat (limited to 'src/binder/assemblybinder.cpp')
-rw-r--r--src/binder/assemblybinder.cpp82
1 files changed, 55 insertions, 27 deletions
diff --git a/src/binder/assemblybinder.cpp b/src/binder/assemblybinder.cpp
index 73ea025ae8..7c0aa8077e 100644
--- a/src/binder/assemblybinder.cpp
+++ b/src/binder/assemblybinder.cpp
@@ -89,38 +89,66 @@ namespace BINDER_SPACE
AssemblyVersion *pRequestedVersion = pRequestedName->GetVersion();
AssemblyVersion *pFoundVersion = pFoundName->GetVersion();
- //
- // If the AssemblyRef has no version, we can treat it as requesting the most accommodating version (0.0.0.0). In
- // that case, skip version checking and allow the bind.
- //
- if (!pRequestedName->HaveAssemblyVersion())
+ do
{
- return hr;
- }
+ if (!pRequestedVersion->HasMajor())
+ {
+ // An unspecified requested version component matches any value for the same component in the found version,
+ // regardless of lesser-order version components
+ break;
+ }
+ if (!pFoundVersion->HasMajor() || pRequestedVersion->GetMajor() > pFoundVersion->GetMajor())
+ {
+ // - A specific requested version component does not match an unspecified value for the same component in
+ // the found version, regardless of lesser-order version components
+ // - Or, the requested version is greater than the found version
+ hr = FUSION_E_APP_DOMAIN_LOCKED;
+ break;
+ }
+ if (pRequestedVersion->GetMajor() < pFoundVersion->GetMajor())
+ {
+ // The requested version is less than the found version
+ break;
+ }
- //
- // This if condition is paired with the one above that checks for pRequestedName
- // not having an assembly version. If we didn't exit in the above if condition,
- // and satisfy this one's requirements, we're in a situation where the assembly
- // Ref has a version, but the Def doesn't, which cannot succeed a bind
- //
- _ASSERTE(pRequestedName->HaveAssemblyVersion());
- if (!pFoundName->HaveAssemblyVersion())
- {
- hr = FUSION_E_APP_DOMAIN_LOCKED;
- }
- else if (pRequestedVersion->IsEqualFeatureVersion(pFoundVersion))
- {
- // Now service version matters
- if (pRequestedVersion->IsLargerServiceVersion(pFoundVersion))
+ if (!pRequestedVersion->HasMinor())
+ {
+ break;
+ }
+ if (!pFoundVersion->HasMinor() || pRequestedVersion->GetMinor() > pFoundVersion->GetMinor())
{
hr = FUSION_E_APP_DOMAIN_LOCKED;
+ break;
}
- }
- else if (pRequestedVersion->IsLargerFeatureVersion(pFoundVersion))
- {
- hr = FUSION_E_APP_DOMAIN_LOCKED;
- }
+ if (pRequestedVersion->GetMinor() < pFoundVersion->GetMinor())
+ {
+ break;
+ }
+
+ if (!pRequestedVersion->HasBuild())
+ {
+ break;
+ }
+ if (!pFoundVersion->HasBuild() || pRequestedVersion->GetBuild() > pFoundVersion->GetBuild())
+ {
+ hr = FUSION_E_APP_DOMAIN_LOCKED;
+ break;
+ }
+ if (pRequestedVersion->GetBuild() < pFoundVersion->GetBuild())
+ {
+ break;
+ }
+
+ if (!pRequestedVersion->HasRevision())
+ {
+ break;
+ }
+ if (!pFoundVersion->HasRevision() || pRequestedVersion->GetRevision() > pFoundVersion->GetRevision())
+ {
+ hr = FUSION_E_APP_DOMAIN_LOCKED;
+ break;
+ }
+ } while (false);
if (pApplicationContext->IsTpaListProvided() && hr == FUSION_E_APP_DOMAIN_LOCKED)
{