mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
fix buffer overrun on mswindows
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25973 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
d7a0a0cc0d
commit
b728011a03
2 changed files with 186 additions and 165 deletions
|
@ -2,6 +2,8 @@
|
|||
|
||||
* Tools/autogsdoc.m: Fix bug recording sources and outputs in
|
||||
index and dependencies.
|
||||
* Source/NSTimeZone.m: Fix coding style errors and buffer overrun
|
||||
on mswindows reported by Roland Schwingel.
|
||||
|
||||
2008-01-14 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
|
|
|
@ -2115,173 +2115,192 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
|
|||
- (id) initWithName: (NSString*)name data: (NSData*)data
|
||||
{
|
||||
HKEY regDirKey;
|
||||
BOOL isNT = NO,regFound=NO;
|
||||
BOOL isNT = NO, regFound=NO;
|
||||
|
||||
/* Open the key in the local machine hive where the time zone data is stored. */
|
||||
/* Open the key in the local machine hive where
|
||||
* the time zone data is stored. */
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
|
||||
0,
|
||||
KEY_READ,
|
||||
®DirKey))
|
||||
{
|
||||
isNT=YES;
|
||||
regFound=YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
|
||||
0,
|
||||
KEY_READ,
|
||||
®DirKey))
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
|
||||
0,
|
||||
KEY_READ,
|
||||
®DirKey))
|
||||
{
|
||||
regFound=YES;
|
||||
isNT=YES;
|
||||
regFound=YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
|
||||
0,
|
||||
KEY_READ,
|
||||
®DirKey))
|
||||
{
|
||||
regFound=YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (regFound)
|
||||
{
|
||||
/* Iterate over all subKeys in the registry to find the right one.
|
||||
Unfortunately name is a localized value. The keys in the registry are
|
||||
unlocalized names. */
|
||||
wchar_t achKey[255]; // buffer for subkey name
|
||||
DWORD cbName; // size of name string
|
||||
wchar_t achClass[MAX_PATH] = L""; // buffer for class name
|
||||
DWORD cchClassName = MAX_PATH; // size of class string
|
||||
DWORD cSubKeys=0; // number of subkeys
|
||||
DWORD cbMaxSubKey; // longest subkey size
|
||||
DWORD cchMaxClass; // longest class string
|
||||
DWORD cValues; // number of values for key
|
||||
DWORD cchMaxValue; // longest value name
|
||||
DWORD cbMaxValueData; // longest value data
|
||||
DWORD cbSecurityDescriptor; // size of security descriptor
|
||||
FILETIME ftLastWriteTime; // last write time
|
||||
{
|
||||
/* Iterate over all subKeys in the registry to find the right one.
|
||||
Unfortunately name is a localized value. The keys in the registry are
|
||||
unlocalized names. */
|
||||
wchar_t achKey[255]; // buffer for subkey name
|
||||
DWORD cbName; // size of name string
|
||||
wchar_t achClass[MAX_PATH] = L""; // buffer for class name
|
||||
DWORD cchClassName = MAX_PATH; // size of class string
|
||||
DWORD cSubKeys=0; // number of subkeys
|
||||
DWORD cbMaxSubKey; // longest subkey size
|
||||
DWORD cchMaxClass; // longest class string
|
||||
DWORD cValues; // number of values for key
|
||||
DWORD cchMaxValue; // longest value name
|
||||
DWORD cbMaxValueData; // longest value data
|
||||
DWORD cbSecurityDescriptor; // size of security descriptor
|
||||
FILETIME ftLastWriteTime; // last write time
|
||||
DWORD i, retCode;
|
||||
BOOL tzFound = NO;
|
||||
|
||||
DWORD i, retCode;
|
||||
BOOL tzFound = NO;
|
||||
|
||||
/* Get the class name and the value count. */
|
||||
retCode = RegQueryInfoKeyW(
|
||||
regDirKey, // key handle
|
||||
achClass, // buffer for class name
|
||||
&cchClassName, // size of class string
|
||||
NULL, // reserved
|
||||
&cSubKeys, // number of subkeys
|
||||
&cbMaxSubKey, // longest subkey size
|
||||
&cchMaxClass, // longest class string
|
||||
&cValues, // number of values for this key
|
||||
&cchMaxValue, // longest value name
|
||||
&cbMaxValueData, // longest value data
|
||||
&cbSecurityDescriptor, // security descriptor
|
||||
&ftLastWriteTime); // last write time
|
||||
/* Get the class name and the value count. */
|
||||
retCode = RegQueryInfoKeyW(
|
||||
regDirKey, // key handle
|
||||
achClass, // buffer for class name
|
||||
&cchClassName, // size of class string
|
||||
NULL, // reserved
|
||||
&cSubKeys, // number of subkeys
|
||||
&cbMaxSubKey, // longest subkey size
|
||||
&cchMaxClass, // longest class string
|
||||
&cValues, // number of values for this key
|
||||
&cchMaxValue, // longest value name
|
||||
&cbMaxValueData, // longest value data
|
||||
&cbSecurityDescriptor, // security descriptor
|
||||
&ftLastWriteTime); // last write time
|
||||
|
||||
if (cSubKeys && (retCode == ERROR_SUCCESS))
|
||||
if (cSubKeys && (retCode == ERROR_SUCCESS))
|
||||
{
|
||||
wchar_t *wName = malloc(([name length]+1) * sizeof(wchar_t));
|
||||
if (wName)
|
||||
{
|
||||
[name getCharacters:wName];
|
||||
int wLen = [name length];
|
||||
wchar_t *wName = malloc((wLen+1) * sizeof(wchar_t));
|
||||
|
||||
for (i=0; i<cSubKeys && !tzFound; i++)
|
||||
{
|
||||
cbName = 255;
|
||||
|
||||
retCode = RegEnumKeyExW(regDirKey, i, achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime);
|
||||
if (retCode == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t keyBuffer[16384];
|
||||
HKEY regKey;
|
||||
|
||||
if (isNT)
|
||||
wcscpy(keyBuffer,L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\");
|
||||
else
|
||||
wcscpy(keyBuffer,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones\\");
|
||||
|
||||
wcscat(keyBuffer,achKey);
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyBuffer, 0, KEY_READ, ®Key))
|
||||
{
|
||||
wchar_t buf[256];
|
||||
wchar_t standardName[256];
|
||||
wchar_t daylightName[256];
|
||||
DWORD bufsize;
|
||||
DWORD type;
|
||||
|
||||
/* check standardname */
|
||||
standardName[0]=L'\0';
|
||||
bufsize=sizeof(buf);
|
||||
if (ERROR_SUCCESS==RegQueryValueExW(regKey, L"Std", 0, &type, (BYTE *)buf, &bufsize))
|
||||
{
|
||||
wcscpy(standardName,buf);
|
||||
if (wcscmp(standardName,wName) == 0)
|
||||
tzFound = YES;
|
||||
}
|
||||
|
||||
/* check daylightname */
|
||||
daylightName[0]=L'\0';
|
||||
bufsize=sizeof(buf);
|
||||
if (ERROR_SUCCESS==RegQueryValueExW(regKey, L"Dlt", 0, &type, (BYTE *)buf, &bufsize))
|
||||
{
|
||||
wcscpy(daylightName,buf);
|
||||
if (wcscmp(daylightName,wName) == 0)
|
||||
tzFound = YES;
|
||||
}
|
||||
|
||||
if (tzFound)
|
||||
{
|
||||
/* Read in the time zone data */
|
||||
bufsize=sizeof(buf);
|
||||
if (ERROR_SUCCESS==RegQueryValueExW(regKey, L"TZI", 0, &type, (BYTE *)buf, &bufsize))
|
||||
{
|
||||
TZI *tzi = (void*)buf;
|
||||
Bias = tzi->Bias;
|
||||
StandardBias = tzi->StandardBias;
|
||||
DaylightBias = tzi->DaylightBias;
|
||||
StandardDate = tzi->StandardDate;
|
||||
DaylightDate = tzi->DaylightDate;
|
||||
}
|
||||
|
||||
/* Set the standard name for the time zone. */
|
||||
if (wcslen(standardName))
|
||||
{
|
||||
int a, b;
|
||||
ASSIGN(timeZoneName,[NSString stringWithCharacters:standardName length:wcslen(standardName)]);
|
||||
|
||||
/* Abbr generated here is IMHO a bit suspicous but I kept it */
|
||||
for(a=0,b=0;standardName[a];a++)
|
||||
{
|
||||
if (iswupper(standardName[a]))
|
||||
standardName[b++]=standardName[a];
|
||||
}
|
||||
standardName[b]=L'\0';
|
||||
ASSIGN(timeZoneNameAbbr,[NSString stringWithCharacters:standardName length:wcslen(standardName)]);
|
||||
}
|
||||
|
||||
/* Set the daylight savings name for the time zone. */
|
||||
if (wcslen(daylightName))
|
||||
{
|
||||
int a,b;
|
||||
ASSIGN(daylightZoneName,[NSString stringWithCharacters:daylightName length:wcslen(daylightName)]);
|
||||
|
||||
/* Abbr generated here is IMHO a bit suspicous but I kept it */
|
||||
for(a=0,b=0;daylightName[a];a++)
|
||||
{
|
||||
if (iswupper(daylightName[a]))
|
||||
daylightName[b++]=daylightName[a];
|
||||
}
|
||||
daylightName[b]=L'\0';
|
||||
ASSIGN(daylightZoneNameAbbr,[NSString stringWithCharacters:daylightName length:wcslen(daylightName)]);
|
||||
}
|
||||
}
|
||||
RegCloseKey(regKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(wName);
|
||||
}
|
||||
}
|
||||
if (wName)
|
||||
{
|
||||
[name getCharacters: wName];
|
||||
wName[wLen] = 0;
|
||||
for (i = 0; i < cSubKeys && !tzFound; i++)
|
||||
{
|
||||
cbName = 255;
|
||||
|
||||
retCode = RegEnumKeyExW(regDirKey, i, achKey, &cbName,
|
||||
NULL, NULL, NULL, &ftLastWriteTime);
|
||||
if (retCode == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t keyBuffer[16384];
|
||||
HKEY regKey;
|
||||
|
||||
if (isNT)
|
||||
wcscpy(keyBuffer, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\");
|
||||
else
|
||||
wcscpy(keyBuffer, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones\\");
|
||||
|
||||
wcscat(keyBuffer, achKey);
|
||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
keyBuffer, 0, KEY_READ, ®Key))
|
||||
{
|
||||
wchar_t buf[256];
|
||||
wchar_t standardName[256];
|
||||
wchar_t daylightName[256];
|
||||
DWORD bufsize;
|
||||
DWORD type;
|
||||
|
||||
/* check standardname */
|
||||
standardName[0] = L'\0';
|
||||
bufsize = sizeof(buf);
|
||||
if (ERROR_SUCCESS == RegQueryValueExW(regKey,
|
||||
L"Std", 0, &type, (BYTE *)buf, &bufsize))
|
||||
{
|
||||
wcscpy(standardName, buf);
|
||||
if (wcscmp(standardName, wName) == 0)
|
||||
tzFound = YES;
|
||||
}
|
||||
|
||||
/* check daylightname */
|
||||
daylightName[0] = L'\0';
|
||||
bufsize = sizeof(buf);
|
||||
if (ERROR_SUCCESS == RegQueryValueExW(regKey,
|
||||
L"Dlt", 0, &type, (BYTE *)buf, &bufsize))
|
||||
{
|
||||
wcscpy(daylightName, buf);
|
||||
if (wcscmp(daylightName, wName) == 0)
|
||||
tzFound = YES;
|
||||
}
|
||||
|
||||
if (tzFound)
|
||||
{
|
||||
/* Read in the time zone data */
|
||||
bufsize = sizeof(buf);
|
||||
if (ERROR_SUCCESS == RegQueryValueExW(regKey,
|
||||
L"TZI", 0, &type, (BYTE *)buf, &bufsize))
|
||||
{
|
||||
TZI *tzi = (void*)buf;
|
||||
Bias = tzi->Bias;
|
||||
StandardBias = tzi->StandardBias;
|
||||
DaylightBias = tzi->DaylightBias;
|
||||
StandardDate = tzi->StandardDate;
|
||||
DaylightDate = tzi->DaylightDate;
|
||||
}
|
||||
|
||||
/* Set the standard name for the time zone. */
|
||||
if (wcslen(standardName))
|
||||
{
|
||||
int a, b;
|
||||
|
||||
ASSIGN(timeZoneName,
|
||||
[NSString stringWithCharacters: standardName
|
||||
length: wcslen(standardName)]);
|
||||
|
||||
/* Abbr generated here is IMHO
|
||||
* a bit suspicous but I kept it */
|
||||
for (a = 0, b = 0; standardName[a]; a++)
|
||||
{
|
||||
if (iswupper(standardName[a]))
|
||||
standardName[b++] = standardName[a];
|
||||
}
|
||||
standardName[b] = L'\0';
|
||||
ASSIGN(timeZoneNameAbbr,
|
||||
[NSString stringWithCharacters: standardName
|
||||
length: wcslen(standardName)]);
|
||||
}
|
||||
|
||||
/* Set the daylight savings name
|
||||
* for the time zone. */
|
||||
if (wcslen(daylightName))
|
||||
{
|
||||
int a, b;
|
||||
|
||||
ASSIGN(daylightZoneName,
|
||||
[NSString stringWithCharacters: daylightName
|
||||
length: wcslen(daylightName)]);
|
||||
|
||||
/* Abbr generated here is IMHO
|
||||
* a bit suspicous but I kept it */
|
||||
for (a = 0, b = 0; daylightName[a]; a++)
|
||||
{
|
||||
if (iswupper(daylightName[a]))
|
||||
daylightName[b++] = daylightName[a];
|
||||
}
|
||||
daylightName[b] = L'\0';
|
||||
ASSIGN(daylightZoneNameAbbr,
|
||||
[NSString stringWithCharacters: daylightName
|
||||
length: wcslen(daylightName)]);
|
||||
}
|
||||
}
|
||||
RegCloseKey(regKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(wName);
|
||||
}
|
||||
}
|
||||
RegCloseKey(regDirKey);
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -2328,7 +2347,7 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
|
|||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dow = ((int)((when / 86400.0) + GREGORIAN_REFERENCE)) % 7;
|
||||
if (dow < 0)
|
||||
|
@ -2339,13 +2358,13 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
|
|||
daylightdate = day - dow + DaylightDate.wDayOfWeek;
|
||||
maxdate = lastDayOfGregorianMonth(DaylightDate.wMonth, year)-7;
|
||||
while (daylightdate > 7)
|
||||
daylightdate-=7;
|
||||
daylightdate -= 7;
|
||||
if (daylightdate < 1)
|
||||
daylightdate += 7;
|
||||
count=DaylightDate.wDay;
|
||||
while (count>1 && daylightdate < maxdate)
|
||||
count = DaylightDate.wDay;
|
||||
while (count > 1 && daylightdate < maxdate)
|
||||
{
|
||||
daylightdate+=7;
|
||||
daylightdate += 7;
|
||||
count--;
|
||||
}
|
||||
if (day > daylightdate)
|
||||
|
@ -2373,13 +2392,13 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
|
|||
daylightdate = day - dow + StandardDate.wDayOfWeek;
|
||||
maxdate = lastDayOfGregorianMonth(StandardDate.wMonth, year)-7;
|
||||
while (daylightdate > 7)
|
||||
daylightdate-=7;
|
||||
daylightdate -= 7;
|
||||
if (daylightdate < 1)
|
||||
daylightdate += 7;
|
||||
count=StandardDate.wDay;
|
||||
while (count>1 && daylightdate < maxdate)
|
||||
count = StandardDate.wDay;
|
||||
while (count > 1 && daylightdate < maxdate)
|
||||
{
|
||||
daylightdate+=7;
|
||||
daylightdate += 7;
|
||||
count--;
|
||||
}
|
||||
if (day > daylightdate)
|
||||
|
|
Loading…
Reference in a new issue