From a8a0d3ee3073e81288e09330d0a26398d3d493cc Mon Sep 17 00:00:00 2001 From: Thomas Miedema Date: Wed, 12 Mar 2025 09:19:20 +0100 Subject: [PATCH] fix: csv: fix regression in parsing rules containing & (#2352) --- hledger-lib/Hledger/Read/RulesReader.hs | 9 +++++++-- hledger/test/csv.test | 27 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index 907e35a9d..319dc8718 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -723,7 +723,7 @@ regexp end = do Left x -> Fail.fail $ "CSV parser: " ++ x Right x -> return x where - double_ampersand = lookAhead . void $ char '&' >> char '&' + double_ampersand = lookAhead . void $ string "&&" -- -- A match operator, indicating the type of match to perform. -- -- Currently just ~ meaning case insensitive infix regex match. @@ -1596,9 +1596,14 @@ tests_RulesReader = testGroup "RulesReader" [ -- parseWithState' defrules matcherp "%description ~ A A\n" @?= (Right $ FieldMatcher "%description" "A A") ] + ,testGroup "regexp" [ testCase "regexp.ends-before-&&" $ - parseWithState' defrules (regexp empty) "A A && xxx" @?= (Right $ toRegexCI' "A A") + parseWithState' defrules (regexp eof) "A A && xxx" @?= (Right $ toRegexCI' "A A") + ,testCase "regexp contains &" $ + parseWithState' defrules (regexp eof) "A & B" @?= (Right $ toRegexCI' "A & B") + ,testCase "regexp contains escaped &" $ + parseWithState' defrules (regexp eof) "A \\& B" @?= (Right $ toRegexCI' "A \\& B") ] , let matchers = [RecordMatcher Or (toRegexCI' "A"), RecordMatcher And (toRegexCI' "B")] diff --git a/hledger/test/csv.test b/hledger/test/csv.test index 966a9eb12..831a699fc 100644 --- a/hledger/test/csv.test +++ b/hledger/test/csv.test @@ -1203,6 +1203,33 @@ $ ./csvtest.sh >=0 +# ** 62. Matchers can contain '&', either escaped or unescaped (#2352) +< +2025-01-01,STOP & SHOP,100 +2025-01-01,H & M,100 + +RULES +fields date,description,amount + +if +%description STOP & SHOP + account1 expenses:food + +if +%description H \& M + account1 expenses:clothing + +$ ./csvtest.sh +2025-01-01 STOP & SHOP + expenses:food 100 + income:unknown -100 + +2025-01-01 H & M + expenses:clothing 100 + income:unknown -100 + +>= + # ** . #< #$ ./csvtest.sh