From 3a32ba2f3f54378e3e06366a5ff06e339984f065 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 8 Jan 2007 23:41:57 +0000 Subject: [PATCH] Prevent duplicate attribute names in XMLELEMENT. --- src/backend/parser/parse_expr.c | 22 +++++++++++++++++++--- src/test/regress/expected/xml.out | 4 +++- src/test/regress/expected/xml_1.out | 2 ++ src/test/regress/sql/xml.sql | 1 + 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index c15858fc7a..033dd6c75c 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.204 2007/01/05 22:19:34 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.205 2007/01/08 23:41:56 petere Exp $ * *------------------------------------------------------------------------- */ @@ -1415,8 +1415,8 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), x->op == IS_XMLELEMENT - ? errmsg("unnamed attribute value must be a column reference") - : errmsg("unnamed element value must be a column reference"))); + ? errmsg("unnamed XML attribute value must be a column reference") + : errmsg("unnamed XML element value must be a column reference"))); argname = NULL; /* keep compiler quiet */ } @@ -1424,6 +1424,22 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x) newx->arg_names = lappend(newx->arg_names, makeString(argname)); } + if (x->op == IS_XMLELEMENT) + { + foreach(lc, newx->arg_names) + { + ListCell *lc2; + + for_each_cell(lc2, lnext(lc)) + { + if (strcmp(strVal(lfirst(lc)), strVal(lfirst(lc2))) == 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("XML attribute name \"%s\" appears more than once", strVal(lfirst(lc))))); + } + } + } + /* The other arguments are of varying types depending on the function */ newx->args = NIL; i = 0; diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index c0ec868bf8..4179233e99 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -65,7 +65,7 @@ SELECT xmlelement(name element, SELECT xmlelement(name element, xmlattributes ('unnamed and wrong')); -ERROR: unnamed attribute value must be a column reference +ERROR: unnamed XML attribute value must be a column reference SELECT xmlelement(name element, xmlelement(name nested, 'stuff')); xmlelement ------------------------------------------- @@ -85,6 +85,8 @@ SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp; SELECT xmlelement(name wrong, 37); ERROR: argument of XMLELEMENT must be type xml, not type integer +SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a)); +ERROR: XML attribute name "a" appears more than once SELECT xmlparse(content 'abc'); xmlparse ---------- diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index 5a1a6ac031..8ef963b8e9 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -46,6 +46,8 @@ SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp; ERROR: no XML support in this installation SELECT xmlelement(name wrong, 37); ERROR: no XML support in this installation +SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a)); +ERROR: no XML support in this installation SELECT xmlparse(content 'abc'); ERROR: no XML support in this installation SELECT xmlparse(content 'x'); diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql index ae7d633c1c..d3a1e6104b 100644 --- a/src/test/regress/sql/xml.sql +++ b/src/test/regress/sql/xml.sql @@ -38,6 +38,7 @@ SELECT xmlelement(name element, xmlelement(name nested, 'stuff')); SELECT xmlelement(name employee, xmlforest(name, age, salary as pay)) FROM emp; SELECT xmlelement(name wrong, 37); +SELECT xmlelement(name duplicate, xmlattributes(1 as a, 2 as b, 3 as a)); SELECT xmlparse(content 'abc');