diff options
Diffstat (limited to 'src/binder/textualidentityparser.cpp')
-rw-r--r-- | src/binder/textualidentityparser.cpp | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/src/binder/textualidentityparser.cpp b/src/binder/textualidentityparser.cpp index eb6e371afe..2913847dd2 100644 --- a/src/binder/textualidentityparser.cpp +++ b/src/binder/textualidentityparser.cpp @@ -65,7 +65,7 @@ namespace BINDER_SPACE const int iPublicKeyMaxLength = 2048; const int iVersionMax = 65535; - const int iRequiredVersionParts = 4; + const int iVersionParts = 4; inline void UnicodeHexToBin(LPCWSTR pSrc, UINT cSrc, LPBYTE pDest) { @@ -288,10 +288,10 @@ namespace BINDER_SPACE { tmpString.Clear(); tmpString.Printf(W("%d.%d.%d.%d"), - pAssemblyIdentity->m_version.GetMajor(), - pAssemblyIdentity->m_version.GetMinor(), - pAssemblyIdentity->m_version.GetBuild(), - pAssemblyIdentity->m_version.GetRevision()); + (DWORD)(USHORT)pAssemblyIdentity->m_version.GetMajor(), + (DWORD)(USHORT)pAssemblyIdentity->m_version.GetMinor(), + (DWORD)(USHORT)pAssemblyIdentity->m_version.GetBuild(), + (DWORD)(USHORT)pAssemblyIdentity->m_version.GetRevision()); textualIdentity.Append(W(", Version=")); textualIdentity.Append(tmpString); @@ -378,8 +378,10 @@ namespace BINDER_SPACE { BOOL fIsValid = FALSE; DWORD dwFoundNumbers = 0; - DWORD dwCurrentNumber = 0; - DWORD dwNumbers[iRequiredVersionParts]; + bool foundUnspecifiedComponent = false; + const DWORD UnspecifiedNumber = (DWORD)-1; + DWORD dwCurrentNumber = UnspecifiedNumber; + DWORD dwNumbers[iVersionParts] = {UnspecifiedNumber, UnspecifiedNumber, UnspecifiedNumber, UnspecifiedNumber}; BINDER_LOG_ENTER(W("TextualIdentityParser::ParseVersion")); @@ -391,17 +393,46 @@ namespace BINDER_SPACE { WCHAR wcCurrentChar = cursor[0]; - if (dwFoundNumbers >= static_cast<DWORD>(iRequiredVersionParts)) + if (dwFoundNumbers >= static_cast<DWORD>(iVersionParts)) { goto Exit; } - else if (wcCurrentChar == W('.') || wcCurrentChar == 0x00) + else if (wcCurrentChar == W('.') || wcCurrentChar == W('\0')) { - dwNumbers[dwFoundNumbers++] = dwCurrentNumber; - dwCurrentNumber = 0; + if (dwCurrentNumber == UnspecifiedNumber) + { + // Difference from .NET Framework, compat with Version(string) constructor: A missing version component + // is considered invalid. + // + // Examples: + // "MyAssembly, Version=." + // "MyAssembly, Version=1." + // "MyAssembly, Version=.1" + // "MyAssembly, Version=1..1" + goto Exit; + } + + // Compat with .NET Framework: A value of iVersionMax is considered unspecified. Once an unspecified + // component is found, validate the remaining components but consider them as unspecified as well. + if (dwCurrentNumber == iVersionMax) + { + foundUnspecifiedComponent = true; + dwCurrentNumber = UnspecifiedNumber; + } + else if (!foundUnspecifiedComponent) + { + dwNumbers[dwFoundNumbers] = dwCurrentNumber; + dwCurrentNumber = UnspecifiedNumber; + } + + dwFoundNumbers++; } else if ((wcCurrentChar >= W('0')) && (wcCurrentChar <= W('9'))) { + if (dwCurrentNumber == UnspecifiedNumber) + { + dwCurrentNumber = 0; + } dwCurrentNumber = (dwCurrentNumber * 10) + (wcCurrentChar - W('0')); if (dwCurrentNumber > static_cast<DWORD>(iVersionMax)) @@ -417,12 +448,21 @@ namespace BINDER_SPACE cursor++; } - if (dwFoundNumbers == static_cast<DWORD>(iRequiredVersionParts)) + // Difference from .NET Framework: If the major or minor version are unspecified, the version is considered invalid. + // + // Examples: + // "MyAssembly, Version=" + // "MyAssembly, Version=1" + // "MyAssembly, Version=65535.1" + // "MyAssembly, Version=1.65535" + if (dwFoundNumbers < 2 || dwNumbers[0] == UnspecifiedNumber || dwNumbers[1] == UnspecifiedNumber) { - pAssemblyVersion->SetFeatureVersion(dwNumbers[0], dwNumbers[1]); - pAssemblyVersion->SetServiceVersion(dwNumbers[2], dwNumbers[3]); - fIsValid = TRUE; + goto Exit; } + + pAssemblyVersion->SetFeatureVersion(dwNumbers[0], dwNumbers[1]); + pAssemblyVersion->SetServiceVersion(dwNumbers[2], dwNumbers[3]); + fIsValid = TRUE; } Exit: |