From a5d3a4b624c56084e65891a6ad2ed9af8b2717fb Mon Sep 17 00:00:00 2001 From: Takashi Sawanaka Date: Wed, 3 Jan 2024 16:21:16 +0900 Subject: [PATCH] Fix the issue where the following string containing double quotes is not interpreted correctly when specified to the /unpacker command line argument. ~~~ /unpacker "Replace ""a"" ""b""" ~~~~ --- Src/MergeCmdLineInfo.cpp | 32 ++++++++- .../GoogleTest/CmdLine/MergeCmdLine_test.cpp | 68 +++++++++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/Src/MergeCmdLineInfo.cpp b/Src/MergeCmdLineInfo.cpp index f33ad357679..026f6d84e85 100644 --- a/Src/MergeCmdLineInfo.cpp +++ b/Src/MergeCmdLineInfo.cpp @@ -68,8 +68,36 @@ const tchar_t *MergeCmdLineInfo::EatParam(const tchar_t *p, String ¶m, bool param = strutils::makelower(param); } // Strip any leading or trailing whitespace or quotes - param.erase(0, param.find_first_not_of(_T(" \t\r\n\""))); - param.erase(param.find_last_not_of(_T(" \t\r\n\"")) + 1); + param.erase(0, param.find_first_not_of(_T(" \t\r\n"))); + param.erase(param.find_last_not_of(_T(" \t\r\n")) + 1); + if (!param.empty() && param.front() == '"') + { + param = ([](const String& param) -> String + { + String result; + bool inquotes = false; + for (int i = 0; i < param.length(); ++i) + { + if (param[i] == '"') + { + if (inquotes && i < param.length() - 1 && param[i + 1] == '"') + { + result += '"'; + ++i; + } + else + { + inquotes = !inquotes; + } + } + else + { + result += param[i]; + } + } + return result; + })(param); + } return q; } diff --git a/Testing/GoogleTest/CmdLine/MergeCmdLine_test.cpp b/Testing/GoogleTest/CmdLine/MergeCmdLine_test.cpp index cda65cf7722..0e35906b2aa 100644 --- a/Testing/GoogleTest/CmdLine/MergeCmdLine_test.cpp +++ b/Testing/GoogleTest/CmdLine/MergeCmdLine_test.cpp @@ -2048,6 +2048,74 @@ namespace EXPECT_EQ(_T(""), cmdInfo.m_sReportFile); EXPECT_EQ(_T(""), cmdInfo.m_sIniFilepath); } + TEST_F(MergeCmdLineInfoTest, Unpacker2) + { + MergeCmdLineInfo cmdInfo(_T("C:\\WinMerge\\WinMerge.exe /unpacker \"Replace -e ',\\s*\\n\\s*}' '}' -e ',\\s*\\n\\s*\\]' ']' | QueryJSON '.Parameters^|=sort_by(.HandleId)'\"")); + EXPECT_EQ(0, cmdInfo.m_Files.GetSize()); + EXPECT_EQ(MergeCmdLineInfo::SHOWNORMAL, cmdInfo.m_nCmdShow); + EXPECT_FALSE(cmdInfo.m_bEscShutdown); + EXPECT_FALSE(cmdInfo.m_bExitIfNoDiff); + EXPECT_FALSE(cmdInfo.m_bRecurse); + EXPECT_FALSE(cmdInfo.m_bNonInteractive); + EXPECT_FALSE(cmdInfo.m_nSingleInstance.has_value()); + EXPECT_FALSE(cmdInfo.m_bShowUsage); + EXPECT_FALSE(cmdInfo.m_bSelfCompare); + EXPECT_FALSE(cmdInfo.m_bNewCompare); + EXPECT_EQ(MergeCmdLineInfo::AUTOMATIC, cmdInfo.m_nWindowType); + EXPECT_FALSE(cmdInfo.m_nCompMethod.has_value()); + EXPECT_FALSE(cmdInfo.m_cTableDelimiter.has_value()); + EXPECT_FALSE(cmdInfo.m_cTableQuote.has_value()); + EXPECT_FALSE(cmdInfo.m_bTableAllowNewlinesInQuotes.has_value()); + EXPECT_EQ(0,cmdInfo.m_nCodepage); + EXPECT_EQ(-1, cmdInfo.m_nLineIndex); + EXPECT_EQ(FFILEOPEN_NONE, cmdInfo.m_dwLeftFlags); + EXPECT_EQ(FFILEOPEN_NONE, cmdInfo.m_dwMiddleFlags); + EXPECT_EQ(FFILEOPEN_NONE, cmdInfo.m_dwRightFlags); + EXPECT_EQ(_T(""), cmdInfo.m_sLeftDesc); + EXPECT_EQ(_T(""), cmdInfo.m_sMiddleDesc); + EXPECT_EQ(_T(""), cmdInfo.m_sRightDesc); + EXPECT_EQ(_T(""), cmdInfo.m_sFileFilter); + EXPECT_EQ(_T(""), cmdInfo.m_sPreDiffer); + EXPECT_EQ(_T("Replace -e ',\\s*\\n\\s*}' '}' -e ',\\s*\\n\\s*\\]' ']' | QueryJSON '.Parameters^|=sort_by(.HandleId)'"), cmdInfo.m_sUnpacker); + EXPECT_EQ(_T(""), cmdInfo.m_sFileExt); + EXPECT_EQ(_T(""), cmdInfo.m_sOutputpath); + EXPECT_EQ(_T(""), cmdInfo.m_sReportFile); + EXPECT_EQ(_T(""), cmdInfo.m_sIniFilepath); + } + TEST_F(MergeCmdLineInfoTest, Unpacker3) + { + MergeCmdLineInfo cmdInfo(_T("C:\\WinMerge\\WinMerge.exe /unpacker \"Replace -e \"\",\\s*\\n\\s*}\"\" \"\"}\"\" -e \"\",\\s*\\n\\s*\\]\"\" \"\"]\"\" | QueryJSON \"\".Parameters|=sort_by(.HandleId)\"\"\"")); + EXPECT_EQ(0, cmdInfo.m_Files.GetSize()); + EXPECT_EQ(MergeCmdLineInfo::SHOWNORMAL, cmdInfo.m_nCmdShow); + EXPECT_FALSE(cmdInfo.m_bEscShutdown); + EXPECT_FALSE(cmdInfo.m_bExitIfNoDiff); + EXPECT_FALSE(cmdInfo.m_bRecurse); + EXPECT_FALSE(cmdInfo.m_bNonInteractive); + EXPECT_FALSE(cmdInfo.m_nSingleInstance.has_value()); + EXPECT_FALSE(cmdInfo.m_bShowUsage); + EXPECT_FALSE(cmdInfo.m_bSelfCompare); + EXPECT_FALSE(cmdInfo.m_bNewCompare); + EXPECT_EQ(MergeCmdLineInfo::AUTOMATIC, cmdInfo.m_nWindowType); + EXPECT_FALSE(cmdInfo.m_nCompMethod.has_value()); + EXPECT_FALSE(cmdInfo.m_cTableDelimiter.has_value()); + EXPECT_FALSE(cmdInfo.m_cTableQuote.has_value()); + EXPECT_FALSE(cmdInfo.m_bTableAllowNewlinesInQuotes.has_value()); + EXPECT_EQ(0,cmdInfo.m_nCodepage); + EXPECT_EQ(-1, cmdInfo.m_nLineIndex); + EXPECT_EQ(FFILEOPEN_NONE, cmdInfo.m_dwLeftFlags); + EXPECT_EQ(FFILEOPEN_NONE, cmdInfo.m_dwMiddleFlags); + EXPECT_EQ(FFILEOPEN_NONE, cmdInfo.m_dwRightFlags); + EXPECT_EQ(_T(""), cmdInfo.m_sLeftDesc); + EXPECT_EQ(_T(""), cmdInfo.m_sMiddleDesc); + EXPECT_EQ(_T(""), cmdInfo.m_sRightDesc); + EXPECT_EQ(_T(""), cmdInfo.m_sFileFilter); + EXPECT_EQ(_T(""), cmdInfo.m_sPreDiffer); + EXPECT_EQ(_T("Replace -e \",\\s*\\n\\s*}\" \"}\" -e \",\\s*\\n\\s*\\]\" \"]\" | QueryJSON \".Parameters|=sort_by(.HandleId)\""), cmdInfo.m_sUnpacker); + EXPECT_EQ(_T(""), cmdInfo.m_sFileExt); + EXPECT_EQ(_T(""), cmdInfo.m_sOutputpath); + EXPECT_EQ(_T(""), cmdInfo.m_sReportFile); + EXPECT_EQ(_T(""), cmdInfo.m_sIniFilepath); + } // Prediffer TEST_F(MergeCmdLineInfoTest, Prediffer1)