Skip to content

Commit 9e7dd3c

Browse files
committed
[bugfix] Capture the XQuery line-number, column-number, and source when constructing an xs:anyURI fails in the xmldb XQuery extension module
1 parent e2ce895 commit 9e7dd3c

12 files changed

+74
-24
lines changed

exist-core/src/main/java/org/exist/xquery/XPathException.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import java.util.ArrayList;
2525
import java.util.Iterator;
2626
import java.util.List;
27+
28+
import com.evolvedbinary.j8fu.function.SupplierE;
2729
import org.exist.source.Source;
2830
import org.exist.xquery.ErrorCodes.ErrorCode;
2931
import org.exist.xquery.parser.XQueryAST;
@@ -475,4 +477,32 @@ public String toString() {
475477
return function + " [" + line + ":" + column + ":" + file + ']';
476478
}
477479
}
480+
481+
/**
482+
* Executes the function, and if the function raises an XPathException
483+
* and the error information is missing from the exception, it will be added
484+
* from the calling expression.
485+
*
486+
* @param <T> the return type of the function.
487+
*
488+
* @param callingExpression the calling expression.
489+
* @param function the function execute.
490+
*
491+
* @return the result of the calling function
492+
* @throws XPathException if the function throws an XPathException
493+
*/
494+
public static <T> T execAndAddErrorIfMissing(final Expression callingExpression, final SupplierE<T, XPathException> function) throws XPathException {
495+
try {
496+
return function.get();
497+
} catch (final XPathException e) {
498+
if (e.getLine() == 0) {
499+
if (callingExpression.getSource() != null) {
500+
e.setLocation(callingExpression.getLine(), callingExpression.getColumn(), callingExpression.getSource());
501+
} else {
502+
e.setLocation(callingExpression.getLine(), callingExpression.getColumn());
503+
}
504+
}
505+
throw e;
506+
}
507+
}
478508
}

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBAbstractCollectionManipulator.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.exist.xmldb.LocalCollection;
3131
import org.exist.xmldb.txn.bridge.InTxnLocalCollection;
3232
import org.exist.xquery.BasicFunction;
33+
import org.exist.xquery.Expression;
3334
import org.exist.xquery.FunctionSignature;
3435
import org.exist.xquery.XPathException;
3536
import org.exist.xquery.XQueryContext;
@@ -43,6 +44,8 @@
4344
import org.xmldb.api.base.XMLDBException;
4445
import org.xmldb.api.modules.CollectionManagementService;
4546

47+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
48+
4649
/**
4750
* @author Luigi P. Bai, [email protected], 2004
4851
* @author gev
@@ -65,35 +68,35 @@ public XMLDBAbstractCollectionManipulator(final XQueryContext context, final Fun
6568
this.errorIfAbsent = errorIfAbsent;
6669
}
6770

68-
public static LocalCollection getLocalCollection(final XQueryContext context, final String name) throws XMLDBException {
71+
public static LocalCollection getLocalCollection(final Expression callingExpression, final XQueryContext context, final String name) throws XMLDBException {
6972
try {
70-
return new InTxnLocalCollection(context.getSubject(), context.getBroker().getBrokerPool(), null, new AnyURIValue(name).toXmldbURI());
73+
return new InTxnLocalCollection(context.getSubject(), context.getBroker().getBrokerPool(), null, execAndAddErrorIfMissing(callingExpression, () -> new AnyURIValue(name).toXmldbURI()));
7174
} catch (final XPathException e) {
7275
throw new XMLDBException(ErrorCodes.INVALID_URI, e);
7376
}
7477
}
7578

76-
public static Collection getCollection(final XQueryContext context, final String collectionUri, final Optional<String> username, final Optional<String> password) throws XMLDBException {
79+
public static Collection getCollection(final Expression callingExpression, final XQueryContext context, final String collectionUri, final Optional<String> username, final Optional<String> password) throws XMLDBException {
7780
final Collection collection;
7881
if (!collectionUri.startsWith("xmldb:")) {
7982
// Must be a LOCAL collection
80-
collection = getLocalCollection(context, collectionUri);
83+
collection = getLocalCollection(callingExpression, context, collectionUri);
8184

8285
} else if (collectionUri.startsWith("xmldb:exist:///")) {
8386
// Must be a LOCAL collection
84-
collection = getLocalCollection(context, collectionUri.replaceFirst("xmldb:exist://", ""));
87+
collection = getLocalCollection(callingExpression, context, collectionUri.replaceFirst("xmldb:exist://", ""));
8588

8689
} else if (collectionUri.startsWith("xmldb:exist://embedded-eXist-server")) {
8790
// Must be a LOCAL collection
88-
collection = getLocalCollection(context, collectionUri.replaceFirst("xmldb:exist://embedded-eXist-server", ""));
91+
collection = getLocalCollection(callingExpression, context, collectionUri.replaceFirst("xmldb:exist://embedded-eXist-server", ""));
8992

9093
} else if (collectionUri.startsWith("xmldb:exist://localhost")) {
9194
// Must be a LOCAL collection
92-
collection = getLocalCollection(context, collectionUri.replaceFirst("xmldb:exist://localhost", ""));
95+
collection = getLocalCollection(callingExpression, context, collectionUri.replaceFirst("xmldb:exist://localhost", ""));
9396

9497
} else if (collectionUri.startsWith("xmldb:exist://127.0.0.1")) {
9598
// Must be a LOCAL collection
96-
collection = getLocalCollection(context, collectionUri.replaceFirst("xmldb:exist://127.0.0.1", ""));
99+
collection = getLocalCollection(callingExpression, context, collectionUri.replaceFirst("xmldb:exist://127.0.0.1", ""));
97100

98101
} else {
99102
// Right now, the collection is retrieved as GUEST. Need to figure out how to
@@ -131,7 +134,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence)
131134
}
132135
try {
133136
//TODO: use xmldbURI
134-
collection = getLocalCollection(context, internalCol.getURI().toString());
137+
collection = getLocalCollection(this, context, internalCol.getURI().toString());
135138
if (LOGGER.isDebugEnabled()) {
136139
LOGGER.debug("Loaded collection {}", collection.getName());
137140
}
@@ -148,7 +151,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence)
148151
final String collectionURI = args[paramNumber].getStringValue();
149152
if (collectionURI != null) {
150153
try {
151-
collection = getCollection(context, collectionURI, Optional.empty(), Optional.empty());
154+
collection = getCollection(this, context, collectionURI, Optional.empty(), Optional.empty());
152155
} catch (final XMLDBException xe) {
153156
if (errorIfAbsent) {
154157
throw new XPathException(this, "Could not locate collection: " + collectionURI, xe);
@@ -187,9 +190,9 @@ static public final Collection createCollection(final Collection parentColl, fin
187190
return child;
188191
}
189192

190-
static public final Collection createCollectionPath(final Collection parentColl, final String relPath) throws XMLDBException, XPathException {
193+
protected final Collection createCollectionPath(final Collection parentColl, final String relPath) throws XMLDBException, XPathException {
191194
Collection current = parentColl;
192-
final StringTokenizer tok = new StringTokenizer(new AnyURIValue(relPath).toXmldbURI().toString(), "/");
195+
final StringTokenizer tok = new StringTokenizer(execAndAddErrorIfMissing(this, () -> new AnyURIValue(relPath).toXmldbURI().toString()), "/");
193196
while (tok.hasMoreTokens()) {
194197
final String token = tok.nextToken();
195198
current = createCollection(current, token);

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBAuthenticate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro
143143
return BooleanValue.FALSE;
144144
}
145145

146-
final Collection root = XMLDBAbstractCollectionManipulator.getCollection(context, uri, Optional.of(userName), Optional.of(password));
146+
final Collection root = XMLDBAbstractCollectionManipulator.getCollection(this, context, uri, Optional.of(userName), Optional.of(password));
147147

148148
if (root == null) {
149149
logger.error("Unable to authenticate user: target collection {} does not exist {}", uri, getLocation());

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBCopy.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.xmldb.api.base.XMLDBException;
3939

4040
import static org.exist.xquery.FunctionDSL.*;
41+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
4142
import static org.exist.xquery.functions.xmldb.XMLDBModule.functionSignatures;
4243

4344
/**
@@ -101,8 +102,8 @@ public Sequence evalWithCollection(final Collection collection, final Sequence[]
101102
final Sequence contextSequence) throws XPathException {
102103

103104
if (isCalledAs(FS_COPY_RESOURCE_NAME)) {
104-
final XmldbURI destination = new AnyURIValue(args[2].itemAt(0).getStringValue()).toXmldbURI();
105-
final XmldbURI doc = new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI();
105+
final XmldbURI destination = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[2].itemAt(0).getStringValue()).toXmldbURI());
106+
final XmldbURI doc = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI());
106107
try {
107108
final Resource resource = collection.getResource(doc.toString());
108109
if (resource == null) {

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBGetMimeType.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import org.exist.xquery.value.StringValue;
4444
import org.exist.xquery.value.Type;
4545

46+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
47+
4648
/**
4749
* @author <a href="mailto:[email protected]">Adam Retter</a>
4850
*/
@@ -67,7 +69,7 @@ public XMLDBGetMimeType(XQueryContext context, FunctionSignature signature)
6769
public Sequence eval(Sequence[] args, Sequence contextSequence)
6870
throws XPathException {
6971

70-
final String path = new AnyURIValue(args[0].itemAt(0).getStringValue()).toString();
72+
final String path = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[0].itemAt(0).getStringValue()).toString());
7173

7274
if(path.matches("^[a-z]+://.*")) {
7375
//external

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBHasLock.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import org.xmldb.api.base.Resource;
4242
import org.xmldb.api.base.XMLDBException;
4343

44+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
45+
4446
/**
4547
* @author <a href="mailto:[email protected]">Wolfgang Meier</a>
4648
*
@@ -83,7 +85,7 @@ public Sequence evalWithCollection(Collection collection, Sequence[] args, Seque
8385

8486
try {
8587
final UserManagementService ums = (UserManagementService) collection.getService("UserManagementService", "1.0");
86-
final Resource res = collection.getResource(new AnyURIValue(args[1].getStringValue()).toXmldbURI().toString());
88+
final Resource res = collection.getResource(execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[1].getStringValue()).toXmldbURI().toString()));
8789
if (res != null) {
8890
final String lockUser = ums.hasUserLock(res);
8991
if (lockUser != null && isCalledAs("clear-lock")) {

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBMove.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import org.xmldb.api.base.Resource;
4242
import org.xmldb.api.base.XMLDBException;
4343

44+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
45+
4446
/**
4547
* @author <a href="mailto:[email protected]">Wolfgang Meier</a>
4648
*
@@ -81,9 +83,9 @@ public XMLDBMove(XQueryContext context, FunctionSignature signature) {
8183
public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence)
8284
throws XPathException {
8385

84-
final XmldbURI destination = new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI();
86+
final XmldbURI destination = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI());
8587
if (getSignature().getArgumentCount() == 3) {
86-
final XmldbURI doc = new AnyURIValue(args[2].itemAt(0).getStringValue()).toXmldbURI();
88+
final XmldbURI doc = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[2].itemAt(0).getStringValue()).toXmldbURI());
8789
try {
8890
final Resource resource = collection.getResource(doc.toString());
8991
if (resource == null) {

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBRemove.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import org.xmldb.api.base.XMLDBException;
3939
import org.xmldb.api.modules.CollectionManagementService;
4040

41+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
42+
4143
/**
4244
* @author <a href="mailto:[email protected]">Wolfgang Meier</a>
4345
*
@@ -74,7 +76,7 @@ public XMLDBRemove(XQueryContext context, FunctionSignature signature) {
7476
public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence)
7577
throws XPathException {
7678
if(getSignature().getArgumentCount() == 2) {
77-
final String doc = new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI().toString();
79+
final String doc = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI().toString());
7880
try {
7981
final Resource resource = collection.getResource(doc);
8082
if (resource == null) {

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBRename.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import org.xmldb.api.base.Resource;
4242
import org.xmldb.api.base.XMLDBException;
4343

44+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
45+
4446
/**
4547
* @author <a href="mailto:[email protected]">Wolfgang Meier</a>
4648
*
@@ -80,7 +82,7 @@ public Sequence evalWithCollection(Collection collection, Sequence[] args, Seque
8082
throws XPathException {
8183

8284
if(getSignature().getArgumentCount() == 3) {
83-
final XmldbURI doc = new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI();
85+
final XmldbURI doc = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI());
8486
try {
8587
final Resource resource = collection.getResource(doc.toString());
8688
if (resource == null) {

exist-core/src/main/java/org/exist/xquery/functions/xmldb/XMLDBSetMimeType.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import org.exist.xquery.value.SequenceType;
4747
import org.exist.xquery.value.Type;
4848

49+
import static org.exist.xquery.XPathException.execAndAddErrorIfMissing;
50+
4951
/**
5052
* @author <a href="mailto:[email protected]">Dannes Wessels</a>
5153
*/
@@ -74,7 +76,7 @@ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathExce
7476
final MimeTable mimeTable = MimeTable.getInstance();
7577

7678
// Get first parameter
77-
final String pathParameter = new AnyURIValue(args[0].itemAt(0).getStringValue()).toString();
79+
final String pathParameter = execAndAddErrorIfMissing(this, () -> new AnyURIValue(args[0].itemAt(0).getStringValue()).toString());
7880

7981
if (pathParameter.matches("^[a-z]+://.*")) {
8082
throw new XPathException("Can not set mime-type for resources outside the database.");

0 commit comments

Comments
 (0)