ldif 0.0.9 → 0.0.10
raw patch · 9 files changed
+88/−19 lines, 9 filesdep −Cabaldep −ghcPVP ok
version bump matches the API change (PVP)
Dependencies removed: Cabal, ghc
API changes (from Hackage documentation)
+ Text.LDIF.Consts: escapedDNChars :: [Char]
+ Text.LDIF.Consts: specialDNChars :: [Char]
Files
- TODO.org +5/−1
- ldif.cabal +5/−5
- run_tests.sh +1/−1
- src/Text/LDIF/Apply.hs +2/−2
- src/Text/LDIF/Consts.hs +6/−0
- src/Text/LDIF/Parser.hs +13/−4
- src/Text/LDIF/Printer.hs +11/−1
- tests/TestMain.hs +20/−5
- tests/data/OK_dnescaped01.content.ldif +25/−0
TODO.org view
@@ -1,5 +1,4 @@ * Tasks-** update parseDNStr to parse all kind of DN notations ** error handling, modify add: <attrX> and than <attrY>:<value>, need to be asserted that <attrX> and <attrY> are the same. ** Implement the base64 parsing@@ -7,6 +6,11 @@ ** update serializers back to LDIF for base64 & all DN notations ** add module tests for versioned LDIFs ** add module tests for base64 parsing+** update the API for correct support of LDIF RFC+multiple valued attribute in RDN+binary data +** DONE update parseDNStr to parse all kind of DN notations+CLOSED: [2011-04-17 Sun 15:28] ** DONE Use getopt for input parameters on diffLDIF cmd ** DONE Implement ldifmodify (like ldapmodify) offline applying of Change LDIF on Content LDIF
ldif.cabal view
@@ -1,5 +1,5 @@ Name: ldif-Version: 0.0.9+Version: 0.0.10 License: BSD3 License-File: LICENSE Synopsis: The LDAP Data Interchange Format (LDIF) parser @@ -42,6 +42,7 @@ tests/data/OK_simple03.modify.ldif tests/data/OK_simpleComment.modify.ldif tests/data/OK_simpleWrap.modify.ldif+ tests/data/OK_dnescaped01.content.ldif Source-Repository head type: darcs@@ -52,14 +53,12 @@ default: False Library- Build-Depends: ghc,- base < 5,+ Build-Depends: base < 5, filepath, containers, cmdargs >= 0.2, directory,- parsec >= 2.1.0,- Cabal >= 1.4+ parsec >= 2.1.0 Hs-Source-Dirs: src Extensions: CPP, PatternGuards Ghc-Options: -Wall -fno-warn-orphans@@ -72,6 +71,7 @@ Text.LDIF.Utils Text.LDIF.Diff Text.LDIF.Apply+ Text.LDIF.Consts Executable diffLDIF Hs-Source-Dirs: src
run_tests.sh view
@@ -1,3 +1,3 @@ #!/bin/sh -cabal clean && cabal configure -ftest && cabal build && cd tests && ../dist/build/test/test+cabal configure -ftest && cabal build && cd tests && ../dist/build/test/test
src/Text/LDIF/Apply.hs view
@@ -5,12 +5,12 @@ import Text.LDIF.Types import Text.LDIF.Utils import Text.LDIF.Printer-import Data.List (nub)+import Data.List (nub, foldl') -- | Apply one LDIF to another LDIF. The destination LDIF has -- | to be Content LDIF applyLDIF :: LDIF -> LDIF -> LDIF-applyLDIF dst (LDIF _ xs) = foldr (applyRecord2LDIF) dst xs+applyLDIF dst (LDIF _ xs) = foldl' (\ld chg -> applyRecord2LDIF chg ld) dst xs -- | Apply one LDIF Content/Change Record into LDIF and produce Changed LDIF applyRecord2LDIF :: LDIFRecord -> LDIF -> LDIF
+ src/Text/LDIF/Consts.hs view
@@ -0,0 +1,6 @@+module Text.LDIF.Consts where++-- | Chars necessary to be escaped when are within RDN values+specialDNChars, escapedDNChars :: [Char]+specialDNChars = [',','=','+','<','>','#',';']+escapedDNChars = ['\\', '"'] ++ specialDNChars
src/Text/LDIF/Parser.hs view
@@ -6,9 +6,11 @@ ) where import Text.LDIF.Types+import Text.LDIF.Consts import Text.ParserCombinators.Parsec import Data.Char import Data.List (isPrefixOf)+import Numeric (readHex) -- | Parse string as LDIF content and return LDIF or ParseError parseLDIFStr :: String -> Either ParseError LDIF@@ -180,11 +182,18 @@ pAttrValueDN :: CharParser st Value pAttrValueDN = do- many (noneOf stringChars)+ many allChar where - specialChars = [',','=','+','#',';','\n','\r']- -- specialChars = [',','=','+','<','>','#',';','\n','\r']- stringChars = '\\':'"':specialChars + allChar = try (escChar) <|> try (hexChar) <|> (noneOf (escapedDNChars ++ "\n\r"))+ escChar = do+ _ <- char '\\'+ oneOf escapedDNChars+ hexChar = do+ _ <- char '\\'+ hval <- count 2 hexDigit+ case readHex hval of+ [(val,[])] -> return $ chr val+ _ -> fail $ "invalid hex value: " ++ hval pVersionSpec :: CharParser st String pVersionSpec = do
src/Text/LDIF/Printer.hs view
@@ -6,7 +6,10 @@ ) where import Text.LDIF.Types+import Text.LDIF.Consts import Data.List+import Data.Char+import Numeric (showHex) -- | Serialize LDIF in LDIF Format ldif2str :: LDIF -> String@@ -19,7 +22,14 @@ -- | Serialize DN to LDIF Format dn2str :: DN -> String-dn2str xs = intercalate "," $ map (\((Attribute n),v) -> n++"="++v) (dnAttrVals xs)+dn2str xs = intercalate "," $ map (\((Attribute n),v) -> n++"="++(escapeDNVals v)) (dnAttrVals xs)++escapeDNVals :: String -> String+escapeDNVals vs = concat $ map escapeDNVal vs+ where+ escapeDNVal x | not $ isPrint x = '\\':(showHex (ord x) "")+ | elem x escapedDNChars = '\\':[x]+ | otherwise = [x] -- | Serialize Content Record in LDIF Format record2str :: LDIFRecord -> String
tests/TestMain.hs view
@@ -12,13 +12,28 @@ ls <- getLDIFs ldifDir runTestTT (tests ls) -tests ls = TestList $ (testCasesParseOK ls) ++ testCasesDIFF ++ testCasesUtils+tests ls = TestList $ (testCasesParseOK ls) ++ testCasesDIFF ++ testCasesUtils ++ (testCasesPrintOK ls) -- -- Test Cases -- testCasesDIFF = [TestCase (assertEqual "dummy" True True)]-testCasesParseOK ls = map (\x -> TestCase (assertParsedOK x)) $ filter (isOK) ls+testCasesParseOK ls = map (\x -> TestCase (checkParsing x)) $ filter (isOK) ls+ where+ checkParsing fname = do+ ret <- parseLDIFFile fname+ assertParsedOK fname ret "Parsing test"++testCasesPrintOK ls = map (\x -> TestCase (checkParsing x)) $ filter (isOK) ls+ where+ checkParsing fname = do+ ret <- parseLDIFFile fname+ case ret of + Left _ -> return ()+ Right ldif -> do+ let ret2 = parseLDIFStr (ldif2str ldif)+ assertParsedOK fname ret2 "Printing test"+ testCasesUtils = [ TestCase (assertBool "DN1Root is Prefix of DN2Root" (not $ isDNPrefixOf dn1root dn2root)) , TestCase (assertBool "DN1Root is Prefix of DN1Child" (isDNPrefixOf dn1root dn1child)) , TestCase (assertBool "DN Size 1" (1 == sizeOfDN dn1root))@@ -37,9 +52,9 @@ isOK x = isPrefixOf "OK" (takeFileName x) isLDIF x = isSuffixOf ".ldif" x -assertParsedOK filename = do- ret <- parseLDIFFile filename - either (\e -> assertFailure (show e)) (\ldif -> assertParsedType filename ldif) ret+assertParsedOK filename ret msg = case ret of+ Left e -> assertFailure $ msg ++ " " ++ (show e)+ Right ldif -> assertParsedType filename ldif assertParsedType name ldif | (isSuffixOf ".modify.ldif" name) = assertTypeChanges name ldif | (isSuffixOf ".content.ldif" name) = assertTypeContent name ldif
+ tests/data/OK_dnescaped01.content.ldif view
@@ -0,0 +1,25 @@+dn: cn=Slash\\The Post\,ma\=ster\+\<\>\#\;,dc=example.sk,dc=com+objectClass: organizationalRole+cn: The Postmaster++# multivalued not supported yet+# dn: OU=Sales+CN=J. Smith,O=Widget Inc.,C=US+# objectClass: organizationalRole+# cn: The Postmaster++dn: CN=L. Eagle,O=Sue\, Grabbit and Runn,C=GB+objectClass: organizationalRole+cn: The Postmaster++dn: CN=L. Eagle,O=Sue\, Grabbit and Runn,C=GB+objectClass: organizationalRole+cn: The Postmaster++dn: SN=Lu\C4\8Di\C4\87+objectClass: organizationalRole+cn: The Postmaster++# hex values not supported yet+#dn: test=#04024869,O=Test,C=GB+#objectClass: organizationalRole+#cn: The Postmaster