diff options
author | Max <post@wickenrode.com> | 2015-05-09 23:27:05 +0200 |
---|---|---|
committer | Max <post@wickenrode.com> | 2015-05-09 23:27:05 +0200 |
commit | 7dbcadc2c0523dc3c3bcc0a8cd7ceea9f44fc655 (patch) | |
tree | 9d96e97344b323109fa2f54f3bd6e65312da10f9 | |
parent | 4d82718f43d92f2ef2193dc603a4486f85fb1582 (diff) | |
download | sequelpro-7dbcadc2c0523dc3c3bcc0a8cd7ceea9f44fc655.tar.gz sequelpro-7dbcadc2c0523dc3c3bcc0a8cd7ceea9f44fc655.tar.bz2 sequelpro-7dbcadc2c0523dc3c3bcc0a8cd7ceea9f44fc655.zip |
Fix a possible crash caused by a use-after-free in some rare cases when closing a connection tab.
-rw-r--r-- | Source/NoodleLineNumberView.m | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/Source/NoodleLineNumberView.m b/Source/NoodleLineNumberView.m index 24b76be1..8b678434 100644 --- a/Source/NoodleLineNumberView.m +++ b/Source/NoodleLineNumberView.m @@ -59,6 +59,7 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); - (void)invalidateLineIndices; - (void)calculateLines; - (void)updateGutterThicknessConstants; +- (void)setRuleThicknessNumber:(NSNumber *)aNum; @end @@ -112,6 +113,7 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSObject cancelPreviousPerformRequestsWithTarget:self]; if (lineIndices) [lineIndices release]; if (textAttributes) [textAttributes release]; @@ -566,17 +568,23 @@ typedef NSRange (*RangeOfLineIMP)(id object, SEL selector, NSRange range); currentRuleThickness = newThickness; // Not a good idea to resize the view during calculations (which can happen during - // display). Do a delayed perform (using NSInvocation since arg is a float). - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(setRuleThickness:)]]; - [invocation setSelector:@selector(setRuleThickness:)]; - [invocation setTarget:self]; - [invocation setArgument:&newThickness atIndex:2]; - - [invocation performSelector:@selector(invoke) withObject:nil afterDelay:0.0]; + // display). Do a delayed perform. + [self performSelector:@selector(setRuleThicknessNumber:) withObject:[NSNumber numberWithFloat:newThickness] afterDelay:0.0]; } } } +- (void)setRuleThicknessNumber:(NSNumber *)aNum +{ + // We want to do a delayed perform, but setRuleThickness: does take a CGFloat + // and not an object. In the past we used NSInvocation to work around that, + // however that has one major issue: >>This class does not retain the arguments + // for the contained invocation by default.<< (NSInvocation doc). + // A perform with delay 0.0 is queued with the run loop, so a dealloc can very + // well happen before that! + [self setRuleThickness:[aNum floatValue]]; +} + - (void)updateGutterThicknessConstants { maxWidthOfGlyph1 = ceilf(MAX(DEFAULT_THICKNESS, maxWidthOfGlyph + RULER_MARGIN2)); |