You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2026/09/29 00:09:13 UTC

(sis) branch geoapi-4.0 updated (8e8f2e2b92 -> 2cc5bb50ba)

This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


    from 8e8f2e2b92 Use `org.apache.sis.io.Authorization` for the GML access control of "xlink:href" attributes.
     new 03de331249 Cleanup related to relative files in WKT parameters.
     new 2cc5bb50ba Add a property for declaring that the environment is trusted. In trusted environment, some security constraints are relaxed.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/org/apache/sis/xml/ReferenceResolver.java | 26 ++++--------
 .../main/org/apache/sis/xml/XML.java               |  2 +-
 .../sis/xml/internal/shared/InputFactory.java      | 49 ++++++++++++----------
 .../org/apache/sis/xml/ReferenceResolverTest.java  |  8 +++-
 .../main/org/apache/sis/parameter/Parameters.java  |  5 +--
 .../operation/AbstractSingleOperation.java         |  2 +-
 .../operation/transform/MathTransformBuilder.java  | 16 +++++--
 .../geotiff/reader/ImageMetadataBuilder.java       |  1 +
 .../apache/sis/storage/netcdf/MetadataReader.java  | 14 +++----
 .../org/apache/sis/storage/base/PRJDataStore.java  |  4 +-
 .../main/org/apache/sis/storage/wkt/Store.java     |  3 +-
 .../org/apache/sis/storage/wkt/StoreFormat.java    |  5 +--
 .../main/org/apache/sis/setup/Configuration.java   | 38 +++++++++++++++--
 .../main/org/apache/sis/system/Environment.java    |  8 ++++
 optional/src/org.apache.sis.gui/bundle/bin/sis     |  1 +
 optional/src/org.apache.sis.gui/bundle/bin/sisfx   |  1 +
 16 files changed, 113 insertions(+), 70 deletions(-)


(sis) 02/02: Add a property for declaring that the environment is trusted. In trusted environment, some security constraints are relaxed.

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 2cc5bb50ba082b09244b3abb8f0238505bfdc367
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Mon Sep 28 18:11:52 2026 +0900

    Add a property for declaring that the environment is trusted.
    In trusted environment, some security constraints are relaxed.
---
 .../main/org/apache/sis/xml/ReferenceResolver.java | 26 ++++--------
 .../main/org/apache/sis/xml/XML.java               |  2 +-
 .../sis/xml/internal/shared/InputFactory.java      | 49 ++++++++++++----------
 .../org/apache/sis/xml/ReferenceResolverTest.java  |  8 +++-
 .../operation/transform/MathTransformBuilder.java  | 16 +++++--
 .../geotiff/reader/ImageMetadataBuilder.java       |  1 +
 .../main/org/apache/sis/setup/Configuration.java   | 38 +++++++++++++++--
 .../main/org/apache/sis/system/Environment.java    |  8 ++++
 optional/src/org.apache.sis.gui/bundle/bin/sis     |  1 +
 optional/src/org.apache.sis.gui/bundle/bin/sisfx   |  1 +
 10 files changed, 100 insertions(+), 50 deletions(-)

diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/ReferenceResolver.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/ReferenceResolver.java
index bfa3034b2b..4ce9f46b33 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/ReferenceResolver.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/ReferenceResolver.java
@@ -25,6 +25,8 @@ import javax.xml.transform.URIResolver;
 import jakarta.xml.bind.Unmarshaller;
 import org.opengis.metadata.Identifier;
 import org.apache.sis.io.Authorization;
+import org.apache.sis.system.Environment;
+import org.apache.sis.setup.Configuration;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Emptiable;
 import org.apache.sis.util.LenientComparable;
@@ -66,21 +68,6 @@ public class ReferenceResolver {
      */
     public static final ReferenceResolver DEFAULT = new ReferenceResolver();
 
-    /**
-     * A resolver which accepts to open all documents referenced by {@code xlink:href}.
-     * By {@linkplain #DEFAULT default}, only references in the same directory or sub-directory are followed.
-     * But if this resolver is specified as a {@link XML#RESOLVER} property, all <abbr>URI</abbr>s will be accepted.
-     *
-     * <p><b>Historical note:</b> this was the default behavior in Apache <abbr>SIS</abbr> 1.5 and 1.6, but
-     * <abbr>SIS</abbr> 1.7 reverted to not opening external document by default for security reasons.</p>
-     *
-     * @see XML#RESOLVER
-     * @see #accessControl(URI)
-     *
-     * @since 1.7
-     */
-    public static final ReferenceResolver FOLLOW_EXTERNAL_XLINK = new ReferenceResolver();
-
     /**
      * Provider of sources to use for unmarshalling objects referenced by links to another document.
      * It provides the {@code source} argument in {@link #resolveExternal(MarshalContext, Source)}.
@@ -394,15 +381,18 @@ public class ReferenceResolver {
      *       of the document containing the {@code xlink:href}, otherwise behave like {@code DENIED}.</li>
      * </ul>
      *
+     * The default implementation returns {@code GRANTED} in a
+     * {@linkplain Configuration#isTrustedEnvironment() trusted environment}, or {@code DEFAULT} otherwise.
+     * Security policy can be tuned more finely by overriding this method and specifying the customized
+     * {@code Resolver} instance as documented in {@link XML#RESOLVER}.
+     *
      * @param  document  the document or fragment referenced in a {@code xlink:href}.
      * @return whether the given document or fragment can be opened.
      *
-     * @see #FOLLOW_EXTERNAL_XLINK
-     *
      * @since 1.7
      */
     public Authorization accessControl(URI document) {
-        return (this == FOLLOW_EXTERNAL_XLINK) ? Authorization.GRANTED : Authorization.DEFAULT;
+        return Environment.isTrusted ? Authorization.GRANTED : Authorization.DEFAULT;
     }
 
     /**
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java
index 370d26481d..c34584386f 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/XML.java
@@ -253,7 +253,7 @@ public final class XML {
     /**
      * Allows client code to replace {@code xlink} or {@code uuidref} attributes by the actual data.
      * The value for this property shall be an instance of {@link ReferenceResolver}.
-     * The specified reference resolver (of if none, the {@linkplain ReferenceResolver#DEFAULT default} one)
+     * The specified reference resolver (or if none, the {@linkplain ReferenceResolver#DEFAULT default} one)
      * is used when a <abbr>XML</abbr> element is defined only by {@code xlink} or {@code uuidref} attributes,
      * without any concrete definition. The typical choices are:
      *
diff --git a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/internal/shared/InputFactory.java b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/internal/shared/InputFactory.java
index f2a35ad9e6..dc34cf48e9 100644
--- a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/internal/shared/InputFactory.java
+++ b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/xml/internal/shared/InputFactory.java
@@ -33,6 +33,7 @@ import javax.xml.transform.sax.SAXSource;
 import org.w3c.dom.Node;
 import org.xml.sax.InputSource;
 import org.apache.sis.system.Loggers;
+import org.apache.sis.system.Environment;
 import org.apache.sis.util.logging.Logging;
 
 
@@ -59,39 +60,41 @@ public final class InputFactory {
     private static final XMLInputFactory FACTORY = newSecureFactory();
 
     /**
-     * Creates a new <abbr>XML</abbr> factory with some security setting enabled.
+     * Do not allow instantiation of this class.
+     */
+    private InputFactory() {
+    }
+
+    /**
+     * Creates a new <abbr>XML</abbr> factory with some security setting enabled, unless the environment is trusted.
      *
      * @return a new <abbr>XML</abbr> factory.
      */
     public static XMLInputFactory newSecureFactory() {
         final XMLInputFactory factory = XMLInputFactory.newFactory();
-        if (factory.isPropertySupported(XMLConstants.FEATURE_SECURE_PROCESSING)) {
-            factory.setProperty(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-        }
-        try {
-            // No `isPropertySupported(…)` because support of this property is required.
-            if ("all".equals(factory.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD))) {
-                factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+        if (!Environment.isTrusted) {
+            if (factory.isPropertySupported(XMLConstants.FEATURE_SECURE_PROCESSING)) {
+                factory.setProperty(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+            }
+            try {
+                // No `isPropertySupported(…)` because support of this property is required.
+                if ("all".equals(factory.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD))) {
+                    factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+                }
+            } catch (IllegalArgumentException e) {
+                /*
+                 * `ACCESS_EXTERNAL_DTD` is clearly documented as a mandatory property since JAXP 1.5 in Java 7.
+                 * But Jackson 2.19.1, despite being released 14 years after Java 7, still doesn't support this
+                 * property.
+                 */
+                final var record = new LogRecord(Level.CONFIG, e.getLocalizedMessage());
+                record.setThrown(e);
+                Logging.completeAndLog(Logger.getLogger(Loggers.XML), InputFactory.class, "newSecureFactory", record);
             }
-        } catch (IllegalArgumentException e) {
-            /*
-             * `ACCESS_EXTERNAL_DTD` is clearly documented as a mandatory property since JAXP 1.5 in Java 7.
-             * But Jackson 2.19.1, despite being released 14 years after Java 7, still doesn't support this
-             * property.
-             */
-            final var record = new LogRecord(Level.CONFIG, e.getLocalizedMessage());
-            record.setThrown(e);
-            Logging.completeAndLog(Logger.getLogger(Loggers.XML), InputFactory.class, "newSecureFactory", record);
         }
         return factory;
     }
 
-    /**
-     * Do not allow instantiation of this class.
-     */
-    private InputFactory() {
-    }
-
     /*
      * Do not provide convenience method for java.io.File, because the caller needs to close the created
      * input stream himself (this is not done by XMLEventReader.close(), despite its method name).
diff --git a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/ReferenceResolverTest.java b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/ReferenceResolverTest.java
index 99b54c6751..b29a7cc2e3 100644
--- a/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/ReferenceResolverTest.java
+++ b/endorsed/src/org.apache.sis.metadata/test/org/apache/sis/xml/ReferenceResolverTest.java
@@ -21,9 +21,11 @@ import java.util.logging.Filter;
 import java.util.logging.LogRecord;
 import java.io.IOException;
 import java.nio.file.AccessDeniedException;
+import java.net.URI;
 import java.net.URISyntaxException;
 import javax.xml.transform.Source;
 import jakarta.xml.bind.JAXBException;
+import org.apache.sis.io.Authorization;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.identification.DataIdentification;
 
@@ -81,7 +83,11 @@ public final class ReferenceResolverTest extends TestUsingFile implements Filter
         final var properties = new HashMap<String, Object>(4);
         assertNull(properties.put(XML.WARNING_FILTER, this));
         if (readExternal) {
-            assertNull(properties.put(XML.RESOLVER, ReferenceResolver.FOLLOW_EXTERNAL_XLINK));
+            assertNull(properties.put(XML.RESOLVER, new ReferenceResolver() {
+                @Override public Authorization accessControl(URI document) {
+                    return Authorization.GRANTED;
+                }
+            }));
         }
         final var data = assertInstanceOf(DataIdentification.class, XML.unmarshal(source, properties));
         assertTrue(data.getAbstract().toString().startsWith("Test the use of XLink to an external document"));
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java
index 8de5698b8a..07bf20469c 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MathTransformBuilder.java
@@ -25,6 +25,8 @@ import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.OperationMethod;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.setup.Configuration;
+import org.apache.sis.system.Environment;
 import org.apache.sis.io.Authorization;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.internal.shared.Strings;
@@ -50,7 +52,9 @@ public abstract class MathTransformBuilder implements MathTransform.Builder {
 
     /**
      * A function which determines whether the <abbr>URI</abbr> specified in a parameter can be opened.
-     * The default access control returns {@link Authorization#DEFAULT}.
+     * The default access control returns {@link Authorization#DEFAULT} in non-trusted environment.
+     *
+     * @see #getAccessControl()
      */
     private BiFunction<ParameterDescriptor<URI>, URI, Authorization> accessControl;
 
@@ -76,7 +80,7 @@ public abstract class MathTransformBuilder implements MathTransform.Builder {
         accessControl = (param, file) -> {
             Objects.requireNonNull(param);
             Objects.requireNonNull(file);
-            return Authorization.DEFAULT;
+            return Environment.isTrusted ? Authorization.GRANTED : Authorization.DEFAULT;
         };
     }
 
@@ -102,13 +106,17 @@ public abstract class MathTransformBuilder implements MathTransform.Builder {
      *   <li>the actual <abbr>URI</abbr> parameter value.</li>
      * </ol>
      *
-     * The default access control is a function returning {@link Authorization#DEFAULT}.
-     * The default authorization grants access to files in the {@code $SIS_DATA/DatumChanges}
+     * The default access control is a function returning {@link Authorization#GRANTED}
+     * in a {@linkplain Configuration#isTrustedEnvironment() trusted environment},
+     * or {@link Authorization#DEFAULT} otherwise.
+     * The {@code DEFAULT} authorization grants access to files in the {@code $SIS_DATA/DatumChanges}
      * directory for parameters that are datum shift grid files, and to files in the same directory as the
      * <abbr>JSON</abbr>, <abbr>GML</abbr> or <abbr>WKT</abbr> document where the parameter value appears.
      *
      * @return a function deciding whether the <abbr>URI</abbr> can be opened.
      *
+     * @see org.apache.sis.setup.Configuration#isTrustedEnvironment()
+     *
      * @since 1.7
      */
     public BiFunction<ParameterDescriptor<URI>, URI, Authorization> getAccessControl() {
diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/ImageMetadataBuilder.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/ImageMetadataBuilder.java
index a0819d454e..8e5fbe81c9 100644
--- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/ImageMetadataBuilder.java
+++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/reader/ImageMetadataBuilder.java
@@ -174,6 +174,7 @@ public final class ImageMetadataBuilder extends MetadataBuilder {
      *
      * @throws DataStoreException if an error occurred while reading metadata from the data store.
      */
+    @SuppressWarnings("UseSpecificCatch")
     public void finish(final GeoTiffStore store, final StoreListeners listeners) throws DataStoreException {
         /*
          * Add the resolution into the metadata. Our current ISO 19115 implementation restricts
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java
index 3c076e9370..c6e799ee43 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/setup/Configuration.java
@@ -24,14 +24,15 @@ import java.util.concurrent.TimeUnit;
 import javax.sql.DataSource;
 import java.sql.SQLException;
 import org.apache.sis.system.Shutdown;
+import org.apache.sis.system.Environment;
 import org.apache.sis.system.SystemListener;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.internal.shared.MetadataServices;
 
 
 /**
- * Provides system-wide configuration for Apache SIS library.
- * Methods in this class can be used for overriding SIS default values.
+ * Provides system-wide configuration of the Apache <abbr>SIS</abbr> library.
+ * Methods in this class can be used for overriding <abbr>SIS</abbr> default values.
  * Those methods can be used in final applications, but should not be used by libraries
  * in order to avoid interfering with user's settings.
  *
@@ -45,7 +46,7 @@ import org.apache.sis.util.internal.shared.MetadataServices;
  * </ul>
  *
  * The following properties are defined by the standard Java environment.
- * Apache SIS read those properties but does not modify them:
+ * Apache SIS reads those properties but does not modify them:
  *
  * <ul>
  *   <li>{@link Locale#getDefault()} (sometimes using {@link Locale.Category})</li>
@@ -83,6 +84,37 @@ public final class Configuration {
         return DEFAULT;
     }
 
+    /**
+     * Returns whether to relax the default security settings.
+     * By default, Apache <abbr>SIS</abbr> applies the following restrictions:
+     *
+     * <ul>
+     *   <li>Disable all accesses to external <abbr>DTD</abbr>s and external Entity References
+     *       when reading <abbr>XML</abbr> documents.</li>
+     *   <li>Follow {@code xlink:href} only if it is an <abbr>XML</abbr> fragment or if the referenced file is in
+     *       the same directory or in a sub-directory of the <abbr>GML</abbr> file containing the reference.</li>
+     *   <li>Open file referenced in coordinate operation only if the parameter is a datum shift grid file
+     *       and the file is in the {@code $SIS_DATA/DatumChanges} directory, or (for any parameter) if the
+     *       file is in the same directory or in a sub-directory of
+     *       <abbr>JSON</abbr>, <abbr>GML</abbr> or <abbr>WKT</abbr> file containing the parameter value.</li>
+     * </ul>
+     *
+     * If the {@systemProperty org.apache.sis.trustedEnvironment} is set to {@code true},
+     * the above listed restrictions are ignored.
+     *
+     * @return whether the default security restrictions are relaxed.
+     *
+     * @see javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD
+     * @see javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING
+     * @see org.apache.sis.xml.ReferenceResolver#DEFAULT
+     * @see org.apache.sis.referencing.operation.transform.MathTransformBuilder#getAccessControl()
+     *
+     * @since 1.7
+     */
+    public boolean isTrustedEnvironment() {
+        return Environment.isTrusted;
+    }
+
     /**
      * Returns the data source for the <abbr>SIS</abbr>-wide "SpatialMetadata" database.
      * This method returns the first of the following steps that succeed:
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/Environment.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/Environment.java
index dc2844327c..bd6e2e171f 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/Environment.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/system/Environment.java
@@ -30,6 +30,13 @@ import org.apache.sis.pending.jdk.JDK17;
  * @author  Martin Desruisseaux (Geomatys)
  */
 public final class Environment {
+    /**
+     * Whether to relax security restrictions.
+     *
+     * @see org.apache.sis.setup.Configuration#isTrustedEnvironment()
+     */
+    public static final boolean isTrusted = Boolean.getBoolean("org.apache.sis.trustedEnvironment");
+
     /**
      * Whether the use of the console writer should be avoided.
      *
@@ -62,6 +69,7 @@ public final class Environment {
      *
      * @return the writer to use.
      */
+    @SuppressWarnings("UseOfSystemOutOrSystemErr")
     public static PrintWriter writer() {
         return writer(System.console(), System.out);
     }
diff --git a/optional/src/org.apache.sis.gui/bundle/bin/sis b/optional/src/org.apache.sis.gui/bundle/bin/sis
index e82a73d56a..5daf4a5e06 100755
--- a/optional/src/org.apache.sis.gui/bundle/bin/sis
+++ b/optional/src/org.apache.sis.gui/bundle/bin/sis
@@ -30,5 +30,6 @@ export COLUMNS
 java --module-path "$BASE_DIR/lib:$BASE_DIR/lib/app/org.apache.sis.console.jar" \
      -Djava.util.logging.config.class="org.apache.sis.util.logging.Initializer" \
      -Djava.util.logging.config.file="$BASE_DIR/conf/logging.properties" \
+     -Dorg.apache.sis.trustedEnvironment=true \
      --module org.apache.sis.console/org.apache.sis.console.Command \
      $SIS_OPTS "$@"
diff --git a/optional/src/org.apache.sis.gui/bundle/bin/sisfx b/optional/src/org.apache.sis.gui/bundle/bin/sisfx
index a5ed59ff7e..55aeceb785 100755
--- a/optional/src/org.apache.sis.gui/bundle/bin/sisfx
+++ b/optional/src/org.apache.sis.gui/bundle/bin/sisfx
@@ -93,6 +93,7 @@ java -splash:"$BASE_DIR/lib/logo.jpg" \
      --module-path "$PATH_TO_FX:$BASE_DIR/lib:$BASE_DIR/lib/app/org.apache.sis.gui.jar" \
      -Djava.util.logging.config.class="org.apache.sis.util.logging.Initializer" \
      -Djava.util.logging.config.file="$BASE_DIR/conf/logging.properties" \
+     -Dorg.apache.sis.trustedEnvironment=true \
      $ADD_OPTIONAL_MODULES \
      --module org.apache.sis.gui/org.apache.sis.gui.DataViewer \
      $SIS_OPTS "$@"


(sis) 01/02: Cleanup related to relative files in WKT parameters.

Posted by de...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 03de33124954e090b27097efd2fb66201d8da51f
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Sep 25 16:38:33 2026 +0900

    Cleanup related to relative files in WKT parameters.
---
 .../main/org/apache/sis/parameter/Parameters.java          |  5 ++---
 .../sis/referencing/operation/AbstractSingleOperation.java |  2 +-
 .../main/org/apache/sis/storage/netcdf/MetadataReader.java | 14 +++++---------
 .../main/org/apache/sis/storage/base/PRJDataStore.java     |  4 ++--
 .../main/org/apache/sis/storage/wkt/Store.java             |  3 ++-
 .../main/org/apache/sis/storage/wkt/StoreFormat.java       |  5 +----
 6 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java
index 9c6a0cbec1..ab4266f8f0 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/Parameters.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.parameter;
 
-import java.util.Map;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Optional;
@@ -297,7 +296,7 @@ public abstract class Parameters implements ParameterValueGroup, Cloneable, Prin
         if (parameters == null) {
             return null;
         }
-        final GeneralParameterDescriptor[] descriptors = new GeneralParameterDescriptor[parameters.length];
+        final var descriptors = new GeneralParameterDescriptor[parameters.length];
         for (int i=0; i<parameters.length; i++) {
             final GeneralParameterValue p = parameters[i];
             if (p != null) {
@@ -913,7 +912,7 @@ public abstract class Parameters implements ParameterValueGroup, Cloneable, Prin
             throws InvalidParameterNameException, InvalidParameterValueException
     {
         final Integer ZERO = 0;
-        final Map<String,Integer> occurrences = new HashMap<>();
+        final var occurrences = new HashMap<String, Integer>();
         for (final GeneralParameterValue value : values.values()) {
             final String name = value.getDescriptor().getName().getCode();
             final int occurrence = occurrences.getOrDefault(name, ZERO);
diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractSingleOperation.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractSingleOperation.java
index c97b956b88..3294d97433 100644
--- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractSingleOperation.java
+++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/AbstractSingleOperation.java
@@ -412,7 +412,7 @@ class AbstractSingleOperation extends AbstractCoordinateOperation implements Sin
              * because Apache SIS infers the type from the actual parameter value. The `merge` method
              * below puts those information together.
              */
-            final Map<GeneralParameterDescriptor,GeneralParameterDescriptor> replacements = new IdentityHashMap<>(4);
+            final var replacements = new IdentityHashMap<GeneralParameterDescriptor, GeneralParameterDescriptor>(4);
             final GeneralParameterDescriptor[] merged = CC_OperationParameterGroup.merge(
                     method.getParameters().descriptors(),
                     Parameters.getDescriptors(values),
diff --git a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
index 43ae7b17ff..e9ec40cf82 100644
--- a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
+++ b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -190,14 +190,6 @@ final class MetadataReader extends MetadataBuilder {
         searchPath = decoder.getSearchPath();
     }
 
-    /**
-     * Returns the netCDF file as an <abbr>URI</abbr>, or {@code null} if none.
-     */
-    private URI location() {
-        final Path location = decoder.location;
-        return (location != null) ? location.toUri() : null;
-    }
-
     /**
      * Invoked when a non-fatal exception occurred while reading metadata.
      * This method sends a record to the registered listeners if any,
@@ -661,7 +653,11 @@ split:  while ((start = CharSequences.skipLeadingWhitespaces(value, start, lengt
          */
         final String wkt = stringValue(GEOSPATIAL_BOUNDS);
         if (wkt != null) {
-            var parser = new StoreFormat(location(), null, null, decoder.geomlib, decoder.listeners);
+            var parser = new StoreFormat(null, null, decoder.geomlib, decoder.listeners);
+            final Path location = decoder.location;
+            if (location != null) {
+                parser.setSourceFile(location.toUri());
+            }
             addBoundingPolygon(parser.parseGeometry(wkt,
                     stringValue(GEOSPATIAL_BOUNDS + "_crs"),
                     stringValue(GEOSPATIAL_BOUNDS + "_vertical_crs")));
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
index 772ab836b9..7ae3a2d2a0 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/PRJDataStore.java
@@ -165,7 +165,7 @@ public abstract class PRJDataStore extends URIDataStore {
                 throw new DataStoreException(s.getMessage(getLocale()), s.exception);
             }
             final String wkt = content.toString();
-            final var format = new StoreFormat(content.getURI(), dataLocale, timezone, null, listeners);
+            final var format = new StoreFormat(dataLocale, timezone, null, listeners);
             format.setConvention(getConvention());          // Ignored if the format is WKT 2.
             try {
                 format.setSourceFile(content.getURI());
@@ -213,7 +213,7 @@ public abstract class PRJDataStore extends URIDataStore {
             if (crs == null) {
                 deleteAuxiliaryFile(PRJ);
             } else try (BufferedWriter out = writeAuxiliaryFile(PRJ)) {
-                final var format = new StoreFormat(null, dataLocale, timezone, null, listeners);
+                final var format = new StoreFormat(dataLocale, timezone, null, listeners);
                 format.setConvention(Convention.WKT2_2015);     // TODO: upgrade to newer version.
                 format.format(crs, out);
                 out.newLine();
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java
index 544da67e8f..5bf89570cc 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/Store.java
@@ -125,7 +125,8 @@ final class Store extends URIDataStore {
              * definitions.
              */
             final var pos = new ParsePosition(0);
-            final var parser = new StoreFormat(location, dataLocale, timezone, library, listeners);
+            final var parser = new StoreFormat(dataLocale, timezone, library, listeners);
+            parser.setSourceFile(location);
             do {
                 final Object obj = parser.parse(wkt, pos);
                 objects.add(obj);
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java
index fe4b4cf2a4..df464ea39f 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/wkt/StoreFormat.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.storage.wkt;
 
-import java.net.URI;
 import java.text.ParseException;
 import java.time.ZoneId;
 import java.util.Locale;
@@ -63,19 +62,17 @@ public final class StoreFormat extends WKTFormat {
      * The given locale will be used for {@link InternationalString} localization;
      * this is <strong>not</strong> the locale for number format.
      *
-     * @param  source     the file being parsed, or {@code null} if unknown.
      * @param  locale     the locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.
      * @param  timezone   the timezone, or {@code null} for UTC.
      * @param  library    the geometry library, or {@code null} for the default.
      * @param  listeners  where to send warnings.
      */
-    public StoreFormat(final URI source, final Locale locale, final ZoneId timezone,
+    public StoreFormat(final Locale locale, final ZoneId timezone,
                        final GeometryLibrary library, final StoreListeners listeners)
     {
         super(locale, timezone);
         this.library   = library;
         this.listeners = listeners;
-        setSourceFile(source);
     }
 
     /**