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:
rfm 2008-01-18 13:33:26 +00:00
parent a39a414e68
commit 4788e68beb
2 changed files with 186 additions and 165 deletions

View file

@ -2,6 +2,8 @@
* Tools/autogsdoc.m: Fix bug recording sources and outputs in * Tools/autogsdoc.m: Fix bug recording sources and outputs in
index and dependencies. 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> 2008-01-14 Nicola Pero <nicola.pero@meta-innovation.com>

View file

@ -2115,173 +2115,192 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
- (id) initWithName: (NSString*)name data: (NSData*)data - (id) initWithName: (NSString*)name data: (NSData*)data
{ {
HKEY regDirKey; 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, if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
0, 0,
KEY_READ, KEY_READ,
&regDirKey)) &regDirKey))
{
isNT=YES;
regFound=YES;
}
else
{
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
0,
KEY_READ,
&regDirKey))
{ {
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,
&regDirKey))
{
regFound=YES;
}
} }
}
if (regFound) if (regFound)
{ {
/* Iterate over all subKeys in the registry to find the right one. /* Iterate over all subKeys in the registry to find the right one.
Unfortunately name is a localized value. The keys in the registry are Unfortunately name is a localized value. The keys in the registry are
unlocalized names. */ unlocalized names. */
wchar_t achKey[255]; // buffer for subkey name wchar_t achKey[255]; // buffer for subkey name
DWORD cbName; // size of name string DWORD cbName; // size of name string
wchar_t achClass[MAX_PATH] = L""; // buffer for class name wchar_t achClass[MAX_PATH] = L""; // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys=0; // number of subkeys DWORD cSubKeys=0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time FILETIME ftLastWriteTime; // last write time
DWORD i, retCode;
BOOL tzFound = NO;
DWORD i, retCode; /* Get the class name and the value count. */
BOOL tzFound = NO; 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. */ if (cSubKeys && (retCode == ERROR_SUCCESS))
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))
{ {
wchar_t *wName = malloc(([name length]+1) * sizeof(wchar_t)); int wLen = [name length];
if (wName) wchar_t *wName = malloc((wLen+1) * sizeof(wchar_t));
{
[name getCharacters:wName];
for (i=0; i<cSubKeys && !tzFound; i++) if (wName)
{ {
cbName = 255; [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); retCode = RegEnumKeyExW(regDirKey, i, achKey, &cbName,
if (retCode == ERROR_SUCCESS) NULL, NULL, NULL, &ftLastWriteTime);
{ if (retCode == ERROR_SUCCESS)
wchar_t keyBuffer[16384]; {
HKEY regKey; wchar_t keyBuffer[16384];
HKEY regKey;
if (isNT) if (isNT)
wcscpy(keyBuffer,L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\"); wcscpy(keyBuffer, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\");
else else
wcscpy(keyBuffer,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones\\"); wcscpy(keyBuffer, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones\\");
wcscat(keyBuffer,achKey); wcscat(keyBuffer, achKey);
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyBuffer, 0, KEY_READ, &regKey)) if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE,
{ keyBuffer, 0, KEY_READ, &regKey))
wchar_t buf[256]; {
wchar_t standardName[256]; wchar_t buf[256];
wchar_t daylightName[256]; wchar_t standardName[256];
DWORD bufsize; wchar_t daylightName[256];
DWORD type; DWORD bufsize;
DWORD type;
/* check standardname */ /* check standardname */
standardName[0]=L'\0'; standardName[0] = L'\0';
bufsize=sizeof(buf); bufsize = sizeof(buf);
if (ERROR_SUCCESS==RegQueryValueExW(regKey, L"Std", 0, &type, (BYTE *)buf, &bufsize)) if (ERROR_SUCCESS == RegQueryValueExW(regKey,
{ L"Std", 0, &type, (BYTE *)buf, &bufsize))
wcscpy(standardName,buf); {
if (wcscmp(standardName,wName) == 0) wcscpy(standardName, buf);
tzFound = YES; if (wcscmp(standardName, wName) == 0)
} tzFound = YES;
}
/* check daylightname */ /* check daylightname */
daylightName[0]=L'\0'; daylightName[0] = L'\0';
bufsize=sizeof(buf); bufsize = sizeof(buf);
if (ERROR_SUCCESS==RegQueryValueExW(regKey, L"Dlt", 0, &type, (BYTE *)buf, &bufsize)) if (ERROR_SUCCESS == RegQueryValueExW(regKey,
{ L"Dlt", 0, &type, (BYTE *)buf, &bufsize))
wcscpy(daylightName,buf); {
if (wcscmp(daylightName,wName) == 0) wcscpy(daylightName, buf);
tzFound = YES; if (wcscmp(daylightName, wName) == 0)
} tzFound = YES;
}
if (tzFound) if (tzFound)
{ {
/* Read in the time zone data */ /* Read in the time zone data */
bufsize=sizeof(buf); bufsize = sizeof(buf);
if (ERROR_SUCCESS==RegQueryValueExW(regKey, L"TZI", 0, &type, (BYTE *)buf, &bufsize)) if (ERROR_SUCCESS == RegQueryValueExW(regKey,
{ L"TZI", 0, &type, (BYTE *)buf, &bufsize))
TZI *tzi = (void*)buf; {
Bias = tzi->Bias; TZI *tzi = (void*)buf;
StandardBias = tzi->StandardBias; Bias = tzi->Bias;
DaylightBias = tzi->DaylightBias; StandardBias = tzi->StandardBias;
StandardDate = tzi->StandardDate; DaylightBias = tzi->DaylightBias;
DaylightDate = tzi->DaylightDate; StandardDate = tzi->StandardDate;
} DaylightDate = tzi->DaylightDate;
}
/* Set the standard name for the time zone. */ /* Set the standard name for the time zone. */
if (wcslen(standardName)) if (wcslen(standardName))
{ {
int a, b; int a, b;
ASSIGN(timeZoneName,[NSString stringWithCharacters:standardName length:wcslen(standardName)]);
/* Abbr generated here is IMHO a bit suspicous but I kept it */ ASSIGN(timeZoneName,
for(a=0,b=0;standardName[a];a++) [NSString stringWithCharacters: standardName
{ length: wcslen(standardName)]);
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. */ /* Abbr generated here is IMHO
if (wcslen(daylightName)) * a bit suspicous but I kept it */
{ for (a = 0, b = 0; standardName[a]; a++)
int a,b; {
ASSIGN(daylightZoneName,[NSString stringWithCharacters:daylightName length:wcslen(daylightName)]); if (iswupper(standardName[a]))
standardName[b++] = standardName[a];
}
standardName[b] = L'\0';
ASSIGN(timeZoneNameAbbr,
[NSString stringWithCharacters: standardName
length: wcslen(standardName)]);
}
/* Abbr generated here is IMHO a bit suspicous but I kept it */ /* Set the daylight savings name
for(a=0,b=0;daylightName[a];a++) * for the time zone. */
{ if (wcslen(daylightName))
if (iswupper(daylightName[a])) {
daylightName[b++]=daylightName[a]; int a, b;
}
daylightName[b]=L'\0';
ASSIGN(daylightZoneNameAbbr,[NSString stringWithCharacters:daylightName length:wcslen(daylightName)]);
}
}
RegCloseKey(regKey);
}
}
}
free(wName); 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); RegCloseKey(regDirKey);
} }
return self; return self;
} }
@ -2328,7 +2347,7 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
{ {
return NO; return NO;
} }
} }
dow = ((int)((when / 86400.0) + GREGORIAN_REFERENCE)) % 7; dow = ((int)((when / 86400.0) + GREGORIAN_REFERENCE)) % 7;
if (dow < 0) if (dow < 0)
@ -2339,13 +2358,13 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
daylightdate = day - dow + DaylightDate.wDayOfWeek; daylightdate = day - dow + DaylightDate.wDayOfWeek;
maxdate = lastDayOfGregorianMonth(DaylightDate.wMonth, year)-7; maxdate = lastDayOfGregorianMonth(DaylightDate.wMonth, year)-7;
while (daylightdate > 7) while (daylightdate > 7)
daylightdate-=7; daylightdate -= 7;
if (daylightdate < 1) if (daylightdate < 1)
daylightdate += 7; daylightdate += 7;
count=DaylightDate.wDay; count = DaylightDate.wDay;
while (count>1 && daylightdate < maxdate) while (count > 1 && daylightdate < maxdate)
{ {
daylightdate+=7; daylightdate += 7;
count--; count--;
} }
if (day > daylightdate) if (day > daylightdate)
@ -2373,13 +2392,13 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
daylightdate = day - dow + StandardDate.wDayOfWeek; daylightdate = day - dow + StandardDate.wDayOfWeek;
maxdate = lastDayOfGregorianMonth(StandardDate.wMonth, year)-7; maxdate = lastDayOfGregorianMonth(StandardDate.wMonth, year)-7;
while (daylightdate > 7) while (daylightdate > 7)
daylightdate-=7; daylightdate -= 7;
if (daylightdate < 1) if (daylightdate < 1)
daylightdate += 7; daylightdate += 7;
count=StandardDate.wDay; count = StandardDate.wDay;
while (count>1 && daylightdate < maxdate) while (count > 1 && daylightdate < maxdate)
{ {
daylightdate+=7; daylightdate += 7;
count--; count--;
} }
if (day > daylightdate) if (day > daylightdate)