summaryrefslogtreecommitdiff
path: root/src/binder/textualidentityparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/binder/textualidentityparser.cpp')
-rw-r--r--src/binder/textualidentityparser.cpp70
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: