aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <post@wickenrode.com>2015-05-09 23:27:05 +0200
committerMax <post@wickenrode.com>2015-05-09 23:27:05 +0200
commit7dbcadc2c0523dc3c3bcc0a8cd7ceea9f44fc655 (patch)
tree9d96e97344b323109fa2f54f3bd6e65312da10f9
parent4d82718f43d92f2ef2193dc603a4486f85fb1582 (diff)
downloadsequelpro-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.m22
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));