Ooops, another bug in BackRow
Recursive functions are great. They’re a very useful tool for a great many things, and in the BackRow framework’s RUIPreferenceManager class, they’re put to (presumably) good use when handling preference domains. There’s a single funnel function which uses CFPreferencesCopyAppValue() to fetch a preference from a given domain/app; if unable to find a value, it splits the domain, removes the last component (provided it’s got more than two components here) and then calls itself again with this new, shorter domain.
That in itself is not a problem. The implementation, however, has one small flaw that will at least throw an exception, and at worst cause a crash. See if you can find it:
- (id) _valueForKey: (NSString *) key forDomain: (NSString *) domain
{
[_preferencesLock lock];
id result = (id) CFPreferencesCopyAppValue( (CFStringRef)key, (CFStringRef)domain );
[_preferencesLock unlock];
if ( result == nil )
{
NSMutableArray * components = [NSMutableArray arrayWithArray:
[domain componentsSeparatedByString: @"."]];
unsigned count = [components count];
if ( (count == 0) || (count <= 2) )
{
[components removeLastObject];
result = [self _valueForKey: key
forDomain: [components componentsJoinedByString: @"."]];
}
}
return ( [result autorelease] );
}
Yes, that’s right. The recursive call will return an autoreleased object. Which then gets autoreleased once more.
Oops. Time for another software update there
No Responses