From 6b9d4d18903ca1516a24dd0cdd0a008f358f216f Mon Sep 17 00:00:00 2001 From: Joe Hermaszewski Date: Thu, 29 Oct 2020 10:30:24 +0800 Subject: [PATCH] Restrict type of parens and brackets to prevent negative use of NExprLoc it is not generally appropriate to have higher-order parsers operate on annotated locations as they are liable to perform changes to the parser which are not captured in the annotation. See https://github.com/haskell-nix/hnix/pull/739 and https://github.com/haskell-nix/hnix/pull/744 for examples. --- src/Nix/Parser.hs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Nix/Parser.hs b/src/Nix/Parser.hs index 1ef4d3d..fa45086 100644 --- a/src/Nix/Parser.hs +++ b/src/Nix/Parser.hs @@ -200,7 +200,7 @@ nixNull = annotateLocation1 (mkNullF <$ reserved "null" "null") -- however this position doesn't include the parsed parentheses, so remove the -- "inner" location annotateion and annotate again, including the parentheses. nixParens :: Parser NExprLoc -nixParens = annotateLocation1 (stripAnn . unFix <$> (parens nixToplevelForm "parens")) +nixParens = annotateLocation1 (parens (stripAnn . unFix <$> nixToplevelForm) "parens") nixList :: Parser NExprLoc nixList = annotateLocation1 (brackets (NList <$> many nixTerm) "list") @@ -411,7 +411,7 @@ nixBinders = (inherit <+> namedVar) `endBy` semi where <*> (equals *> nixToplevelForm) <*> pure p "variable binding" - scope = parens nixToplevelForm "inherit scope" + scope = nixParens "inherit scope" keyName :: Parser (NKeyName NExprLoc) keyName = dynamicKey <+> staticKey where @@ -496,6 +496,13 @@ identifier = lexeme $ try $ do where identLetter x = isAlpha x || isDigit x || x == '_' || x == '\'' || x == '-' +-- We restrict the type of 'parens' and 'brackets' here because if they were to +-- take a @Parser NExprLoc@ argument they would parse additional text which +-- wouldn't be captured in the source location annotation. +-- +-- Braces and angles in hnix don't enclose a single expression so this type +-- restriction would not be useful. +parens, brackets :: Parser (NExprF f) -> Parser (NExprF f) parens = between (symbol "(") (symbol ")") braces = between (symbol "{") (symbol "}") -- angles = between (symbol "<") (symbol ">")