From 9fefceca3100b6c6f5b2f00bbff507fa3410884f Mon Sep 17 00:00:00 2001 From: Laurettta Date: Fri, 30 Oct 2026 09:27:13 +0000 Subject: [PATCH 1/2] [bugfix] Raise XPTY0004 when declare context item is not given exactly one item. Closes https://github.com/eXist-db/exist/issues/4946 --- .../exist/xquery/ContextItemDeclaration.java | 7 ++++++- .../xquery/XQueryDeclareContextItemTest.java | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java b/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java index 475c892ba9..600a34ae34 100644 --- a/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java +++ b/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java @@ -76,7 +76,12 @@ public Sequence eval(final Sequence contextSequence, final Item contextItem) thr return null; } } else { - return value.get().eval(null, null); + final Sequence result = value.get().eval(null, null); + if (result.isEmpty() || result.hasMany()){ + throw new XPathException(this, ErrorCodes.XPTY0004,"The context item must be exactly one item"); + } else { + return result; + } } } diff --git a/exist-core/src/test/java/org/exist/xquery/XQueryDeclareContextItemTest.java b/exist-core/src/test/java/org/exist/xquery/XQueryDeclareContextItemTest.java index 00d1d3d4b9..12b96876d6 100644 --- a/exist-core/src/test/java/org/exist/xquery/XQueryDeclareContextItemTest.java +++ b/exist-core/src/test/java/org/exist/xquery/XQueryDeclareContextItemTest.java @@ -79,8 +79,7 @@ import java.util.Optional; import java.util.Properties; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; /** * Tests for XQuery 3.0's declare context item @@ -144,6 +143,22 @@ public void declareContextItem() throws EXistException, PermissionDeniedExceptio } } + @Test + public void declareContextItemMoreThanOneItem() throws EXistException, PermissionDeniedException, XPathException, IOException { + final String query = + "xquery version \"3.0\";\n" + + "declare context item := (1,2); \n" + + "."; + + final BrokerPool pool = existEmbeddedServer.getBrokerPool(); + try (final DBBroker broker = pool.getBroker(); + final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, new StringSource(query), false, null, null, null, null, null)) { + fail("Expected XQuery error XPTY0004"); + } catch (final XPathException e){ + assertEquals(ErrorCodes.XPTY0004, e.getErrorCode()); + } + } + /** * See issue https://github.com/eXist-db/exist/issues/2156 */ From 48c83b51ff89f800deba00bd6e8cd0ab509b4490 Mon Sep 17 00:00:00 2001 From: Laurettta Date: Fri, 30 Oct 2026 13:18:54 +0000 Subject: [PATCH 2/2] [ignore] ContextItemDeclaration.analyze() which is never called --- .../exist/xquery/ContextItemDeclaration.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java b/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java index 600a34ae34..8ed2f1d9e0 100644 --- a/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java +++ b/exist-core/src/main/java/org/exist/xquery/ContextItemDeclaration.java @@ -52,6 +52,10 @@ public void analyze(final AnalyzeContextInfo contextInfo) throws XPathException if (value.isPresent()) { value.get().analyze(contextInfo); + if (!value.get().getCardinality().atMostOne()) { + throw new XPathException(this, ErrorCodes.XPTY0004, "The context item must be exactly one item"); + } + } } @@ -76,12 +80,15 @@ public Sequence eval(final Sequence contextSequence, final Item contextItem) thr return null; } } else { - final Sequence result = value.get().eval(null, null); - if (result.isEmpty() || result.hasMany()){ - throw new XPathException(this, ErrorCodes.XPTY0004,"The context item must be exactly one item"); - } else { - return result; - } + return value.get().eval(null, null); + +// else { +// final Sequence result = value.get().eval(null, null); +// if (result.isEmpty() || result.hasMany()){ +// throw new XPathException(this, ErrorCodes.XPTY0004,"The context item must be exactly one item"); +// } else { +// return result; +// } } }