diff --git a/ChangeLog b/ChangeLog index 26e947463..832030d6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,29 @@ +2011-02-10 Richard Frith-Macdonald + + * Source/GSSocketStream.m: + * Source/NSPropertyList.m: + * Source/NSUserDefaults.m: + * Source/NSException.m: + * Source/NSURL.m: + * Source/NSDecimalNumber.m: + * Source/Additions/GSMime.m: + * Source/GSFileHandle.m: + * Source/NSNumberFormatter.m: + * Tools/gdomap.c: + * Tools/HTMLLinker.m: + Fix a couple of minor/theoretical memory leaks and make other code + alterations to try to avoid clang static analyser reporting some + issues. + * Source/GSPrivate.h: + * Source/NSObject.m: + * Source/Additions/NSObject+GNUstepBase.m: + New code to provide a single location to cache information which + should exist for the lifetime of the process, and a function to + clean it up on process exit. Just a placeholder so far. + 2011-02-09 Stefan Bidigaray - * Source/NSTimeZone.m: ([-daylightSavingTimeOffsetForDate:]) Implemented. + * Source/NSTimeZone.m: ([-daylightSavingTimeOffsetForDate:]) Implement. 2011-02-09 Stefan Bidigaray diff --git a/Source/Additions/GSMime.m b/Source/Additions/GSMime.m index 9f69839c0..b0c4399e6 100644 --- a/Source/Additions/GSMime.m +++ b/Source/Additions/GSMime.m @@ -4175,6 +4175,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold, @"/?="]]; [m removeCharactersInString: @"."]; rfc2045Specials = [m copy]; + [m release]; whitespace = RETAIN([NSCharacterSet whitespaceAndNewlineCharacterSet]); if (NSArrayClass == 0) { diff --git a/Source/Additions/NSObject+GNUstepBase.m b/Source/Additions/NSObject+GNUstepBase.m index 2e36d479e..fd6c884d7 100644 --- a/Source/Additions/NSObject+GNUstepBase.m +++ b/Source/Additions/NSObject+GNUstepBase.m @@ -121,3 +121,9 @@ } @end + +/* See ../GSPrivate.h for details. + */ +#import "GSPrivate.h" +BaseCacheStruct GSBaseCache = { }; + diff --git a/Source/GSFileHandle.m b/Source/GSFileHandle.m index 3837460cd..37bc420cf 100644 --- a/Source/GSFileHandle.m +++ b/Source/GSFileHandle.m @@ -2174,7 +2174,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; - (NSString*) socketLocalAddress { NSString *str = nil; - struct sockaddr_in sin; + struct sockaddr_in sin = { 0 }; unsigned size = sizeof(sin); if (getsockname(descriptor, (struct sockaddr*)&sin, &size) == -1) @@ -2191,7 +2191,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; - (NSString*) socketLocalService { NSString *str = nil; - struct sockaddr_in sin; + struct sockaddr_in sin = { 0 }; unsigned size = sizeof(sin); if (getsockname(descriptor, (struct sockaddr*)&sin, &size) == -1) diff --git a/Source/GSPrivate.h b/Source/GSPrivate.h index 042db7462..3598813f5 100644 --- a/Source/GSPrivate.h +++ b/Source/GSPrivate.h @@ -523,5 +523,32 @@ GSPrivateIsCollectable(const void *ptr) GS_ATTRIB_PRIVATE; NSZone* GSAtomicMallocZone (void); +/* NB ... this is a placeholder for future cleanups of the code! + * + * GSBaseCache is a structure in which base library classes may cache private + * information expected to be present for the lifetime of the process. + * + * The NSObject class registers the BSBaseCacheCleanup() function to be called + * to clean it up on process termination, but we actually keep the cleanup + * code here so we can easily update it in sync with the structure definition. + * + * This structure is actually implemented in Additions/NSObject+GNUstepBase.m + * so that it can be accessed from the base-additions library as well as the + * base library. + */ +typedef struct { + // Add fields to hold cached values here +} BaseCacheStruct; +BaseCacheStruct GSBaseCache GS_ATTRIB_PRIVATE; + +#if defined(IN_NSOBJECT_M) +static void +GSBaseCacheCleanup(void) +{ + // Add code to clean up cached values here + return; +} +#endif + #endif /* _GSPrivate_h_ */ diff --git a/Source/GSSocketStream.m b/Source/GSSocketStream.m index 0afce5e98..490dd4955 100644 --- a/Source/GSSocketStream.m +++ b/Source/GSSocketStream.m @@ -1327,7 +1327,7 @@ setNonBlocking(SOCKET fd) { case AF_INET: { - struct sockaddr_in sin; + struct sockaddr_in sin = { 0 }; socklen_t size = sizeof(sin); if ([key isEqualToString: GSStreamLocalAddressKey]) @@ -1367,7 +1367,7 @@ setNonBlocking(SOCKET fd) #if defined(AF_INET6) case AF_INET6: { - struct sockaddr_in6 sin; + struct sockaddr_in6 sin = { 0 }; socklen_t size = sizeof(sin); if ([key isEqualToString: GSStreamLocalAddressKey]) diff --git a/Source/NSDecimalNumber.m b/Source/NSDecimalNumber.m index b2f84c94e..95a866e4e 100644 --- a/Source/NSDecimalNumber.m +++ b/Source/NSDecimalNumber.m @@ -165,9 +165,11 @@ static NSDecimalNumber *one; + (void) initialize { - NSDecimal d; + /* Initialize d to an empty structure to avoid compiler warnings. + * This also sets d.validNumber to NO ... which is what is actually needed. + */ + NSDecimal d = { 0 }; - d.validNumber = NO; notANumber = [[self alloc] initWithDecimal: d]; NSDecimalMax(&d); maxNumber = [[self alloc] initWithDecimal: d]; diff --git a/Source/NSException.m b/Source/NSException.m index 5b5922092..adb3179a3 100644 --- a/Source/NSException.m +++ b/Source/NSException.m @@ -968,7 +968,7 @@ callUncaughtHandler(id value) thread = GSCurrentThread(); handler = thread->_exception_handler; - if (handler == NULL) + if (NULL == handler) { static int recursion = 0; @@ -991,10 +991,12 @@ callUncaughtHandler(id value) */ callUncaughtHandler(self); } - - thread->_exception_handler = handler->next; - handler->exception = self; - longjmp(handler->jumpState, 1); + else + { + thread->_exception_handler = handler->next; + handler->exception = self; + longjmp(handler->jumpState, 1); + } } #endif } diff --git a/Source/NSNumberFormatter.m b/Source/NSNumberFormatter.m index 9e0b493da..16c4acd2d 100644 --- a/Source/NSNumberFormatter.m +++ b/Source/NSNumberFormatter.m @@ -968,13 +968,13 @@ static NSUInteger _defaultBehavior = 0; [intPartString insertString: [intPad substringWithRange: ipRange] atIndex: 0]; [intPartString replaceOccurrencesOfString: @"_" - withString: @" " - options: 0 - range: NSMakeRange(0, [intPartString length])]; + withString: @" " + options: 0 + range: NSMakeRange(0, [intPartString length])]; [intPartString replaceOccurrencesOfString: @"#" - withString: @"0" - options: 0 - range: NSMakeRange(0, [intPartString length])]; + withString: @"0" + options: 0 + range: NSMakeRange(0, [intPartString length])]; } // fix the thousands separators up if (displayThousandsSeparators && [intPartString length] > 3) @@ -982,9 +982,10 @@ static NSUInteger _defaultBehavior = 0; int index = [intPartString length]; while (0 < (index -= 3)) - { - [intPartString insertString: [self thousandSeparator] atIndex: index]; - } + { + [intPartString insertString: [self thousandSeparator] + atIndex: index]; + } } formattedNumber = [intPartString mutableCopy]; @@ -994,37 +995,37 @@ static NSUInteger _defaultBehavior = 0; { if (0 != decimalPlaces) { - NSMutableString *ms; + NSMutableString *ms; fracPart = [fracPart decimalNumberByMultiplyingByPowerOf10: - decimalPlaces]; + decimalPlaces]; ms = [[fracPart descriptionWithLocale: locale] mutableCopy]; [ms replaceOccurrencesOfString: @"0" - withString: @"" - options: (NSBackwardsSearch | NSAnchoredSearch) - range: NSMakeRange(0, [ms length])]; + withString: @"" + options: (NSBackwardsSearch | NSAnchoredSearch) + range: NSMakeRange(0, [ms length])]; if ([fracPad length] > [ms length]) { NSRange fpRange; fpRange = NSMakeRange([ms length], - ([fracPad length] - [ms length])); + ([fracPad length] - [ms length])); [ms appendString: - [fracPad substringWithRange: fpRange]]; + [fracPad substringWithRange: fpRange]]; [ms replaceOccurrencesOfString: @"#" - withString: @"" - options: (NSBackwardsSearch | NSAnchoredSearch) - range: NSMakeRange(0, [ms length])]; + withString: @"" + options: (NSBackwardsSearch | NSAnchoredSearch) + range: NSMakeRange(0, [ms length])]; [ms replaceOccurrencesOfString: @"#" - withString: @"0" - options: 0 - range: NSMakeRange(0, [ms length])]; + withString: @"0" + options: 0 + range: NSMakeRange(0, [ms length])]; [ms replaceOccurrencesOfString: @"_" - withString: @" " - options: 0 - range: NSMakeRange(0, [ms length])]; + withString: @" " + options: 0 + range: NSMakeRange(0, [ms length])]; } - fracPartString = AUTORELEASE(ms); + fracPartString = AUTORELEASE(ms); } else { diff --git a/Source/NSObject.m b/Source/NSObject.m index 272c389ed..657fc61e4 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -65,6 +65,7 @@ #include #endif +#define IN_NSOBJECT_M 1 #import "GSPrivate.h" @@ -945,6 +946,10 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak)); # endif #endif + /* Cleanup cached information on exit. + */ + atexit(GSBaseCacheCleanup); + #ifdef HAVE_LOCALE_H GSSetLocaleC(LC_ALL, ""); // Set up locale from environment. #endif @@ -2312,3 +2317,4 @@ objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak)); return [object methodSignatureForSelector: aSelector]; } @end + diff --git a/Source/NSPropertyList.m b/Source/NSPropertyList.m index 358002647..f46e3cc04 100644 --- a/Source/NSPropertyList.m +++ b/Source/NSPropertyList.m @@ -2160,7 +2160,7 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step, #define STRIDE_FACTOR 3 unsigned c,d, stride; BOOL found; - NSComparisonResult (*comp)(id, SEL, id) = 0; + NSComparisonResult (*comp)(id, SEL, id); unsigned int count = numKeys; #ifdef GSWARN BOOL badComparison = NO; @@ -2171,7 +2171,15 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step, { stride = stride * STRIDE_FACTOR + 1; } - lastClass = 0; + + /* Initialise lastClass and comparison method to those of the + * first object to be sorted ... this is done here to avoid + * bogus compiler warnings. + */ + lastClass = object_getClass(keys[0]); + comp = (NSComparisonResult (*)(id, SEL, id)) + [keys[0] methodForSelector: @selector(compare:)]; + while (stride > (STRIDE_FACTOR - 1)) { // loop to sort for each value of stride diff --git a/Source/NSURL.m b/Source/NSURL.m index df4f1031e..73d5d306d 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -162,6 +162,7 @@ static char *unescape(const char *from, char * to); */ static char *buildURL(parsedURL *base, parsedURL *rel, BOOL standardize) { + const char *rpath; char *buf; char *ptr; char *tmp; @@ -189,8 +190,13 @@ static char *buildURL(parsedURL *base, parsedURL *rel, BOOL standardize) } if (rel->path != 0) { - len += strlen(rel->path) + 1; // path + rpath = rel->path; } + else + { + rpath = ""; + } + len += strlen(rpath) + 1; // path if (base != 0 && base->path != 0) { len += strlen(base->path) + 1; // path @@ -267,13 +273,13 @@ static char *buildURL(parsedURL *base, parsedURL *rel, BOOL standardize) { *tmp++ = '/'; } - strcpy(tmp, rel->path); + strcpy(tmp, rpath); } else if (base == 0) { - strcpy(tmp, rel->path); + strcpy(tmp, rpath); } - else if (rel->path[0] == 0) + else if (rpath[0] == 0) { if (base->hasNoPath == NO) { @@ -293,7 +299,7 @@ static char *buildURL(parsedURL *base, parsedURL *rel, BOOL standardize) tmp += (end - start); } *tmp++ = '/'; - strcpy(tmp, rel->path); + strcpy(tmp, rpath); } if (standardize == YES) @@ -394,7 +400,6 @@ static char *buildURL(parsedURL *base, parsedURL *rel, BOOL standardize) { *ptr++ = '#'; strcpy(ptr, rel->fragment); - ptr = &ptr[strlen(ptr)]; } return buf; diff --git a/Source/NSUserDefaults.m b/Source/NSUserDefaults.m index 9ab8517d3..a513d3492 100644 --- a/Source/NSUserDefaults.m +++ b/Source/NSUserDefaults.m @@ -1150,8 +1150,9 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ } else { - dict = [obj mutableCopy]; + dict = obj = [obj mutableCopy]; [_persDomains setObject: dict forKey: processName]; + [obj release]; } [dict removeObjectForKey: defaultName]; [self __changePersistentDomain: processName]; @@ -1575,6 +1576,7 @@ static BOOL isLocked = NO; { NSLog(@"Failed to lock user defaults database even after " @"breaking old locks!"); + RELEASE(arp); return NO; } @@ -1901,7 +1903,7 @@ NSLog(@"Creating empty user defaults database"); - (NSDictionary*) dictionaryRepresentation { - NSDictionary *rep = nil; + NSDictionary *rep; [_lock lock]; NS_DURING @@ -1937,16 +1939,17 @@ NSLog(@"Creating empty user defaults database"); } _dictionaryRep = [dictRep makeImmutableCopyOnFail: NO]; } - rep = RETAIN(_dictionaryRep); + rep = [[_dictionaryRep retain] autorelease]; [_lock unlock]; } NS_HANDLER { + rep = nil; [_lock unlock]; [localException raise]; } NS_ENDHANDLER - return AUTORELEASE(rep); + return rep; } - (void) registerDefaults: (NSDictionary*)newVals diff --git a/Tools/HTMLLinker.m b/Tools/HTMLLinker.m index e480ec26e..d056abc02 100644 --- a/Tools/HTMLLinker.m +++ b/Tools/HTMLLinker.m @@ -1307,8 +1307,8 @@ int main (int argc, char** argv, char** env) HTMLDirectoryEnumerator *e; NSString *filename; - e = [HTMLDirectoryEnumerator alloc]; - e = [e initWithBasePath: arg]; + e = [[[HTMLDirectoryEnumerator alloc] + initWithBasePath: arg] autorelease]; [e setReturnsAbsolutePaths: YES]; while ((filename = [e nextObject]) != nil) diff --git a/Tools/gdomap.c b/Tools/gdomap.c index ce918470f..4b1b59498 100644 --- a/Tools/gdomap.c +++ b/Tools/gdomap.c @@ -2065,7 +2065,7 @@ init_probe() { int broadcast = 0; int elen = 0; - struct in_addr *other; + struct in_addr *other = 0; struct in_addr sin; int high = 0; int low = 0;