diff --git a/ChangeLog b/ChangeLog index e9ea8f6bd..d2f713dbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-04-12 Richard Frith-Macdonald + + * Source/NSRegularExpression.m: Check for bad range from ICU and + flag an internal error if we see it; mimic OSX behavior when a + range limited match fails. + 2014-04-11 Fred Kiefer * Headers/Foundation/NSXMLNodeOptions.h: Add new 10.7 options. diff --git a/Headers/Foundation/Foundation.h b/Headers/Foundation/Foundation.h index 120beadb7..00267ef28 100644 --- a/Headers/Foundation/Foundation.h +++ b/Headers/Foundation/Foundation.h @@ -114,6 +114,7 @@ #import #import #import +#import #import #import #import diff --git a/Headers/Foundation/MISSING b/Headers/Foundation/MISSING index 009eb9343..2ea839da4 100644 --- a/Headers/Foundation/MISSING +++ b/Headers/Foundation/MISSING @@ -46,8 +46,6 @@ Foundation: - - @@ -1017,4 +1015,4 @@ Good headers: - \ No newline at end of file + diff --git a/Source/NSRegularExpression.m b/Source/NSRegularExpression.m index 2fc0194dc..df0cd12b3 100644 --- a/Source/NSRegularExpression.m +++ b/Source/NSRegularExpression.m @@ -300,6 +300,11 @@ prepareResult(NSRegularExpression *regex, NSUInteger start = uregex_start(r, i, s); NSUInteger end = uregex_end(r, i, s); + if (end < start) + { + flags |= NSMatchingInternalError; + end = start = NSNotFound; + } ranges[i] = NSMakeRange(start, end-start); } if (uregex_hitEnd(r, s)) @@ -344,7 +349,8 @@ prepareResult(NSRegularExpression *regex, NSTextCheckingResult *result; flags = prepareResult(self, r, ranges, groups, &s); - result = [NSTextCheckingResult + result = (flags & NSMatchingInternalError) ? nil + : [NSTextCheckingResult regularExpressionCheckingResultWithRanges: ranges count: groups regularExpression: self]; @@ -359,7 +365,8 @@ prepareResult(NSRegularExpression *regex, NSTextCheckingResult *result; flags = prepareResult(self, r, ranges, groups, &s); - result = [NSTextCheckingResult + result = (flags & NSMatchingInternalError) ? nil + : [NSTextCheckingResult regularExpressionCheckingResultWithRanges: ranges count: groups regularExpression: self]; @@ -403,7 +410,8 @@ prepareResult(NSRegularExpression *regex, NSTextCheckingResult *result; flags = prepareResult(self, r, ranges, groups, &s); - result = [NSTextCheckingResult + result = (flags & NSMatchingInternalError) ? nil + : [NSTextCheckingResult regularExpressionCheckingResultWithRanges: ranges count: groups regularExpression: self]; @@ -418,7 +426,8 @@ prepareResult(NSRegularExpression *regex, NSTextCheckingResult *result; flags = prepareResult(self, r, ranges, groups, &s); - result = [NSTextCheckingResult + result = (flags & NSMatchingInternalError) ? nil + : [NSTextCheckingResult regularExpressionCheckingResultWithRanges: ranges count: groups regularExpression: self]; @@ -603,8 +612,11 @@ prepareResult(NSRegularExpression *regex, FAKE_BLOCK_HACK(result, { - prepareResult(self, r, ranges, groups, &s); - result = [NSTextCheckingResult + uint32_t flags; + + flags = prepareResult(self, r, ranges, groups, &s); + result = (flags & NSMatchingInternalError) ? nil + : [NSTextCheckingResult regularExpressionCheckingResultWithRanges: ranges count: groups regularExpression: self]; @@ -624,13 +636,18 @@ prepareResult(NSRegularExpression *regex, FAKE_BLOCK_HACK(array, { NSTextCheckingResult *result = NULL; + uint32_t flags; - prepareResult(self, r, ranges, groups, &s); - result = [NSTextCheckingResult + flags = prepareResult(self, r, ranges, groups, &s); + result = (flags & NSMatchingInternalError) ? nil + : [NSTextCheckingResult regularExpressionCheckingResultWithRanges: ranges count: groups regularExpression: self]; - [array addObject: result]; + if (nil != result) + { + [array addObject: result]; + } }); return array; } diff --git a/Tests/base/NSString/regex.m b/Tests/base/NSString/regex.m index b999e3be7..253ea7c9c 100644 --- a/Tests/base/NSString/regex.m +++ b/Tests/base/NSString/regex.m @@ -1,21 +1,45 @@ #import +#import #import "ObjectTesting.h" int main(void) { - [NSAutoreleasePool new]; - START_SET("NSString + regex") + [NSAutoreleasePool new]; + START_SET("NSString + regex") + #if !(__APPLE__ || GS_USE_ICU) - SKIP("NSRegularExpression not built, please install libicu") + SKIP("NSRegularExpression not built, please install libicu") #else - NSString *regex = @"abcd*"; - NSString *source = @"abcdddddd e f g"; - NSRange r = [source rangeOfString: regex options: NSRegularExpressionSearch]; - PASS(r.length == 9, "Correct length for regex, expected 9 got %d", (int)r.length); - regex = @"aBcD*"; - r = [source rangeOfString: regex options: (NSRegularExpressionSearch | NSCaseInsensitiveSearch)]; - PASS(r.length == 9, "Correct length for regex, expected 9 got %d", (int)r.length); + NSRegularExpression *expr; + NSString *regex; + NSString *source; + NSInteger index; + NSRange r; + + source = @"abcdddddd e f g"; + + regex = @"abcd*"; + r = [source rangeOfString: regex options: NSRegularExpressionSearch]; + PASS(r.length == 9, "Correct length for regex, expected 9 got %d", + (int)r.length); + + regex = @"aBcD*"; + r = [source rangeOfString: regex + options: (NSRegularExpressionSearch | NSCaseInsensitiveSearch)]; + PASS(r.length == 9, "Correct length for regex, expected 9 got %d", + (int)r.length); + + source = @"h1. Real Acme\n\n||{noborder}{left}Item||{right}Price||\n|Testproduct|{right}2 x $59.50|\n| |{right}net amount: $100.00|\n| |{right}total amount: $119.00|\n\n\nh2. Thanks for your purchase!\n\n\n"; + + expr = [NSRegularExpression regularExpressionWithPattern: @"h[123]\\. " + options: NSRegularExpressionCaseInsensitive error: NULL]; + index = 33; + + NSLog(@"%@", [expr firstMatchInString: source + options: NSMatchingAnchored + range: NSMakeRange(index, [source length] - index - 1)]); #endif - END_SET("NSString + regex") - return 0; + + END_SET("NSString + regex") + return 0; }