diff options
author | Joey Hess <joey@kitenet.net> | 2014-02-19 01:28:48 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2014-02-19 01:28:48 -0400 |
commit | bfe8e2641e67c69020e89995fec7dfbc28d2f752 (patch) | |
tree | af4cbe32d4147e1e5bda835bfa983def5b4e478b /Annex/View.hs | |
parent | 51c12a76ef54affaf9428232fde4f2c3e30e7488 (diff) |
reject views with too many nested subdirs
Diffstat (limited to 'Annex/View.hs')
-rw-r--r-- | Annex/View.hs | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/Annex/View.hs b/Annex/View.hs index cc2aad5b9..66ae76f75 100644 --- a/Annex/View.hs +++ b/Annex/View.hs @@ -35,6 +35,20 @@ data ViewChange = Unchanged | Narrowing | Widening matchGlob :: String -> String -> Bool matchGlob glob val = wildCheckCase glob val +{- Each multivalued ViewFilter in a view results in another level of + - subdirectory nesting. When a file matches multiple ways, it will appear + - in multiple subdirectories. This means there is a bit of an exponential + - blowup with a single file appearing in a crazy number of places! + - + - Capping the view size to 5 is reasonable; why wants to dig + - through 5+ levels of subdirectories to find anything? + -} +viewTooLarge :: View -> Bool +viewTooLarge view = visibleViewSize view > 5 + +visibleViewSize :: View -> Int +visibleViewSize = length . filter (multiValue . viewFilter) . viewComponents + {- Updates a view, adding a new field to filter on (Narrowing), - or allowing a new value in an existing field (Widening). -} refineView :: View -> MetaField -> String -> (View, ViewChange) @@ -42,7 +56,10 @@ refineView view field wanted | field `elem` (map viewField components) = let (components', viewchanges) = runWriter $ mapM updatefield components in (view { viewComponents = components' }, maximum viewchanges) - | otherwise = (view { viewComponents = ViewComponent field viewfilter : components }, Narrowing) + | otherwise = let view' = view { viewComponents = ViewComponent field viewfilter : components } + in if viewTooLarge view' + then error $ "View is too large (" ++ show (visibleViewSize view') ++ " levels of subdirectories)" + else (view', Narrowing) where components = viewComponents view viewfilter @@ -86,17 +103,6 @@ combineViewFilter (FilterGlob old) newglob@(FilterGlob new) | matchGlob old new = (newglob, Narrowing) | otherwise = (newglob, Widening) -{- Each multivalued ViewFilter in a view results in another level of - - subdirectory nesting. When a file matches multiple ways, it will appear - - in multiple subdirectories. This means there is a bit of an exponential - - blowup with a single file appearing in a crazy number of places! - - - - Capping the view size to 5 is reasonable; why wants to dig - - through 5+ levels of subdirectories to find anything? - -} -viewTooLarge :: View -> Bool -viewTooLarge view = length (filter (multiValue . viewFilter) (viewComponents view)) > 5 - {- Checks if metadata matches a filter, and if so returns the value, - or values that match. -} matchFilter :: MetaData -> ViewComponent -> Maybe [MetaValue] |