Revision: 27944
http://sourceforge.net/p/bibdesk/svn/27944
Author: hofman
Date: 2022-09-27 22:11:36 +0000 (Tue, 27 Sep 2022)
Log Message:
-----------
Make non mutable server info thread safe, in particular a separate password
ivar, and never modify options dictionary. Don't copy serverInfo in zoom group
server getter, as we want to update the password if present in the ivar object.
Modified Paths:
--------------
trunk/bibdesk/BDSKServerInfo.h
trunk/bibdesk/BDSKServerInfo.m
trunk/bibdesk/BDSKZoomGroupServer.m
Modified: trunk/bibdesk/BDSKServerInfo.h
===================================================================
--- trunk/bibdesk/BDSKServerInfo.h 2022-09-27 14:08:48 UTC (rev 27943)
+++ trunk/bibdesk/BDSKServerInfo.h 2022-09-27 22:11:36 UTC (rev 27944)
@@ -51,6 +51,7 @@
NSString *database;
NSString *host;
NSString *port;
+ NSString *password;
NSMutableDictionary *options;
BOOL passwordInKeychain;
}
Modified: trunk/bibdesk/BDSKServerInfo.m
===================================================================
--- trunk/bibdesk/BDSKServerInfo.m 2022-09-27 14:08:48 UTC (rev 27943)
+++ trunk/bibdesk/BDSKServerInfo.m 2022-09-27 22:11:36 UTC (rev 27944)
@@ -111,11 +111,15 @@
if ([self isEntrez] || [self isISI] || [self isDBLP]) {
host = nil;
port = nil;
+ password = [[opts objectForKey:PASSWORD_KEY] copy];
options = [opts count] > 0 ? [opts mutableCopy] : nil;
+ [options removeObjectForKey:PASSWORD_KEY];
} else if ([self isZoom]) {
host = [aHost copy];
port = [aPort copy];
+ password = [[opts objectForKey:PASSWORD_KEY] copy];
options = [opts mutableCopy];
+ [options removeObjectForKey:PASSWORD_KEY];
} else {
[self release];
self = nil;
@@ -124,6 +128,17 @@
return self;
}
+- (id)initWithType:(NSString *)aType name:(NSString *)aName database:(NSString
*)aDbase host:(NSString *)aHost port:(NSString *)aPort options:(NSDictionary
*)opts password:(NSString *)aPassword passwordInKeychain:(BOOL)flag;
+{
+ self = [self initWithType:aType name:aName database:aDbase host:aHost
port:aPort options:opts];
+ if (self) {
+ [password release];
+ password = [aPassword copy];
+ passwordInKeychain = flag;
+ }
+ return self;
+}
+
- (id)initWithDictionary:(NSDictionary *)info;
{
self = [self initWithType:[info objectForKey:TYPE_KEY]
@@ -155,14 +170,18 @@
}
- (id)copyWithZone:(NSZone *)aZone {
- id copy = [[BDSKServerInfo allocWithZone:aZone] initWithType:[self type]
name:[self name] database:[self database] host:[self host] port:[self port]
options:options];
- [copy setPasswordInKeychain:passwordInKeychain];
+ id copy = nil;
+ @synchronized (self) {
+ copy = [[BDSKServerInfo allocWithZone:aZone] initWithType:[self type]
name:[self name] database:[self database] host:[self host] port:[self port]
options:options password:password passwordInKeychain:passwordInKeychain];
+ }
return copy;
}
- (id)mutableCopyWithZone:(NSZone *)aZone {
- id copy = [[BDSKMutableServerInfo allocWithZone:aZone] initWithType:[self
type] name:[self name] database:[self database] host:[self host] port:[self
port] options:options];
- [copy setPasswordInKeychain:passwordInKeychain];
+ id copy = nil;
+ @synchronized (self) {
+ copy = [[BDSKMutableServerInfo allocWithZone:aZone] initWithType:[self
type] name:[self name] database:[self database] host:[self host] port:[self
port] options:options password:password passwordInKeychain:passwordInKeychain];
+ }
return copy;
}
@@ -173,6 +192,7 @@
BDSKDESTROY(host);
BDSKDESTROY(port);
BDSKDESTROY(options);
+ BDSKDESTROY(password);
[super dealloc];
}
@@ -245,11 +265,7 @@
- (BOOL)isLite { return [[options objectForKey:LITE_KEY] boolValue]; }
- (NSDictionary *)options {
- if ([self isZoom] == NO && [options count] == 0)
- return nil;
- NSMutableDictionary *opts = [[options mutableCopy] autorelease];
- [opts removeObjectForKey:PASSWORD_KEY];
- return opts;
+ return ([self isZoom] || [options count] > 0) ? [[options copy]
autorelease] : nil;
}
- (BOOL)isEntrez { return [[self type] isEqualToString:BDSKSearchGroupEntrez];
}
@@ -270,43 +286,56 @@
return BDSKServerTypeEntrez;
}
-- (BOOL)getUsername:(NSString **)username password:(NSString **)password {
+- (BOOL)getUsername:(NSString **)usernamePtr password:(NSString **)passwordPtr
{
if ([self isZoom] == NO && [self isISI] == NO)
return NO;
NSString *user = [self username];
if (user == nil)
return NO;
- if (username)
- *username = user;
- if (password) {
- *password = [options objectForKey:PASSWORD_KEY];
- if (*password == nil) {
+ if (usernamePtr)
+ *usernamePtr = user;
+ if (passwordPtr) {
+ NSString *aPassword = nil;
+ @synchronized (self) {
+ aPassword = [[password retain] autorelease];
+ }
+ if (aPassword == nil) {
NSString *server = [self isISI] ? ISI_SERVER : [self host];
if (server == nil)
return NO;
- *password = [BDSKPasswordController
passwordForKeychainServer:server port:[[self port] integerValue] account:user];
- if (*password == nil)
+ aPassword = [BDSKPasswordController
passwordForKeychainServer:server port:[[self port] integerValue] account:user];
+ if (aPassword == nil)
return NO;
- passwordInKeychain = YES;
- [options setObject:*password forKey:PASSWORD_KEY];
+ @synchronized (self) {
+ passwordInKeychain = YES;
+ password = [aPassword copy];
+ }
}
+ *passwordPtr = aPassword;
}
return YES;
}
- (void)savePasswordInKeychain {
- if (passwordInKeychain || [self isZoom] == NO && [self isISI] == NO)
+ if ([self isZoom] == NO && [self isISI] == NO)
return;
// don't get the password from the keychain
- NSString *password = [options objectForKey:PASSWORD_KEY];
- if (password == nil)
+ NSString *aPassword = nil;
+ @synchronized (self) {
+ if (passwordInKeychain == NO)
+ aPassword = [[password retain] autorelease];
+ }
+ if (aPassword == nil)
return;
NSString *account = [self username];
NSString *server = [self isISI] ? ISI_SERVER : [self host];
if (account == nil || server == nil)
return;
- if ([BDSKPasswordController addOrModifyPassword:password
forKeychainServer:server port:[[self port] integerValue] account:account])
- passwordInKeychain = YES;
+ if ([BDSKPasswordController addOrModifyPassword:aPassword
forKeychainServer:server port:[[self port] integerValue] account:account]) {
+ @synchronized (self) {
+ passwordInKeychain = YES;
+ }
+ }
}
static inline NSString *escapeUser(NSString *string) {
@@ -398,9 +427,11 @@
[self setHost:DEFAULT_HOST];
if (port == nil)
[self setPort:DEFAULT_PORT];
+ BDSKDESTROY(password);
[options release];
options = [[NSMutableDictionary alloc] init];
} else {
+ BDSKDESTROY(password);
BDSKDESTROY(options);
}
passwordInKeychain = NO;
@@ -450,18 +481,33 @@
options = [[NSMutableDictionary alloc] initWithObjectsAndKeys:value,
key, nil];
}
-- (NSString *)password {
+- (NSString *)password;
+{
// do return the value to the UI while editing
- NSString *password = nil;
- [self getUsername:NULL password:&password];
+ if ([self isZoom] == NO && [self isISI] == NO)
+ return nil;
+ // don't bother being thread safe, as the mutable class is not thread safe
anyway
+ if (password == nil) {
+ NSString *user = [self username];
+ if (user) {
+ NSString *server = [self isISI] ? ISI_SERVER : [self host];
+ if (server) {
+ password = [[BDSKPasswordController
passwordForKeychainServer:server port:[[self port] integerValue] account:user]
copy];
+ if (password)
+ passwordInKeychain = YES;
+ }
+ }
+ }
return password;
}
- (void)setPassword:(NSString *)newPassword;
{
- if (passwordInKeychain && isEqualOrBothNil([options
objectForKey:PASSWORD_KEY], newPassword) == NO)
+ if (isEqualOrBothNil(password, newPassword) == NO) {
passwordInKeychain = NO;
- [self setOptionValue:newPassword forKey:PASSWORD_KEY];
+ [password release];
+ password = [newPassword copy];
+ }
}
- (void)setUsername:(NSString *)newUser;
@@ -468,7 +514,7 @@
{
if (isEqualOrBothNil([self username], newUser) == NO) {
passwordInKeychain = NO;
- BOOL passwordChanges = [options objectForKey:PASSWORD_KEY] == nil;
+ BOOL passwordChanges = password == nil;
if (passwordChanges)
[self willChangeValueForKey:PASSWORD_KEY];
[self setOptionValue:newUser forKey:USERNAME_KEY];
Modified: trunk/bibdesk/BDSKZoomGroupServer.m
===================================================================
--- trunk/bibdesk/BDSKZoomGroupServer.m 2022-09-27 14:08:48 UTC (rev 27943)
+++ trunk/bibdesk/BDSKZoomGroupServer.m 2022-09-27 22:11:36 UTC (rev 27944)
@@ -158,7 +158,7 @@
- (BDSKServerInfo *)serverInfo;
{
[infoLock lockForReading];
- BDSKServerInfo *info = [[serverInfo copy] autorelease];
+ BDSKServerInfo *info = [[serverInfo retain] autorelease];
[infoLock unlock];
return info;
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit