diff options
author | Koundinya Veluri <kouvel@microsoft.com> | 2017-08-17 00:05:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-17 00:05:21 -0700 |
commit | 0825741447c14a6a70c60b7c429e16f95214e74e (patch) | |
tree | 1d1b10c39c05fd3bac87649514aa2b3f4f8a448d /src/binder/assemblybinder.cpp | |
parent | 0010efc91e3834affd878f122e44dc961e93f851 (diff) | |
download | coreclr-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.cpp | 82 |
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) { |