fix: infinite loop when using .* patterns

Summary:

When we are using `.*` patterns, this causes an infinite loop. What happens is
we are adding text to the end and then replacing that. Its only when we are
matching the end of the output string.

We can detect this when the starting point is the same as the end point and the
match is "" (an empty string). If we hit this condition we can get out and
return the output that has been replaced.

Test Plan:

Test in CI
This commit is contained in:
Ade Attwood 2024-05-29 17:22:37 +01:00
parent b098c75cb5
commit fcaf425042
2 changed files with 19 additions and 1 deletions

View file

@ -26,6 +26,12 @@ pub fn replace(search: &String, replace: String, input: String) -> String {
let start = search_match.start(); let start = search_match.start();
let end = search_match.end(); let end = search_match.end();
// Prevent an infinite loop. If we hit this condition we will keep adding a new replacement
// to the end.
if start == end {
break;
}
let mut replacement = String::new(); let mut replacement = String::new();
match search_pattern.captures(&output[start..end]) { match search_pattern.captures(&output[start..end]) {
Some(captures) => { Some(captures) => {

View file

@ -22,4 +22,16 @@ Feature: Regex search and replace
Given Search is '(\w+' Given Search is '(\w+'
And Replace is 'new' And Replace is 'new'
And Input is 'this is a' And Input is 'this is a'
Then Output is 'this is a' Then Output is 'this is a'
Scenario: You can replace a pattern with a dot in it like a css class name
Given Search is '.testing'
And Replace is '.another'
And Input is '.testing {'
Then Output is '.another {'
Scenario: You can replace a pattern that grabs all the text
Given Search is '.*'
And Replace is '.another'
And Input is '.testing {'
Then Output is '.another'