diff --git a/KeePassKit b/KeePassKit index 1ec6abf2..283e12d2 160000 --- a/KeePassKit +++ b/KeePassKit @@ -1 +1 @@ -Subproject commit 1ec6abf2fa63959045f3eab2b49bac1d57cd3b68 +Subproject commit 283e12d23ec7314d62c31c4a826a117b599bfd4a diff --git a/MacPass/MPAutotypeCommand.m b/MacPass/MPAutotypeCommand.m index 6fe99e97..37a57185 100644 --- a/MacPass/MPAutotypeCommand.m +++ b/MacPass/MPAutotypeCommand.m @@ -20,37 +20,30 @@ @implementation MPAutotypeCommand + (NSArray *)commandsForContext:(MPAutotypeContext *)context { - if([context isValid]) { + if(![context isValid]) { return nil; } - NSMutableArray *commands = [[NSMutableArray alloc] initWithCapacity:10]; - BOOL outsideCommand = YES; - NSString *unparsedCommand = context.normalizedCommand; - while(YES) { - /* Outside Command */ - if(outsideCommand) { - NSRange openingBracketRange = [unparsedCommand rangeOfString:@"{"]; - if(openingBracketRange.location != NSNotFound && openingBracketRange.length == 1) { - outsideCommand = NO; - NSString *skipped = [unparsedCommand substringToIndex:openingBracketRange.location]; - unparsedCommand = [unparsedCommand substringFromIndex:openingBracketRange.location + 1]; - } - else { - /* No more opeing brackets, stop - or none at all */ - [self appendPasteCommandForContent:unparsedCommand toCommands:commands]; - break; - } + NSUInteger reserverd = [context.normalizedCommand length] / 4; + NSMutableArray *commands = [[NSMutableArray alloc] initWithCapacity:reserverd]; + NSMutableArray __block *commandRanges = [[NSMutableArray alloc] initWithCapacity:reserverd]; + NSRegularExpression *commandRegExp = [[NSRegularExpression alloc] initWithPattern:@"\\{[^\\}]+\\}" options:NSRegularExpressionCaseInsensitive error:0]; + NSAssert(commandRegExp, @"RegExp is constant. Has to work all the time"); + [commandRegExp enumerateMatchesInString:context.normalizedCommand options:0 range:NSMakeRange(0, [context.normalizedCommand length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { + @autoreleasepool { + [commandRanges addObject:[NSValue valueWithRange:result.range]]; } - /* Inside Command */ - else { - NSRange closingBracketRange = [unparsedCommand rangeOfString:@"}"]; - if(closingBracketRange.location == NSNotFound || closingBracketRange.length != 1) { - return nil; - } - outsideCommand = NO; + }]; + NSUInteger skipped = 0; + for(NSValue *rangeValue in commandRanges) { + NSRange range = [rangeValue rangeValue]; + /* All non-commands will get translated into paste commands */ + if(range.location > skipped) { + NSString *pasteValue = [context.normalizedCommand substringWithRange:NSMakeRange(skipped, range.location - skipped)]; + [self appendPasteCommandForContent:pasteValue toCommands:commands]; + skipped = range.location; } } - return commands; + return nil; } + (MPAutotypeCommand *)appendPasteCommandForContent:(NSString *)pasteContent toCommands:(NSMutableArray *)commands { diff --git a/MacPass/MPAutotypeContext.h b/MacPass/MPAutotypeContext.h index 5844227f..7b7a5097 100644 --- a/MacPass/MPAutotypeContext.h +++ b/MacPass/MPAutotypeContext.h @@ -24,8 +24,8 @@ /** * The Autotype command as it's supplied by the entry */ -@property (nonatomic, copy) NSString *command; -@property (nonatomic, copy) NSString *normalizedCommand; +@property (nonatomic, readonly, copy) NSString *command; +@property (nonatomic, readonly, copy) NSString *normalizedCommand; /** * Designated initializer @@ -45,4 +45,6 @@ */ - (BOOL)isValid; +- (NSString *)evaluatedCommand; + @end diff --git a/MacPass/MPAutotypeContext.m b/MacPass/MPAutotypeContext.m index 63864206..f1ceca3a 100644 --- a/MacPass/MPAutotypeContext.m +++ b/MacPass/MPAutotypeContext.m @@ -40,8 +40,18 @@ return copy; } + - (BOOL)isValid { return (self.normalizedCommand != nil); } +- (NSString *)evaluatedCommand { + static NSString *evaluated; + if(!evaluated) { + NSString *placeholderFilled = [self.normalizedCommand evaluatePlaceholderWithEntry:self.entry]; + evaluated = [placeholderFilled resolveReferencesWithTree:self.entry.tree]; + } + return evaluated; +} + @end diff --git a/MacPassTests/KPKTestAutotypeNormalization.m b/MacPassTests/KPKTestAutotypeNormalization.m index 270f78f6..4db5dcd3 100644 --- a/MacPassTests/KPKTestAutotypeNormalization.m +++ b/MacPassTests/KPKTestAutotypeNormalization.m @@ -8,6 +8,10 @@ #import #import "NSString+Commands.h" +#import "MPAutotypeCommand.h" +#import "MPAutotypeContext.h" + +#import "KPKEntry.h" @interface KPKTestAutotypeNormalization : XCTestCase @@ -34,4 +38,14 @@ XCTAssertTrue([@"{}{}{}{}{}{ }ThisIsValid{}{STOP}" validateCommmand]); } +- (void)testCommandCreation { + KPKEntry *entry = [[KPKEntry alloc] init]; + entry.title = @"Title"; + entry.url = @"www.myurl.com"; + entry.username = @"Username"; + entry.password = @"Password"; + + MPAutotypeContext *context = [[MPAutotypeContext alloc] initWithEntry:entry andSequence:@"{USERNAME}{TAB}{PASSWORD}{ENTER}"]; + NSArray *commands = [MPAutotypeCommand commandsForContext:context]; +} @end