From 5c3e47f529d6d1e81926530985bf4bb7c2557afe Mon Sep 17 00:00:00 2001 From: Pushkar N Kulkarni Date: Thu, 24 Mar 2016 17:32:44 +0530 Subject: [PATCH] Fix a stack corruption issue in CFRegularExpression The function _CFRegularExpressionEnumerateMatchesInString() walks the text searching for occurrences of the pattern. For every occurrence, it populates a CFRange array. If the number of capture groups is not greater than 7, it uses an array on the stack (instead of mallocing one). However, the total number of CFRanges inserted is (number of capture groups + 1). The last insert can corrupt the stack if the number of capture groups is 7. --- CoreFoundation/String.subproj/CFRegularExpression.c | 4 ++-- TestFoundation/TestNSRegularExpression.swift | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CoreFoundation/String.subproj/CFRegularExpression.c b/CoreFoundation/String.subproj/CFRegularExpression.c index 785aa79e93..71a121df45 100644 --- a/CoreFoundation/String.subproj/CFRegularExpression.c +++ b/CoreFoundation/String.subproj/CFRegularExpression.c @@ -363,8 +363,8 @@ void _CFRegularExpressionEnumerateMatchesInString(_CFRegularExpressionRef regexO if (!omitResult) { CFRange stack_ranges[7]; CFRange *ranges = &stack_ranges[0]; - if (numberOfCaptureGroups > sizeof(stack_ranges) / sizeof(stack_ranges[0])) { - ranges = (CFRange *)malloc(sizeof(CFRange) * numberOfCaptureGroups); + if (numberOfCaptureGroups + 1 > sizeof(stack_ranges) / sizeof(stack_ranges[0])) { + ranges = (CFRange *)malloc(sizeof(CFRange) * (numberOfCaptureGroups + 1)); } CFIndex rangeCount = 0; for (int i = 0; i <= numberOfCaptureGroups; i++) { diff --git a/TestFoundation/TestNSRegularExpression.swift b/TestFoundation/TestNSRegularExpression.swift index 5d86881d7b..a47ef57341 100644 --- a/TestFoundation/TestNSRegularExpression.swift +++ b/TestFoundation/TestNSRegularExpression.swift @@ -199,6 +199,8 @@ class TestNSRegularExpression : XCTestCase { replaceRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "This this is the the way.", [], NSMakeRange(0, 25), NSRegularExpression.escapedTemplateForString("*\\$1*"), 2, "*\\$1* is *\\$1* way.") replaceRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "This this is the the way.", [], NSMakeRange(0, 25), "*\\$1*", 2, "*$1* is *$1* way.") replaceRegularExpressionTest("\\b(th[a-z]+) \\1\\b", .CaseInsensitive, "This this is the the way.", [], NSMakeRange(0, 25), "*\\\\\\$1*", 2, "*\\$1* is *\\$1* way.") + replaceRegularExpressionTest("([1-9]a)([1-9]b)([1-9]c)([1-9]d)([1-9]e)([1-9]f)", [], "9a3b4c8d3e1f,9a3b4c8d3e1f", [], NSMakeRange(0,25), "$2$4 is your key", 2, "3b8d is your key,3b8d is your key") + replaceRegularExpressionTest("([1-9]a)([1-9]b)([1-9]c)([1-9]d)([1-9]e)([1-9]f)([1-9]z)", [], "9a3b4c8d3e1f2z,9a3b4c8d3e1f2z", [], NSMakeRange(0,29), "$2$4$1 is your key", 2, "3b8d9a is your key,3b8d9a is your key") } func complexRegularExpressionTest(patternString: String, _ patternOptions: NSRegularExpressionOptions, _ searchString: String, _ searchOptions: NSMatchingOptions, _ searchRange: NSRange, _ numberOfMatches: Int, _ firstMatchOverallRange: NSRange, _ firstMatchFirstCaptureRange: NSRange, _ firstMatchLastCaptureRange: NSRange, file: StaticString = #file, line: UInt = #line) {