diff --git a/ChangeLog b/ChangeLog index 36539c1da..bc2d21fdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/Source/NSTimeZone.m b/Source/NSTimeZone.m index 0eec9976c..ebafcc9c7 100644 --- a/Source/NSTimeZone.m +++ b/Source/NSTimeZone.m @@ -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; iBias; - 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)