From 21ffd01f2b91ea9be04fa94176a40ec9ea1f8834 Mon Sep 17 00:00:00 2001 From: michael starke Date: Fri, 21 Mar 2014 01:56:45 +0100 Subject: [PATCH] Collection of modifiers and subsequent key presses implemented Extended tests for command creation --- MacPass/MPAutotypeCommand.m | 73 +++++++++++---------- MacPass/MPAutotypeKeyPress.h | 1 + MacPass/MPAutotypeKeyPress.m | 11 ++++ MacPassTests/KPKTestAutotypeNormalization.m | 14 ++++ 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/MacPass/MPAutotypeCommand.m b/MacPass/MPAutotypeCommand.m index 1d531a59..34a0d19d 100644 --- a/MacPass/MPAutotypeCommand.m +++ b/MacPass/MPAutotypeCommand.m @@ -107,21 +107,35 @@ } }]; NSUInteger lastLocation = 0; - MPAutotypeKeyPress *keyPress; + CGEventFlags collectedModifers = 0; for(NSValue *rangeValue in commandRanges) { NSRange commandRange = [rangeValue rangeValue]; /* All non-commands will get translated into paste commands */ if(commandRange.location > lastLocation) { /* If there were modifiers we need to use the next single stroke and make update the modifier command */ - if(keyPress) { - + if(collectedModifers) { + NSString *modifiedKey = [context.evaluatedCommand substringWithRange:NSMakeRange(lastLocation, 1)]; + MPAutotypeKeyPress *press = [[MPAutotypeKeyPress alloc] initWithModifierMask:collectedModifers character:modifiedKey]; + if(press) { + [commands addObject:press]; + } + collectedModifers = 0; + lastLocation++; + } + NSRange pasteRange = NSMakeRange(lastLocation, commandRange.location - lastLocation); + if(pasteRange.length > 0) { + NSString *pasteValue = [context.evaluatedCommand substringWithRange:NSMakeRange(lastLocation, commandRange.location - lastLocation)]; + // Determin if it's amodifier key, and collect them! + [self appendPasteCommandForContent:pasteValue toCommands:commands]; } - NSString *pasteValue = [context.evaluatedCommand substringWithRange:NSMakeRange(lastLocation, commandRange.location - lastLocation)]; - // Determin if it's amodifier key, and collect them! - [self appendPasteCommandForContent:pasteValue toCommands:commands]; } + /* Test for modifer Key */ NSString *commandString = [context.evaluatedCommand substringWithRange:commandRange]; - [self appendCommandForString:commandString toCommands:commands keyPressCommand:&keyPress]; + /* append commands for non-modifer keys */ + if(![self updateModifierMask:&collectedModifers forCommand:commandString]) { + [self appendCommandForString:commandString toCommands:commands activeModifer:collectedModifers]; + collectedModifers = 0; // Reset the modifers; + } lastLocation = commandRange.location + commandRange.length; } return commands; @@ -134,44 +148,33 @@ } } -+ (void)appendCommandForString:(NSString *)commandString toCommands:(NSMutableArray *)commands keyPressCommand:(MPAutotypeKeyPress **)keyPress { ++ (void)appendCommandForString:(NSString *)commandString toCommands:(NSMutableArray *)commands activeModifer:(CGEventFlags)flags { if(!commandString) { return; } - NSNumber *flagNumber = [self modifierCommands][commandString]; NSNumber *keyCodeNumber = [self keypressCommands][commandString]; - /* modifier key */ - if(flagNumber) { - if(keyPress == NULL) { - return; // We need a pointer to return the keypress! - } - CGEventFlags flags = [flagNumber eventFlagsValue]; - if(*keyPress == nil) { - *keyPress = [[MPAutotypeKeyPress alloc] initWithModifierMask:flags keyCode:0]; - [commands addObject:*keyPress]; - } - else { - NSAssert([*keyPress isKindOfClass:[MPAutotypeKeyPress class]], @"Invalid command supplied"); - (*keyPress).modifierMask |= flags; - } - } - /* key press */ - else if(keyCodeNumber) { + if(keyCodeNumber) { CGKeyCode keyCode = [keyCodeNumber keyCodeValue]; - /* we have no modifers collected */ - if(keyPress != NULL && keyPress == nil) { - *keyPress = [[MPAutotypeKeyPress alloc] initWithModifierMask:0 keyCode:keyCode]; - [commands addObject:*keyPress]; - } - /* modifers collected, set keycode */ - else if(keyPress) { - (*keyPress).keyCode = keyCode; - } + [commands addObject:[[MPAutotypeKeyPress alloc] initWithModifierMask:flags keyCode:keyCode]]; } } ++ (BOOL)updateModifierMask:(CGEventFlags *)mask forCommand:(NSString *)commandString { + NSAssert(mask != NULL, @"Input pointer missing!"); + if(mask == NULL) { + return NO; + } + NSNumber *flagNumber = [self modifierCommands][commandString]; + if(!flagNumber) { + return NO; // No modifier key, just leave + } + CGEventFlags flags = [flagNumber eventFlagsValue]; + *mask |= flags; + return YES; +} + - (void)sendPressKey:(CGKeyCode)keyCode modifierFlags:(CGEventFlags)flags { CGEventRef pressKey = CGEventCreateKeyboardEvent (NULL, keyCode, YES); CGEventRef releaseKey = CGEventCreateKeyboardEvent (NULL, keyCode, NO); diff --git a/MacPass/MPAutotypeKeyPress.h b/MacPass/MPAutotypeKeyPress.h index f8b7ad61..478a0009 100644 --- a/MacPass/MPAutotypeKeyPress.h +++ b/MacPass/MPAutotypeKeyPress.h @@ -17,5 +17,6 @@ @property (assign) CGKeyCode keyCode; - (instancetype)initWithModifierMask:(CGEventFlags)modiferMask keyCode:(CGKeyCode)code; +- (instancetype)initWithModifierMask:(CGEventFlags)modiferMask character:(NSString *)character; @end diff --git a/MacPass/MPAutotypeKeyPress.m b/MacPass/MPAutotypeKeyPress.m index c12687b9..297d1bed 100644 --- a/MacPass/MPAutotypeKeyPress.m +++ b/MacPass/MPAutotypeKeyPress.m @@ -20,6 +20,17 @@ return self; } +- (instancetype)initWithModifierMask:(CGEventFlags)modiferMask character:(NSString *)character { + CGKeyCode mappedKey = [MPKeyMapper keyCodeForCharacter:character]; + if(mappedKey == kMPUnknownKeyCode) { + self = nil; + } + else { + self = [self initWithModifierMask:modiferMask keyCode:mappedKey]; + } + return self; +} + - (void)execute { if(![self isValid]) { return; // no valid command. Stop. diff --git a/MacPassTests/KPKTestAutotypeNormalization.m b/MacPassTests/KPKTestAutotypeNormalization.m index 4db5dcd3..047ae9c3 100644 --- a/MacPassTests/KPKTestAutotypeNormalization.m +++ b/MacPassTests/KPKTestAutotypeNormalization.m @@ -10,6 +10,8 @@ #import "NSString+Commands.h" #import "MPAutotypeCommand.h" #import "MPAutotypeContext.h" +#import "MPAutotypePaste.h" +#import "MPAutotypeKeyPress.h" #import "KPKEntry.h" @@ -47,5 +49,17 @@ MPAutotypeContext *context = [[MPAutotypeContext alloc] initWithEntry:entry andSequence:@"{USERNAME}{TAB}{PASSWORD}{ENTER}"]; NSArray *commands = [MPAutotypeCommand commandsForContext:context]; + + XCTAssert([commands count] == 4); + XCTAssert([commands[0] isKindOfClass:[MPAutotypePaste class]]); + XCTAssert([commands[1] isKindOfClass:[MPAutotypeKeyPress class]]); + XCTAssert([commands[2] isKindOfClass:[MPAutotypePaste class]]); + XCTAssert([commands[3] isKindOfClass:[MPAutotypeKeyPress class]]); + + context = [[MPAutotypeContext alloc] initWithEntry:entry andSequence:@"^T{USERNAME}%+^{TAB}Whoo{PASSWORD}{ENTER}"]; + commands = [MPAutotypeCommand commandsForContext:context]; + + + XCTAssert([commands count] == 5); } @end