From a27f0e7d00351135282264f7e49a8c761b0ceb60 Mon Sep 17 00:00:00 2001
From: Bogdan Bot-Rus <Bogdan.Bot-Rus@gfi.com>
Date: Wed, 3 Aug 2016 14:37:50 +0300
Subject: [PATCH 1/1] JEDI JCL   
 http://issuetracker.delphi-jedi.org/view.php?id=6519 Summary 0006519:
 GetWindowsMajorVersionNumber strToInt(StrBefore('.' Crash on Windows Storage
 Server 2012 R2 in JclSysInfo.pas > initialization s Description OS:Windows
 Storage Server 2012 R2
 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows
 NT\CurrentVersion\CurrentVersion = 6.3
 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows
 NT\CurrentVersion\ProductName = 'Windows Storage Server 2012 R2 Standard' The
 crash is generated because 'ProductName' <> 'Windows Server 2012 R2'
 GetWindowsMajorVersionNumber calls StrBefore which calls StrFind which calls
 StrIPos which calls StrUpper which calls StrUpperInPlace which calls
 StrCase(S, StrUpOffset) which needs StrCaseMap to be populated. But since
 this all is run as part of the initialization section of JclSysInfo,
 StrCaseMap is not populated yet. Therefore StrUpper returns #0#0#0, StrBefore
 returns '', StrToInt crashes the process.

---
 ThirdParty/JEDI/jcl/common/JclSysInfo.pas | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/ThirdParty/JEDI/jcl/common/JclSysInfo.pas b/ThirdParty/JEDI/jcl/common/JclSysInfo.pas
index 7e4c814..efd4045 100644
--- a/ThirdParty/JEDI/jcl/common/JclSysInfo.pas
+++ b/ThirdParty/JEDI/jcl/common/JclSysInfo.pas
@@ -3874,6 +3874,28 @@ begin
     Result := Win32BuildNumber;
 end;
 
+function StrBeforeCaseSensitive(const SubStr, S: string): string;
+var
+  P: SizeInt;
+begin
+  P := Pos(SubStr, S, 1); //StrFind(SubStr, S, 1);
+  if P <= 0 then
+    Result := S
+  else
+    Result := StrLeft(S, P - 1);
+end;
+
+function StrAfterCaseSensitive(const SubStr, S: string): string;
+var
+  P: SizeInt;
+begin
+  P := Pos(SubStr, S, 1); //StrFind(SubStr, S, 1); // StrFind is case-insensitive pos
+  if P <= 0 then
+    Result := ''           // substr not found -> nothing after it
+  else
+    Result := StrRestOf(S, P + Length(SubStr));
+end;
+
 function GetWindowsMajorVersionNumber: Integer;
 begin
   // Starting with Windows 8.1, the GetVersion(Ex) API is deprecated and will detect the
@@ -3885,7 +3907,7 @@ begin
     // If CurrentMajorVersionNumber not present in registry then use CurrentVersion
     Result := RegReadIntegerDef(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'CurrentMajorVersionNumber', -1);
     if Result = -1 then
-      Result := strToInt(StrBefore('.', RegReadStringDef(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'CurrentVersion', intToStr(Win32MajorVersion) + '.' + intToStr(Win32MinorVersion))));
+      Result := StrToInt(StrBeforeCaseSensitive('.', RegReadStringDef(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'CurrentVersion', intToStr(Win32MajorVersion) + '.' + intToStr(Win32MinorVersion))));
   end
   else
     Result := Win32MajorVersion;
@@ -3902,7 +3924,7 @@ begin
     // If CurrentMinorVersionNumber not present then use CurrentVersion
     Result := RegReadIntegerDef(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'CurrentMinorVersionNumber', -1);
     if Result = -1 then
-      Result := strToInt(StrAfter('.', RegReadStringDef(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'CurrentVersion', intToStr(Win32MajorVersion) + '.' + intToStr(Win32MinorVersion))));
+      Result := strToInt(StrAfterCaseSensitive('.', RegReadStringDef(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'CurrentVersion', intToStr(Win32MajorVersion) + '.' + intToStr(Win32MinorVersion))));
   end
   else
     Result := Win32MajorVersion;
-- 
2.8.2.windows.1

