Skip to content

Commit

Permalink
Workaround to avoid memory leak in ICU functions if we set NULL as de…
Browse files Browse the repository at this point in the history
…stination.
  • Loading branch information
rfm committed Nov 20, 2024
1 parent 91124f3 commit 7b77a20
Showing 1 changed file with 43 additions and 58 deletions.
101 changes: 43 additions & 58 deletions Source/NSRegularExpression.m
Original file line number Diff line number Diff line change
Expand Up @@ -868,35 +868,29 @@ - (NSUInteger) replaceMatchesInString: (NSMutableString*)string
{
// FIXME: We're computing a value that is most likely ignored in an
// expensive way.
NSInteger results = [self numberOfMatchesInString: string
options: opts
range: range];
UErrorCode s = 0;
UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER;
GSUTextString *ret = [GSUTextString new];
URegularExpression *r = setupRegex(regex, string, &txt, opts, range, 0);
UText *output = NULL;
NSInteger results = [self numberOfMatchesInString: string
options: opts
range: range];
UErrorCode s = 0;
UText dst = UTEXT_INITIALIZER;
UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER;
NSMutableString *ms = [NSMutableString string];
URegularExpression *r = setupRegex(regex, string, &txt, opts, range, 0);

UTextInitWithNSString(&replacement, template);
UTextInitWithNSMutableString(&dst, ms);

output = uregex_replaceAllUText(r, &replacement, NULL, &s);
uregex_replaceAllUText(r, &replacement, &dst, &s);
uregex_close(r);
utext_close(&replacement);
utext_close(&txt);
utext_close(&dst);
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];
RELEASE(ret);
uregex_close(r);

utext_close(&txt);
utext_close(output);
utext_close(&replacement);
[string setString: ms];
return results;
}

Expand All @@ -905,68 +899,59 @@ - (NSString*) stringByReplacingMatchesInString: (NSString*)string
range: (NSRange)range
withTemplate: (NSString*)template
{
UErrorCode s = 0;
UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER;
UText *output = NULL;
GSUTextString *ret = [GSUTextString new];
URegularExpression *r = setupRegex(regex, string, &txt, opts, range, 0);
UErrorCode s = 0;
UText dst = UTEXT_INITIALIZER;
UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER;
NSMutableString *ms = [NSMutableString string];
URegularExpression *r = setupRegex(regex, string, &txt, opts, range, 0);

UTextInitWithNSString(&replacement, template);
UTextInitWithNSMutableString(&dst, ms);

output = uregex_replaceAllUText(r, &replacement, NULL, &s);
uregex_replaceAllUText(r, &replacement, &dst, &s);
uregex_close(r);
utext_close(&replacement);
utext_close(&txt);
utext_close(&dst);
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 AUTORELEASE(ret);
return ms;
}

- (NSString*) replacementStringForResult: (NSTextCheckingResult*)result
inString: (NSString*)string
offset: (NSInteger)offset
template: (NSString*)template
{
UErrorCode s = 0;
UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER;
UText *output = NULL;
GSUTextString *ret = [GSUTextString new];
NSRange range = [result range];
URegularExpression *r = setupRegex(regex,
UErrorCode s = 0;
UText dst = UTEXT_INITIALIZER;
UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER;
NSMutableString *ms = [NSMutableString string];
NSRange range = [result range];
URegularExpression *r = setupRegex(regex,
[string substringWithRange: range],
&txt,
0,
NSMakeRange(0, range.length),
0);

UTextInitWithNSString(&replacement, template);
UTextInitWithNSMutableString(&dst, ms);

output = uregex_replaceFirstUText(r, &replacement, NULL, &s);
uregex_replaceFirstUText(r, &replacement, &dst, &s);
uregex_close(r);
utext_close(&dst);
utext_close(&txt);
utext_close(&replacement);
if (0 != s)
{
uregex_close(r);
utext_close(&replacement);
utext_close(&txt);
DESTROY(ret);
return nil;
}
utext_clone(&ret->txt, output, TRUE, TRUE, &s);
utext_close(output);
uregex_close(r);
utext_close(&txt);
utext_close(&replacement);
return AUTORELEASE(ret);
return ms;
}
#else
- (NSUInteger) replaceMatchesInString: (NSMutableString*)string
Expand Down

0 comments on commit 7b77a20

Please sign in to comment.