diff options
-rwxr-xr-x | blacklisting/check-env.pl | 2 | ||||
-rw-r--r-- | src/libexpr/parser.cc | 61 | ||||
-rw-r--r-- | tests/lang/parse-fail-dup-attrs-1.nix | 4 | ||||
-rw-r--r-- | tests/lang/parse-fail-dup-attrs-2.nix | 13 | ||||
-rw-r--r-- | tests/lang/parse-fail-dup-attrs-3.nix | 13 | ||||
-rw-r--r-- | tests/lang/parse-fail-dup-formals.nix | 1 | ||||
-rw-r--r-- | tests/lang/parse-fail-undef-var.nix (renamed from tests/lang/parse-fail-1.nix) | 0 |
7 files changed, 93 insertions, 1 deletions
diff --git a/blacklisting/check-env.pl b/blacklisting/check-env.pl index 0d76156ee..6eb792a52 100755 --- a/blacklisting/check-env.pl +++ b/blacklisting/check-env.pl @@ -232,7 +232,7 @@ foreach my $userEnvElem (@userEnvElems) { # Evaluate each blacklist item. foreach my $item ($blacklist->getChildrenByTagName("item")) { my $itemId = $item->getAttributeNode("id")->getValue; - print " CHECKING FOR $itemId\n"; +# print " CHECKING FOR $itemId\n"; my $condition = ($item->getChildrenByTagName("condition"))[0]; die unless $condition; diff --git a/src/libexpr/parser.cc b/src/libexpr/parser.cc index 8232b0de5..16b94fa62 100644 --- a/src/libexpr/parser.cc +++ b/src/libexpr/parser.cc @@ -75,6 +75,65 @@ int yyparse(yyscan_t scanner, ParseData * data); } +static void checkAttrs(ATermMap & names, ATermList bnds) +{ + for (ATermIterator i(bnds); i; ++i) { + ATerm name; + Expr e; + ATerm pos; + if (!matchBind(*i, name, e, pos)) abort(); /* can't happen */ + if (names.get(name)) + throw Error(format("duplicate attribute `%1%' at %2%") + % aterm2String(name) % showPos(pos)); + names.set(name, name); + } +} + + +static void checkAttrSets(ATerm e) +{ + ATermList formals; + ATerm body, pos; + if (matchFunction(e, formals, body, pos)) { + ATermMap names; + for (ATermIterator i(formals); i; ++i) { + ATerm name; + Expr deflt; + if (!matchNoDefFormal(*i, name) && + !matchDefFormal(*i, name, deflt)) + abort(); + if (names.get(name)) + throw Error(format("duplicate formal function argument `%1%' at %2%") + % aterm2String(name) % showPos(pos)); + names.set(name, name); + } + } + + ATermList bnds; + if (matchAttrs(e, bnds)) { + ATermMap names; + checkAttrs(names, bnds); + } + + ATermList rbnds, nrbnds; + if (matchRec(e, rbnds, nrbnds)) { + ATermMap names; + checkAttrs(names, rbnds); + checkAttrs(names, nrbnds); + } + + if (ATgetType(e) == AT_APPL) { + int arity = ATgetArity(ATgetAFun(e)); + for (int i = 0; i < arity; ++i) + checkAttrSets(ATgetArgument(e, i)); + } + + else if (ATgetType(e) == AT_LIST) + for (ATermIterator i((ATermList) e); i; ++i) + checkAttrSets(*i); +} + + static Expr parse(EvalState & state, const char * text, const Path & path, const Path & basePath) @@ -96,6 +155,8 @@ static Expr parse(EvalState & state, } catch (Error & e) { throw Error(format("%1%, in `%2%'") % e.msg() % path); } + + checkAttrSets(data.result); return data.result; } diff --git a/tests/lang/parse-fail-dup-attrs-1.nix b/tests/lang/parse-fail-dup-attrs-1.nix new file mode 100644 index 000000000..2c02317d2 --- /dev/null +++ b/tests/lang/parse-fail-dup-attrs-1.nix @@ -0,0 +1,4 @@ +{ x = 123; + y = 456; + x = 789; +} diff --git a/tests/lang/parse-fail-dup-attrs-2.nix b/tests/lang/parse-fail-dup-attrs-2.nix new file mode 100644 index 000000000..864d9865e --- /dev/null +++ b/tests/lang/parse-fail-dup-attrs-2.nix @@ -0,0 +1,13 @@ +let { + + as = { + x = 123; + y = 456; + }; + + bs = { + x = 789; + inherit (as) x; + }; + +} diff --git a/tests/lang/parse-fail-dup-attrs-3.nix b/tests/lang/parse-fail-dup-attrs-3.nix new file mode 100644 index 000000000..114d19779 --- /dev/null +++ b/tests/lang/parse-fail-dup-attrs-3.nix @@ -0,0 +1,13 @@ +let { + + as = { + x = 123; + y = 456; + }; + + bs = rec { + x = 789; + inherit (as) x; + }; + +} diff --git a/tests/lang/parse-fail-dup-formals.nix b/tests/lang/parse-fail-dup-formals.nix new file mode 100644 index 000000000..a0edd91a9 --- /dev/null +++ b/tests/lang/parse-fail-dup-formals.nix @@ -0,0 +1 @@ +{x, y, x}: x
\ No newline at end of file diff --git a/tests/lang/parse-fail-1.nix b/tests/lang/parse-fail-undef-var.nix index 7b6300811..7b6300811 100644 --- a/tests/lang/parse-fail-1.nix +++ b/tests/lang/parse-fail-undef-var.nix |