Skip to content

Commit

Permalink
avoid invalid filepaths on Windows (#9254)
Browse files Browse the repository at this point in the history
* avoid invalid filepaths on Windows

* comment bad Arbitrary instances
  • Loading branch information
geekosaur authored Sep 28, 2023
1 parent b639bfa commit d363088
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions Cabal-QuickCheck/src/Test/QuickCheck/Instances/Cabal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ module Test.QuickCheck.Instances.Cabal () where

import Control.Applicative (liftA2)
import Data.Bits (shiftR)
import Data.Char (isAlphaNum, isDigit)
import Data.List (intercalate)
import Data.Char (isAlphaNum, isDigit, toLower)
import Data.List (intercalate, (\\))
import Data.List.NonEmpty (NonEmpty (..))
import Distribution.Utils.Generic (lowercase)
import Test.QuickCheck
Expand Down Expand Up @@ -405,6 +405,10 @@ instance (Arbitrary a, Ord a) => Arbitrary (NubList a) where
-- InstallDirs
-------------------------------------------------------------------------------

-- these are wrong because they bottom out in String. We should really use
-- the modern FilePath at some point, so we get QC instances that don't include
-- invalid characters or path components

instance Arbitrary a => Arbitrary (InstallDirs a) where
arbitrary = InstallDirs
<$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary -- 4
Expand Down Expand Up @@ -506,11 +510,20 @@ arbitraryShortToken :: Gen String
arbitraryShortToken = arbitraryShortStringWithout "{}[]"

arbitraryShortPath :: Gen String
arbitraryShortPath = arbitraryShortStringWithout "{}[],"
arbitraryShortPath = arbitraryShortStringWithout "{}[],<>:|*?" `suchThat` (not . winDevice)
where
-- split path components on dots
-- no component can be empty or a device name
-- this blocks a little too much (both "foo..bar" and "foo.con" are legal)
-- but for QC being a little conservative isn't harmful
winDevice = any (any (`elem` ["","con", "aux", "prn", "com", "lpt", "nul"]) . splitBy ".") . splitBy "\\/" . map toLower
splitBy _ "" = []
splitBy seps str = let (part,rest) = break (`elem` seps) str
in part : if length rest == 1 then [""] else splitBy seps (drop 1 rest)

arbitraryShortStringWithout :: String -> Gen String
arbitraryShortStringWithout excludeChars =
shortListOf1 5 $ elements [c | c <- ['#' .. '~' ], c `notElem` excludeChars ]
shortListOf1 5 $ elements $ ['#' .. '~'] \\ excludeChars

-- |
intSqrt :: Int -> Int
Expand Down

0 comments on commit d363088

Please sign in to comment.