From 0a4701855060946fe57142bce7226d2410e839f6 Mon Sep 17 00:00:00 2001 From: Juri Leino Date: Mon, 16 Oct 2023 20:27:36 +0200 Subject: [PATCH] [fix] handle IllegalStateException in file:directory-list#2 fixes #5028 The Java code of DirectoryList can throw an IllegalStateException when a non-existent directory is supplied as its first argument. This exception class is now handled in file:list#2. Additionally, the raised error now has a proper code `file:DIRECTORY_NOT_FOUND`. This will allow us in the future to add proper error codes to more errors raised by this module. --- .../xquery/modules/file/DirectoryList.java | 17 +++---- .../xquery/modules/file/FileErrorCode.java | 33 +++++++++++++ .../xquery/modules/file/directory-list.xqm | 47 +++++++++++++++++++ 3 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 extensions/modules/file/src/main/java/org/exist/xquery/modules/file/FileErrorCode.java create mode 100644 extensions/modules/file/src/test/xquery/modules/file/directory-list.xqm diff --git a/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/DirectoryList.java b/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/DirectoryList.java index df783fd186d..de6ab2dd0a3 100644 --- a/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/DirectoryList.java +++ b/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/DirectoryList.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Date; import org.apache.logging.log4j.LogManager; @@ -34,11 +33,7 @@ import org.exist.dom.QName; import org.exist.dom.memtree.MemTreeBuilder; import org.exist.util.FileUtils; -import org.exist.xquery.BasicFunction; -import org.exist.xquery.Cardinality; -import org.exist.xquery.FunctionSignature; -import org.exist.xquery.XPathException; -import org.exist.xquery.XQueryContext; +import org.exist.xquery.*; import org.exist.xquery.value.DateTimeValue; import org.exist.xquery.value.FunctionParameterSequenceType; import org.exist.xquery.value.FunctionReturnSequenceType; @@ -47,9 +42,11 @@ import org.exist.xquery.value.SequenceType; import org.exist.xquery.value.Type; +import static org.exist.xquery.modules.file.FileErrorCode.DIRECTORY_NOT_FOUND; + /** * eXist File Module Extension DirectoryList - * + *

* Enumerate a list of files, including their size and modification time, found * in a specified directory, using a pattern * @@ -121,7 +118,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro builder.addAttribute(new QName("directory", null, null), baseDir.toString()); try { final int patternsLen = patterns.getItemCount(); - final String includes[] = new String[patternsLen]; + final String[] includes = new String[patternsLen]; for (int i = 0; i < patternsLen; i++) { includes[i] = patterns.itemAt(0).getStringValue(); } @@ -172,8 +169,8 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro builder.endElement(); return (NodeValue) builder.getDocument().getDocumentElement(); - } catch (final IOException e) { - throw new XPathException(this, e.getMessage()); + } catch (final IOException | IllegalStateException e) { + throw new XPathException(this, DIRECTORY_NOT_FOUND, e.getMessage()); } finally { context.popDocumentContext(); } diff --git a/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/FileErrorCode.java b/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/FileErrorCode.java new file mode 100644 index 00000000000..2e23f59fc7e --- /dev/null +++ b/extensions/modules/file/src/main/java/org/exist/xquery/modules/file/FileErrorCode.java @@ -0,0 +1,33 @@ +/* + * eXist-db Open Source Native XML Database + * Copyright (C) 2001 The eXist-db Authors + * + * info@exist-db.org + * http://www.exist-db.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package org.exist.xquery.modules.file; + +import org.exist.dom.QName; +import org.exist.xquery.ErrorCodes; + +class FileErrorCode extends ErrorCodes.ErrorCode { + public static final ErrorCodes.ErrorCode DIRECTORY_NOT_FOUND = new FileErrorCode("DIRECTORY_NOT_FOUND", "The directory could not be found."); + + FileErrorCode(String code, String description) { + super(new QName(code, FileModule.NAMESPACE_URI, FileModule.PREFIX), description); + } +} diff --git a/extensions/modules/file/src/test/xquery/modules/file/directory-list.xqm b/extensions/modules/file/src/test/xquery/modules/file/directory-list.xqm new file mode 100644 index 00000000000..19411da4517 --- /dev/null +++ b/extensions/modules/file/src/test/xquery/modules/file/directory-list.xqm @@ -0,0 +1,47 @@ +(: + : eXist-db Open Source Native XML Database + : Copyright (C) 2001 The eXist-db Authors + : + : info@exist-db.org + : http://www.exist-db.org + : + : This library is free software; you can redistribute it and/or + : modify it under the terms of the GNU Lesser General Public + : License as published by the Free Software Foundation; either + : version 2.1 of the License, or (at your option) any later version. + : + : This library is distributed in the hope that it will be useful, + : but WITHOUT ANY WARRANTY; without even the implied warranty of + : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + : Lesser General Public License for more details. + : + : You should have received a copy of the GNU Lesser General Public + : License along with this library; if not, write to the Free Software + : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + :) +xquery version "3.1"; + +module namespace dirlist="http://exist-db.org/testsuite/modules/file/dirlist"; + + +import module namespace file="http://exist-db.org/xquery/file"; + + +declare namespace test="http://exist-db.org/xquery/xqsuite"; + + +declare + %test:assertError("file:DIRECTORY_NOT_FOUND") +function dirlist:non-existent-error-code() { + file:directory-list("/non/existent", ()) +}; + +declare + %test:assertXPath("contains($result,'basedir /non/existent does not exist.')") +function dirlist:non-existent-error-description() { + try { + file:directory-list("/non/existent", ()) + } catch file:DIRECTORY_NOT_FOUND { + $err:description + } +};