From 37e367eb7953c24265690e64575a8daef0395f1d Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Wed, 19 Oct 2016 01:26:10 +0200 Subject: [PATCH] fix(string_util): Prevent replace_all lock --- include/utils/string.hpp | 19 ++++++++++++++----- tests/utils/test_string.cpp | 2 ++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/utils/string.hpp b/include/utils/string.hpp index 756183bb..28de72c5 100644 --- a/include/utils/string.hpp +++ b/include/utils/string.hpp @@ -55,17 +55,26 @@ namespace string_util { * Replace all occurences of needle in haystack */ inline auto replace_all(const string& haystack, string needle, string replacement) { - auto result = haystack; - while (needle != replacement && result.find(needle) != string::npos) - result = replace(result, needle, replacement); - return result; + string replaced; + for (int i = 0; i < haystack.length(); i++) { + if (haystack.compare(i, needle.length(), needle) == 0) { + replaced += replacement; + i += needle.length()-1; + } else { + replaced += haystack[i]; + } + } + return replaced; } /** * Replace all consecutive occurrences of needle in haystack */ inline auto squeeze(const string& haystack, char needle) { - return replace_all(haystack, {needle, needle}, {needle}); + auto result = haystack; + while (result.find({needle, needle}) != string::npos) + result = replace_all(result, {needle, needle}, {needle}); + return result; } /** diff --git a/tests/utils/test_string.cpp b/tests/utils/test_string.cpp index 26310719..8b9faed7 100644 --- a/tests/utils/test_string.cpp +++ b/tests/utils/test_string.cpp @@ -43,6 +43,8 @@ class test_string : public unit_test { void test_replace_all() { CPPUNIT_ASSERT_EQUAL(string{"Foo bxr bxz"}, string_util::replace_all("Foo bar baz", "a", "x")); + CPPUNIT_ASSERT_EQUAL(string{"hoohoohoo"}, string_util::replace_all("hehehe", "he", "hoo")); + CPPUNIT_ASSERT_EQUAL(string{"113113113"}, string_util::replace_all("131313", "3", "13")); } void test_squeeze() {