Skip to content

Commit c77feb4

Browse files
committed
[bugfix] Warn on missing Fn namespace on elements passed to fn:xml-to-json
Closes eXist-db/exist#5543
1 parent 4c4bac3 commit c77feb4

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed

exist-core/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@
679679
<include>project-suppression.xml</include>
680680
<include>src/test/java/org/exist/xquery/ImportFromPkgTest.java</include>
681681
<include>src/test/java/org/exist/xquery/value/DateTimeTypesTest.java</include>
682+
<include>src/test/java/org/exist/xquery/functions/fn/FunXmlToJsonTest.java</include>
682683
<include>src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml</include>
683684
</includes>
684685
</licenseSet>
@@ -787,6 +788,7 @@
787788
<include>src/test/java/org/exist/management/JmxRemoteTest.java</include>
788789
<include>src/test/java/org/exist/xmldb/CreateCollectionsTest.java</include>
789790
<include>src/test/java/org/exist/xquery/XQueryFunctionsTest.java</include>
791+
<include>src/main/java/org/exist/xquery/functions/fn/FunXmlToJson.java</include>
790792
<include>src/test/java/org/exist/xquery/functions/transform/TransformFromPkgTest.java</include>
791793
<include>src/test/java/org/exist/xquery/value/Base64BinaryValueTypeTest.java</include>
792794
<include>src/main/java/org/exist/xslt/XsltURIResolverHelper.java</include>
@@ -889,6 +891,8 @@
889891
<exclude>src/main/java/org/exist/xmlrpc/ExistRpcTypeFactory.java</exclude>
890892
<exclude>src/test/java/org/exist/xquery/ImportFromPkgTest.java</exclude>
891893
<exclude>src/main/java/org/exist/xquery/functions/fn/FunUriCollection.java</exclude>
894+
<exclude>src/main/java/org/exist/xquery/functions/fn/FunXmlToJson.java</exclude>
895+
<exclude>src/test/java/org/exist/xquery/functions/fn/FunXmlToJsonTest.java</exclude>
892896
<exclude>src/main/java/org/exist/xquery/functions/system/GetUptime.java</exclude>
893897
<exclude>src/main/java/org/exist/xquery/functions/system/Shutdown.java</exclude>
894898
<exclude>src/main/java/org/exist/xquery/value/AbstractDateTimeValue.java</exclude>

exist-core/src/main/java/org/exist/xquery/functions/fn/FunXmlToJson.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -143,9 +167,11 @@ private void nodeValueToJson(final NodeValue nodeValue, final Writer writer) thr
143167
}
144168
switch (reader.getLocalName()) {
145169
case "array":
170+
checkNamespace(reader.getNamespaceURI());
146171
jsonGenerator.writeStartArray();
147172
break;
148173
case "map":
174+
checkNamespace(reader.getNamespaceURI());
149175
mapkeyArrayList.add(stackSeparator);
150176
jsonGenerator.writeStartObject();
151177
break;
@@ -161,13 +187,15 @@ private void nodeValueToJson(final NodeValue nodeValue, final Writer writer) thr
161187
final String tempString = tempStringBuilder.toString();
162188
switch (reader.getLocalName()) {
163189
case "array":
190+
checkNamespace(reader.getNamespaceURI());
164191
jsonGenerator.writeEndArray();
165192
break;
166193
case "boolean":
167194
final boolean tempBoolean = !(tempString.isEmpty() || "0".equals(tempString) || "false".equals(tempString));
168195
jsonGenerator.writeBoolean(tempBoolean);
169196
break;
170197
case "map":
198+
checkNamespace(reader.getNamespaceURI());
171199
while (!mapkeyArrayList.isEmpty() && mapkeyArrayList.remove(mapkeyArrayList.size() - 1) != stackSeparator) {
172200
}
173201
jsonGenerator.writeEndObject();
@@ -245,4 +273,11 @@ private String unescapeEscapedJsonString(final String escapedJsonString) throws
245273
unescapedJsonString = unescapedJsonStringBuilder.toString();
246274
return unescapedJsonString;
247275
}
276+
277+
private void checkNamespace(final String namespaceUri) throws XPathException {
278+
if (!Function.BUILTIN_FUNCTION_NS.equals(namespaceUri)) {
279+
// throw new XPathException(this, ErrorCodes.FOJS0006, "Element was in namespace: " + namespaceUri + ", but should have been in namespace: " + Function.BUILTIN_FUNCTION_NS);
280+
LOG.warn(ErrorCodes.FOJS0006.getErrorQName() + ": Element was in namespace: " + namespaceUri + ", but should have been in namespace: " + Function.BUILTIN_FUNCTION_NS);
281+
}
282+
}
248283
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
package org.exist.xquery.functions.fn;
22+
23+
import org.exist.test.ExistXmldbEmbeddedServer;
24+
import org.junit.ClassRule;
25+
import org.junit.Ignore;
26+
import org.junit.Test;
27+
import org.xmldb.api.base.XMLDBException;
28+
29+
import static org.junit.Assert.*;
30+
31+
/**
32+
* @author <a href="mailto:[email protected]">Adam Retter</a>
33+
*/
34+
public class FunXmlToJsonTest {
35+
36+
@ClassRule
37+
public static final ExistXmldbEmbeddedServer existEmbeddedServer = new ExistXmldbEmbeddedServer(false, true, true);
38+
39+
@Test
40+
public void arrayInFnNs() throws XMLDBException {
41+
final String query =
42+
"fn:xml-to-json(\n" +
43+
" <array xmlns=\"http://www.w3.org/2005/xpath-functions\">\n" +
44+
" <string>Curly</string>\n" +
45+
" <string>Larry</string>\n" +
46+
" <string>Moe</string>\n" +
47+
" </array>\n" +
48+
")";
49+
final String result = existEmbeddedServer.executeOneValue(query);
50+
assertEquals("[\"Curly\",\"Larry\",\"Moe\"]", result);
51+
}
52+
53+
@Ignore("Enable in FunXmlToJson#checkNamespace(String) see: https://github.com/eXist-db/exist/issues/5543")
54+
@Test
55+
public void arrayOutsideFnNs() {
56+
final String query =
57+
"fn:xml-to-json(\n" +
58+
" <array>\n" +
59+
" <string>Curly</string>\n" +
60+
" <string>Larry</string>\n" +
61+
" <string>Moe</string>\n" +
62+
" </array>\n" +
63+
")";
64+
try {
65+
existEmbeddedServer.executeOneValue(query);
66+
} catch (final XMLDBException e) {
67+
assertTrue(e.getMessage().startsWith("err:FOJS0006"));
68+
return;
69+
}
70+
71+
fail("Expected XPathException: err:FOJS0006");
72+
}
73+
74+
@Test
75+
public void mapInFnNs() throws XMLDBException {
76+
final String query =
77+
"fn:xml-to-json(\n" +
78+
" <map xmlns=\"http://www.w3.org/2005/xpath-functions\">\n" +
79+
" <string key=\"Fruit\">Apple</string>\n" +
80+
" <string key=\"Vegetable\">Carrot</string>\n" +
81+
" </map>" +
82+
")";
83+
final String result = existEmbeddedServer.executeOneValue(query);
84+
assertEquals("{\"Fruit\":\"Apple\",\"Vegetable\":\"Carrot\"}", result);
85+
}
86+
87+
@Ignore("Enable in FunXmlToJson#checkNamespace(String) see: https://github.com/eXist-db/exist/issues/5543")
88+
@Test
89+
public void mapOutsideFnNs() throws XMLDBException {
90+
final String query =
91+
"fn:xml-to-json(\n" +
92+
" <map>\n" +
93+
" <string key=\"Fruit\">Apple</string>\n" +
94+
" <string key=\"Vegetable\">Carrot</string>\n" +
95+
" </map>" +
96+
")";
97+
try {
98+
existEmbeddedServer.executeOneValue(query);
99+
} catch (final XMLDBException e) {
100+
assertTrue(e.getMessage().startsWith("err:FOJS0006"));
101+
return;
102+
}
103+
104+
fail("Expected XPathException: err:FOJS0006");
105+
}
106+
107+
}

0 commit comments

Comments
 (0)