mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Fix handling of incorrect replacement patterns.
The error code from trying to apply a replacement pattern was not checked, resulting in a crash inside libicu. This also fixes a few memory leaks (replacement string objects not correctly autoreleased before returning them to the caller). git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@40142 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
0abb1803ce
commit
6509aeb2de
3 changed files with 79 additions and 2 deletions
|
@ -1,3 +1,9 @@
|
|||
2016-10-12 Niels Grewe <niels.grewe@halbordnung.de>
|
||||
|
||||
* Source/NSRegularExpression.m: Fix crashes in libicu due to ignored error
|
||||
codes. Also fix a few memory leaks.
|
||||
* Tests/base/NSRegularExpression/basic.m: Test cases for this.
|
||||
|
||||
2016-10-11 Niels Grewe <niels.grewe@halbordnung.de>
|
||||
|
||||
* Source/GSTLS.m
|
||||
|
|
|
@ -831,6 +831,14 @@ prepareResult(NSRegularExpression *regex,
|
|||
UTextInitWithNSString(&replacement, template);
|
||||
|
||||
output = uregex_replaceAllUText(r, &replacement, NULL, &s);
|
||||
if (0 != s)
|
||||
{
|
||||
uregex_close(r);
|
||||
utext_close(&replacement);
|
||||
utext_close(&txt);
|
||||
DESTROY(ret);
|
||||
return 0;
|
||||
}
|
||||
utext_clone(&ret->txt, output, TRUE, TRUE, &s);
|
||||
[string setString: ret];
|
||||
[ret release];
|
||||
|
@ -857,13 +865,21 @@ prepareResult(NSRegularExpression *regex,
|
|||
UTextInitWithNSString(&replacement, template);
|
||||
|
||||
output = uregex_replaceAllUText(r, &replacement, NULL, &s);
|
||||
if (0 != s)
|
||||
{
|
||||
uregex_close(r);
|
||||
utext_close(&replacement);
|
||||
utext_close(&txt);
|
||||
DESTROY(ret);
|
||||
return nil;
|
||||
}
|
||||
utext_clone(&ret->txt, output, TRUE, TRUE, &s);
|
||||
uregex_close(r);
|
||||
|
||||
utext_close(&txt);
|
||||
utext_close(output);
|
||||
utext_close(&replacement);
|
||||
return ret;
|
||||
return AUTORELEASE(ret);
|
||||
}
|
||||
|
||||
- (NSString*) replacementStringForResult: (NSTextCheckingResult*)result
|
||||
|
@ -887,13 +903,21 @@ prepareResult(NSRegularExpression *regex,
|
|||
UTextInitWithNSString(&replacement, template);
|
||||
|
||||
output = uregex_replaceFirstUText(r, &replacement, NULL, &s);
|
||||
if (0 != s)
|
||||
{
|
||||
uregex_close(r);
|
||||
utext_close(&replacement);
|
||||
utext_close(&txt);
|
||||
DESTROY(ret);
|
||||
return nil;
|
||||
}
|
||||
utext_clone(&ret->txt, output, TRUE, TRUE, &s);
|
||||
uregex_close(r);
|
||||
|
||||
utext_close(&txt);
|
||||
utext_close(output);
|
||||
utext_close(&replacement);
|
||||
return ret;
|
||||
return AUTORELEASE(ret);
|
||||
}
|
||||
#else
|
||||
- (NSUInteger) replaceMatchesInString: (NSMutableString*)string
|
||||
|
|
|
@ -82,6 +82,53 @@ int main()
|
|||
* which is also the reason for wrapping the previous one in an ARP */
|
||||
PASS_RUNS([testObj pattern], "Calling -pattern twice runs");
|
||||
|
||||
// The pattern does not include a capture group $1, so this should return
|
||||
// nil;
|
||||
NSString *replacement = @"should be unset on return";
|
||||
replacement = [testObj stringByReplacingMatchesInString: @"ab"
|
||||
options: 0
|
||||
range: NSMakeRange(0,2)
|
||||
withTemplate: @"$1c"];
|
||||
PASS(replacement == nil, "Replacement: returns nil on capture group error");
|
||||
replacement = [testObj stringByReplacingMatchesInString: @"ab"
|
||||
options: 0
|
||||
range: NSMakeRange(0, 2)
|
||||
withTemplate: @"c"];
|
||||
PASS_EQUAL(replacement, @"cb", "Replacement correct");
|
||||
|
||||
NSString *replMut = [NSMutableString stringWithString: @"ab"];
|
||||
[testObj replaceMatchesInString: replMut
|
||||
options: 0
|
||||
range: NSMakeRange(0,2)
|
||||
withTemplate: @"$1c"];
|
||||
PASS_EQUAL(replMut, @"ab",
|
||||
"Mutable replacement: Incorrect template does not change string");
|
||||
replMut = [NSMutableString stringWithString: @"ab"];
|
||||
[testObj replaceMatchesInString: replMut
|
||||
options: 0
|
||||
range: NSMakeRange(0,2)
|
||||
withTemplate: @"c"];
|
||||
PASS_EQUAL(replMut, @"cb",
|
||||
"Mutable replacement: Correct replacement for template");
|
||||
|
||||
NSTextCheckingResult *r = [testObj firstMatchInString: @"ab"
|
||||
options: 0
|
||||
range: NSMakeRange(0,2)];
|
||||
PASS(r, "Found NSTextCheckingResult");
|
||||
replacement = @"should be unset on return";
|
||||
replacement = [testObj replacementStringForResult: r
|
||||
inString: @"ab"
|
||||
offset: 0
|
||||
template: @"$1c"];
|
||||
PASS(replacement == nil,
|
||||
"Custom replacement: returns nil on capture group error");
|
||||
replacement = nil;
|
||||
replacement = [testObj replacementStringForResult: r
|
||||
inString: @"ab"
|
||||
offset: 0
|
||||
template: @"c"];
|
||||
PASS_EQUAL(replacement, @"c",
|
||||
"Custom replacement: Returns correct replacement");
|
||||
/* To test whether we correctly bail out of processing degenerate patterns,
|
||||
* we spin up a new thread and evaluate an expression there. The expectation
|
||||
* is that the thread should terminate within a few seconds.
|
||||
|
|
Loading…
Reference in a new issue