From 35a214603f96cb42c61cee394e7e367575d28426 Mon Sep 17 00:00:00 2001 From: Mehmet Murat Akburak Date: Thu, 23 Jul 2020 00:12:46 +0300 Subject: [PATCH] [PowerRename] Clear capturing groups with more than 1 digit (#5116) User has actually signed CLA, see #4722 * Clear capturing groups with more than 1 digit * Fix issue in regex pattern * Add unittest * Fix regex patterns * Edit unittest * Fix regex pattern, add some tests --- .../powerrename/lib/PowerRenameRegEx.cpp | 3 ++ .../unittests/PowerRenameRegExTests.cpp | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/modules/powerrename/lib/PowerRenameRegEx.cpp b/src/modules/powerrename/lib/PowerRenameRegEx.cpp index 70b27a61d..80378365c 100644 --- a/src/modules/powerrename/lib/PowerRenameRegEx.cpp +++ b/src/modules/powerrename/lib/PowerRenameRegEx.cpp @@ -201,6 +201,9 @@ HRESULT CPowerRenameRegEx::Replace(_In_ PCWSTR source, _Outptr_ PWSTR* result) std::wstring searchTerm(m_searchTerm); std::wstring replaceTerm(m_replaceTerm ? wstring(m_replaceTerm) : wstring(L"")); + replaceTerm = regex_replace(replaceTerm, std::wregex(L"(([^\\$]|^)(\\$\\$)*)\\$[0]"), L"$1$$$0"); + replaceTerm = regex_replace(replaceTerm, std::wregex(L"(([^\\$]|^)(\\$\\$)*)\\$([1-9])"), L"$1$0$4"); + if (m_flags & UseRegularExpressions) { std::wregex pattern(m_searchTerm, (!(m_flags & CaseSensitive)) ? regex_constants::icase | regex_constants::ECMAScript : regex_constants::ECMAScript); diff --git a/src/modules/powerrename/unittests/PowerRenameRegExTests.cpp b/src/modules/powerrename/unittests/PowerRenameRegExTests.cpp index f11c51fcd..f2163a37d 100644 --- a/src/modules/powerrename/unittests/PowerRenameRegExTests.cpp +++ b/src/modules/powerrename/unittests/PowerRenameRegExTests.cpp @@ -331,6 +331,37 @@ TEST_METHOD(VerifyReplaceFirstWildNoFlags) VerifyReplaceFirstWildcard(sreTable, ARRAYSIZE(sreTable), 0); } +TEST_METHOD(VerifyHandleCapturingGroups) +{ + CComPtr renameRegEx; + Assert::IsTrue(CPowerRenameRegEx::s_CreateInstance(&renameRegEx) == S_OK); + DWORD flags = MatchAllOccurences | UseRegularExpressions | CaseSensitive; + Assert::IsTrue(renameRegEx->put_flags(flags) == S_OK); + + SearchReplaceExpected sreTable[] = { + //search, replace, test, result + { L"(foo)(bar)", L"$1_$002_$223_$001021_$00001", L"foobar", L"foo_$002_bar23_$001021_$00001" }, + { L"(foo)(bar)", L"_$1$2_$123$040", L"foobar", L"_foobar_foo23$040" }, + { L"(foo)(bar)", L"$$$1", L"foobar", L"$foo" }, + { L"(foo)(bar)", L"$$1", L"foobar", L"$1" }, + { L"(foo)(bar)", L"$12", L"foobar", L"foo2" }, + { L"(foo)(bar)", L"$10", L"foobar", L"foo0" }, + { L"(foo)(bar)", L"$01", L"foobar", L"$01" }, + { L"(foo)(bar)", L"$$$11", L"foobar", L"$foo1" }, + { L"(foo)(bar)", L"$$$$113a", L"foobar", L"$$113a" }, + }; + + for (int i = 0; i < ARRAYSIZE(sreTable); i++) + { + PWSTR result = nullptr; + Assert::IsTrue(renameRegEx->put_searchTerm(sreTable[i].search) == S_OK); + Assert::IsTrue(renameRegEx->put_replaceTerm(sreTable[i].replace) == S_OK); + Assert::IsTrue(renameRegEx->Replace(sreTable[i].test, &result) == S_OK); + Assert::IsTrue(wcscmp(result, sreTable[i].expected) == 0); + CoTaskMemFree(result); + } +} + TEST_METHOD(VerifyEventsFire) { CComPtr renameRegEx;