From f486bb41d65924a2bd4d9d7bd3f25dc9375d123a Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Fri, 19 Jun 2009 23:09:03 +0200 Subject: [PATCH] Avoid exceptions in charRangeForRow::: --- src/MacVim/MMTextStorage.m | 22 +++++++++++++++++----- src/MacVim/MMTextView.m | 2 ++ src/MacVim/MMTypesetter.m | 4 ++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/MacVim/MMTextStorage.m b/src/MacVim/MMTextStorage.m index 82ad1400e1..030c1daf2c 100644 --- a/src/MacVim/MMTextStorage.m +++ b/src/MacVim/MMTextStorage.m @@ -253,6 +253,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; foregroundColor:(NSColor *)fg backgroundColor:(NSColor *)bg specialColor:(NSColor *)sp { + //NSLog(@"%@(%d,%d,%d,%d)", string, row, col, cells, flags); //NSLog(@"replaceString:atRow:%d column:%d withFlags:%d " // "foreground:%@ background:%@ special:%@", // row, col, flags, fg, bg, sp); @@ -1009,15 +1010,16 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; return NSMakeRange(row*(actualColumns+1) + col, cells); NSString *string = [attribString string]; + unsigned stringLen = [string length]; NSRange r, range = { NSNotFound, 0 }; - unsigned idx, rowEnd; + unsigned idx; int i; if (row < 0 || row >= actualRows || col < 0 || col >= actualColumns || col+cells > actualColumns) { #if MM_TS_PARANOIA_LOG NSLog(@"%s row=%d col=%d cells=%d is out of range (length=%d)", - _cmd, row, col, cells, [string length]); + _cmd, row, col, cells, stringLen); #endif return range; } @@ -1029,12 +1031,12 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; for (i = 0; i < row; ++i, ++cache) idx += cache->length; - rowEnd = idx + cache->length; + int rowEnd = idx + cache->length; #else // Locate the beginning of the row by scanning for EOL characters. r.location = 0; for (i = 0; i < row; ++i) { - r.length = [string length] - r.location; + r.length = stringLen - r.location; r = [string rangeOfString:@"\n" options:NSLiteralSearch range:r]; if (NSNotFound == r.location) return range; @@ -1070,6 +1072,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; if (col > i) { // Forward search while (col > i) { + if (idx >= stringLen) + return NSMakeRange(NSNotFound, 0); r = [string rangeOfComposedCharacterSequenceAtIndex:idx]; // Wide chars take up two display cells. @@ -1084,6 +1088,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; } else if (col < i) { // Backward search while (col < i) { + if (idx-1 >= stringLen) + return NSMakeRange(NSNotFound, 0); r = [string rangeOfComposedCharacterSequenceAtIndex:idx-1]; idx -= r.length; --i; @@ -1111,6 +1117,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; // Forward search while (col > i) { + if (idx >= stringLen) + return NSMakeRange(NSNotFound, 0); r = [string rangeOfComposedCharacterSequenceAtIndex:idx]; // Wide chars take up two display cells. @@ -1131,6 +1139,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; #else idx = r.location; for (i = 0; i < col; ++i) { + if (idx >= stringLen) + return NSMakeRange(NSNotFound, 0); r = [string rangeOfComposedCharacterSequenceAtIndex:idx]; // Wide chars take up two display cells. @@ -1146,6 +1156,8 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; // Count the number of characters that cover the cells. range.location = idx; for (i = 0; i < cells; ++i) { + if (idx >= stringLen) + return NSMakeRange(NSNotFound, 0); r = [string rangeOfComposedCharacterSequenceAtIndex:idx]; // Wide chars take up two display cells. @@ -1174,7 +1186,7 @@ static NSString *MMWideCharacterAttributeName = @"MMWideChar"; } #endif - if (NSMaxRange(range) > [string length]) { + if (NSMaxRange(range) > stringLen) { NSLog(@"INTERNAL ERROR [%s] : row=%d col=%d cells=%d --> range=%@", _cmd, row, col, cells, NSStringFromRange(range)); range.location = NSNotFound; diff --git a/src/MacVim/MMTextView.m b/src/MacVim/MMTextView.m index 1a8a87ccf8..bd1d71dbcf 100644 --- a/src/MacVim/MMTextView.m +++ b/src/MacVim/MMTextView.m @@ -63,10 +63,12 @@ NSTypesetter *typesetter = [[MMTypesetter alloc] init]; [lm setTypesetter:typesetter]; [typesetter release]; +#if MM_USE_ROW_CACHE } else if ([typesetterString isEqual:@"MMTypesetter2"]) { NSTypesetter *typesetter = [[MMTypesetter2 alloc] init]; [lm setTypesetter:typesetter]; [typesetter release]; +#endif // MM_USE_ROW_CACHE } else { // Only MMTypesetter supports different cell width multipliers. [[NSUserDefaults standardUserDefaults] diff --git a/src/MacVim/MMTypesetter.m b/src/MacVim/MMTypesetter.m index 481b29db31..746f181e8e 100644 --- a/src/MacVim/MMTypesetter.m +++ b/src/MacVim/MMTypesetter.m @@ -89,6 +89,8 @@ +#if MM_USE_ROW_CACHE + @implementation MMTypesetter2 // @@ -188,3 +190,5 @@ @end // MMTypesetter2 +#endif // MM_USE_ROW_CACHE +