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 8ff703b6c65fd6e95214639400e01548c4ca79c4
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Fri Oct 2 12:06:19 2026 +0200

    Security recommendation for MySQL/MariaDB.
    Fix an error message in netCDF reader.
---
 .../metadata/sql/internal/shared/SQLBuilder.java   | 26 ++++++++++++++++------
 .../org/apache/sis/storage/netcdf/NetcdfStore.java |  2 +-
 .../sis/storage/netcdf/NetcdfStoreProvider.java    |  6 ++---
 .../sis/storage/netcdf/classic/ChannelDecoder.java |  7 +++---
 .../apache/sis/storage/netcdf/package-info.java    |  2 +-
 .../main/module-info.java                          | 13 ++++++++---
 .../org/apache/sis/storage/sql/package-info.java   |  7 +++++-
 7 files changed, 43 insertions(+), 20 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/SQLBuilder.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/SQLBuilder.java
index 01e4015e7f..2455bff4f5 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/SQLBuilder.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/sql/internal/shared/SQLBuilder.java
@@ -167,18 +167,25 @@ public class SQLBuilder extends Syntax {
      * Appends an identifier between quote characters.
      * If the identifier contains quotes, the quotes will be doubled.
      *
+     * @todo Replace by {@link Connection#enquoteIdentifier(String, boolean)}
+     * when we will be allowed to compile for JDK26.
+     *
      * @param  name  the identifier to append.
      * @return this builder, for method call chaining.
      */
     public final SQLBuilder appendIdentifier(final String name) {
-        int i = buffer.append(identifierQuote).length();
-        buffer.append(name);
-        while ((i = buffer.indexOf(identifierQuote, i)) >= 0) {
-            final int n = identifierQuote.length();
-            buffer.insert(i += n, identifierQuote);
-            i += n;
+        if (identifierQuote.isEmpty()) {
+            buffer.append(name);
+        } else {
+            int i = buffer.append(identifierQuote).length();
+            buffer.append(name);
+            while ((i = buffer.indexOf(identifierQuote, i)) >= 0) {
+                final int n = identifierQuote.length();
+                buffer.insert(i += n, identifierQuote);
+                i += n;
+            }
+            buffer.append(identifierQuote);
         }
-        buffer.append(identifierQuote);
         return this;
     }
 
@@ -205,6 +212,8 @@ public class SQLBuilder extends Syntax {
      * The name part is quoted only if {@code quoteName} is {@code true}.
      * Unquoted names are useful when the name is for built-in functions,
      * which often use the lower/upper case convention of the database.
+     * In the latter case, the caller must ensure that the {@code name}
+     * does not contain the quote character.
      *
      * <h4>Simplification</h4>
      * If the given catalog is equal to the {@linkplain 
Connection#getCatalog() catalog which was current} when
@@ -262,6 +271,9 @@ public class SQLBuilder extends Syntax {
      * Appends a value in a {@code SELECT} or {@code INSERT} statement.
      * The value is written between quotes.
      *
+     * @todo Replace by {@link Connection#enquoteLiteral(String)} when we will 
be allowed to compile for JDK26.
+     * This is important for MySQL/MariaDB, which may use the backslash as an 
escaping character.
+     *
      * @param  value  the value to append, or {@code null}.
      * @return this builder, for method call chaining.
      */
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
index 48793ae1ae..eee38a13fa 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStore.java
@@ -60,7 +60,7 @@ import org.apache.sis.util.internal.shared.Constants;
  * Instances of this data store are created by {@link 
NetcdfStoreProvider#open(StorageConnector)}.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.6
+ * @version 1.7
  *
  * @see NetcdfStoreProvider
  *
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
index 2af0c516bb..32cdbce872 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/NetcdfStoreProvider.java
@@ -67,7 +67,7 @@ import org.apache.sis.util.internal.shared.Constants;
  * the part of the caller. However, the {@link NetcdfStore} instances created 
by this factory are not thread-safe.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.4
+ * @version 1.7
  *
  * @see NetcdfStore
  *
@@ -315,10 +315,8 @@ public class NetcdfStoreProvider extends DataStoreProvider 
{
                 keepOpen = path;
             } catch (IOException | DataStoreException s) {
                 e.addSuppressed(s);
-                throw e;
-            } else {
-                throw e;
             }
+            throw e;
         } else {
             keepOpen = connector.getStorage();
             decoder = createByReflection(keepOpen, true, geomlib, listeners);
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java
index 0eaba588bf..82a4e7d459 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/classic/ChannelDecoder.java
@@ -44,6 +44,7 @@ import 
org.opengis.parameter.InvalidParameterCardinalityException;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
+import org.apache.sis.storage.UnsupportedEncodingException;
 import org.apache.sis.storage.metadata.MetadataBuilder;
 import org.apache.sis.storage.netcdf.base.DataType;
 import org.apache.sis.storage.netcdf.base.Decoder;
@@ -244,7 +245,7 @@ public final class ChannelDecoder extends Decoder {
          */
         int version = input.readInt();
         if ((version & 0xFFFFFF00) != MAGIC_NUMBER) {
-            throw new 
DataStoreContentException(errors().getString(Errors.Keys.UnexpectedFileFormat_2,
 FORMAT_NAME, getFilename()));
+            throw new 
UnsupportedEncodingException(errors().getString(Errors.Keys.UnexpectedFileFormat_2,
 FORMAT_NAME, getFilename()));
         }
         /*
          * Check the version number.
@@ -253,7 +254,7 @@ public final class ChannelDecoder extends Decoder {
         switch (version) {
             case 1:  is64bits = false; break;
             case 2:  is64bits = true;  break;
-            default: throw new 
DataStoreContentException(errors().getString(Errors.Keys.UnsupportedFormatVersion_2,
 FORMAT_NAME, version));
+            default: throw new 
UnsupportedEncodingException(errors().getString(Errors.Keys.UnsupportedFormatVersion_2,
 FORMAT_NAME, version));
             // If more cases are added, remember to increment the MAX_VERSION 
constant.
         }
         numrecs = input.readInt();
@@ -432,7 +433,7 @@ public final class ChannelDecoder extends Decoder {
             return;
         }
         args[0] = tagPath(tagName(tag));
-        throw new DataStoreContentException(errors().getString(key, 
tagPath(tagName(tag))));
+        throw new DataStoreContentException(errors().getString(key, args));
     }
 
     /**
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/package-info.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/package-info.java
index b0885b3270..f7dff8776b 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/package-info.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/package-info.java
@@ -40,7 +40,7 @@
  * Care must be taken for avoiding confusion when using SIS and UCAR libraries 
together.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.6
+ * @version 1.7
  * @since   0.3
  */
 package org.apache.sis.storage.netcdf;
diff --git a/endorsed/src/org.apache.sis.storage.sql/main/module-info.java 
b/endorsed/src/org.apache.sis.storage.sql/main/module-info.java
index bb0104a6d9..416941c47d 100644
--- a/endorsed/src/org.apache.sis.storage.sql/main/module-info.java
+++ b/endorsed/src/org.apache.sis.storage.sql/main/module-info.java
@@ -21,12 +21,12 @@
  * <a href="https://www.ogc.org/standards/sfs";>OGC Simple feature access - 
Part 2: SQL option</a>
  * international standard, also known as <abbr>ISO</abbr> 19125-2.
  *
- * <h2>Difference with Geopackage</h2>
+ * <h2>Differences with Geopackage</h2>
  * Compared to the <abbr>OGC</abbr> Geopackage standard,
  * this <abbr>SQL</abbr> module has the following differences:
  *
  * <ul>
- *   <li>There is no discovery mechanism (e.g., no {@code "gpkg_contents"} 
table).
+ *   <li>There is no {@code "gpkg_contents"} table.
  *       The tables to use as {@linkplain 
org.apache.sis.storage.sql.ResourceDefinition resource definitions}
  *       must be specified explicitly.</li>
  *   <li>Each feature table can contain an arbitrary number of geometry 
columns, including zero.
@@ -38,11 +38,18 @@
  *       (made of many columns). By contrast, Geopackage mandates primary keys 
made of exactly one column of integers.</li>
  * </ul>
  *
+ * <h2>Recommended database configuration</h2>
+ * <p><b>PostgreSQL</b> databases should have the PostGIS extension installed 
(optional but recommended).</p>
+ *
+ * <p><b>MySQL/MariaDB</b> databases should set the <abbr>SQL</abbr> mode to 
at least {@code NO_BACKSLASH_ESCAPES}.
+ * See <a 
href="https://mariadb.com/docs/server/server-management/variables-and-modes/sql_mode#no_backslash_escapes";>
+ * MariaDB documentation</a>.</p>
+ *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
  * @author  Guilhem Legal (Geomatys)
- * @version 1.6
+ * @version 1.7
  * @since   1.0
  */
 module org.apache.sis.storage.sql {
diff --git 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
index c764390369..4d00813196 100644
--- 
a/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
+++ 
b/endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/package-info.java
@@ -53,10 +53,15 @@
  * those other features are created at the same time as the parent feature. 
There is no lazy instantiation yet.
  * Performances should be okay if each parent feature references only a small 
amount of children.</p>
  *
+ * <h2>Security</h2>
+ * MySQL/MariaDB databases should set the <abbr>SQL</abbr> mode to at least 
{@code NO_BACKSLASH_ESCAPES}.
+ * See <a 
href="https://mariadb.com/docs/server/server-management/variables-and-modes/sql_mode#no_backslash_escapes";>
+ * MariaDB documentation</a>.
+ *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.6
+ * @version 1.7
  * @since   1.0
  */
 package org.apache.sis.storage.sql;

Reply via email to