Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package opennlp for openSUSE:Factory checked 
in at 2026-07-24 22:07:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/opennlp (Old)
 and      /work/SRC/openSUSE:Factory/.opennlp.new.2004 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "opennlp"

Fri Jul 24 22:07:06 2026 rev:6 rq:1367685 version:1.9.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/opennlp/opennlp.changes  2026-07-15 
22:15:20.166709218 +0200
+++ /work/SRC/openSUSE:Factory/.opennlp.new.2004/opennlp.changes        
2026-07-24 22:07:58.811235070 +0200
@@ -1,0 +2,9 @@
+Fri Jul 24 14:34:26 UTC 2026 - Fridrich Strba <[email protected]>
+
+- Added patch:
+  * opennlp-CVE-2026-63317.patch
+    + Backport of 2.x fixes for bsc#1272520, CVE-2026-63317:
+      Arbitrary Class Instantiation via XML Feature Generator
+      Descriptor and Format Name in Apache OpenNLP
+
+-------------------------------------------------------------------

New:
----
  opennlp-CVE-2026-63317.patch

----------(New B)----------
  New:- Added patch:
  * opennlp-CVE-2026-63317.patch
    + Backport of 2.x fixes for bsc#1272520, CVE-2026-63317:
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ opennlp.spec ++++++
--- /var/tmp/diff_new_pack.dzILGK/_old  2026-07-24 22:08:00.279286325 +0200
+++ /var/tmp/diff_new_pack.dzILGK/_new  2026-07-24 22:08:00.279286325 +0200
@@ -23,6 +23,7 @@
 License:        Apache-2.0
 URL:            https://opennlp.apache.org/
 Source0:        
https://archive.apache.org/dist/opennlp/%{name}-%{version}/apache-%{name}-%{version}-src.tar.gz
+Patch0:         opennlp-CVE-2026-63317.patch
 BuildRequires:  fdupes
 BuildRequires:  java-devel >= 1.8
 BuildRequires:  maven-local
@@ -77,6 +78,8 @@
 find . -name '*.jar' -print -delete
 find . -name '*.bat' -print -delete
 find . -name '*.class' -print -delete
+# Patches
+%patch -P 0 -p1
 
 # use latest OSGi implementation
 %pom_change_dep -r :org.osgi.core org.osgi:osgi.core

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.dzILGK/_old  2026-07-24 22:08:00.335288280 +0200
+++ /var/tmp/diff_new_pack.dzILGK/_new  2026-07-24 22:08:00.339288419 +0200
@@ -1,6 +1,6 @@
-mtime: 1784101949
-commit: b9bc41e9993394a12f99e9eab9d003bb45d43b1818f558c915e1c674d2f0e2aa
+mtime: 1784904848
+commit: 4f250b3ecad70439da69846bd12f01f4788cac2c612da6ccb562dc74d7c5e8b3
 url: https://src.opensuse.org/java-packages/opennlp
-revision: b9bc41e9993394a12f99e9eab9d003bb45d43b1818f558c915e1c674d2f0e2aa
+revision: 4f250b3ecad70439da69846bd12f01f4788cac2c612da6ccb562dc74d7c5e8b3
 projectscmsync: https://src.opensuse.org/java-packages/_ObsPrj
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-07-24 16:54:08.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ opennlp-CVE-2026-63317.patch ++++++
diff --git 
a/opennlp-tools/src/main/java/opennlp/tools/cmdline/StreamFactoryRegistry.java 
b/opennlp-tools/src/main/java/opennlp/tools/cmdline/StreamFactoryRegistry.java
index db95a4f4..eb4c15f3 100644
--- 
a/opennlp-tools/src/main/java/opennlp/tools/cmdline/StreamFactoryRegistry.java
+++ 
b/opennlp-tools/src/main/java/opennlp/tools/cmdline/StreamFactoryRegistry.java
@@ -65,6 +65,8 @@ import 
opennlp.tools.formats.nkjp.NKJPSentenceSampleStreamFactory;
 import opennlp.tools.formats.ontonotes.OntoNotesNameSampleStreamFactory;
 import opennlp.tools.formats.ontonotes.OntoNotesPOSSampleStreamFactory;
 import opennlp.tools.formats.ontonotes.OntoNotesParseSampleStreamFactory;
+import opennlp.tools.util.ext.ExtensionLoader;
+import opennlp.tools.util.ext.ExtensionNotLoadedException;
 
 /**
  * Registry for object stream factories.
@@ -193,12 +195,18 @@ public final class StreamFactoryRegistry {
   }
 
   /**
-   * Returns a factory which reads format named <code>formatName</code> and
-   * instantiates streams producing objects of <code>sampleClass</code> class.
+   * Returns a factory which reads format named {@code formatName} and
+   * instantiates streams producing objects of {@code sampleClass} class.
+   * <p>
+   * If no factory is registered for {@code formatName}, an attempt is made to
+   * interpret {@code formatName} as the fully qualified class name of an
+   * {@link ObjectStreamFactory} implementation and load it via the
+   * {@link ExtensionLoader}. Such a class must reside in an allowed package,
+   * see {@link ExtensionLoader#registerAllowedPackage(String)}.
    *
    * @param sampleClass class of the objects, produced by the streams 
instantiated by the factory
    * @param formatName  name of the format, if null, assumes OpenNLP format
-   * @return factory instance
+   * @return factory instance, or {@code null} if no factory could be found or 
loaded
    */
   @SuppressWarnings("unchecked")
   public static <T> ObjectStreamFactory<T> getFactory(Class<T> sampleClass,
@@ -215,18 +223,9 @@ public final class StreamFactoryRegistry {
     }
     else {
       try {
-        Class<?> factoryClazz = Class.forName(formatName);
-
-        // TODO: Need to check if it can produce the desired output
-        // Otherwise there will be class cast exceptions later in the flow
-
-        try {
-          return (ObjectStreamFactory<T>) factoryClazz.newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
-          return null;
-        }
-
-      } catch (ClassNotFoundException e) {
+        return (ObjectStreamFactory<T>)
+            ExtensionLoader.instantiateExtension(ObjectStreamFactory.class, 
formatName);
+      } catch (ExtensionNotLoadedException e) {
         return null;
       }
     }
diff --git 
a/opennlp-tools/src/main/java/opennlp/tools/util/featuregen/GeneratorFactory.java
 
b/opennlp-tools/src/main/java/opennlp/tools/util/featuregen/GeneratorFactory.java
index 71b5822d..18eb2628 100644
--- 
a/opennlp-tools/src/main/java/opennlp/tools/util/featuregen/GeneratorFactory.java
+++ 
b/opennlp-tools/src/main/java/opennlp/tools/util/featuregen/GeneratorFactory.java
@@ -19,8 +19,6 @@ package opennlp.tools.util.featuregen;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
@@ -529,18 +527,13 @@ public class GeneratorFactory {
     }
     else {
       try {
-        Class factoryClass = Class.forName(className);
-        try {
-          Constructor constructor = factoryClass.getConstructor();
-          AbstractXmlFeatureGeneratorFactory factory =
-              (AbstractXmlFeatureGeneratorFactory)constructor.newInstance();
-          factory.init(generatorElement, resourceManager);
-          return factory.create();
-        } catch (NoSuchMethodException | InvocationTargetException | 
InstantiationException
-            | IllegalAccessException e) {
-          throw new RuntimeException(e);
-        }
-      } catch (ClassNotFoundException e) {
+        final AbstractXmlFeatureGeneratorFactory factory =
+            
ExtensionLoader.instantiateExtension(AbstractXmlFeatureGeneratorFactory.class, 
className);
+        factory.init(generatorElement, resourceManager);
+        return factory.create();
+      } catch (InvalidFormatException e) {
+        throw e;
+      } catch (Exception e) {
         throw new RuntimeException(e);
       }
     }
@@ -621,21 +614,15 @@ public class GeneratorFactory {
     String className = element.getAttribute("class");
     if (className != null) {
       try {
-        Class factoryClass = Class.forName(className);
-        try {
-          Constructor constructor = factoryClass.getConstructor();
-          AbstractXmlFeatureGeneratorFactory factory =
-              (AbstractXmlFeatureGeneratorFactory)constructor.newInstance();
-          factory.init(element, null);
-          Map<String, ArtifactSerializer<?>> map = 
factory.getArtifactSerializerMapping();
-          if (map != null)
-            mapping.putAll(map);
-        } catch (NoSuchMethodException | InvocationTargetException | 
InstantiationException
-            | IllegalAccessException e) {
-          throw new RuntimeException(e);
-        } catch (InvalidFormatException ignored) {
+        final AbstractXmlFeatureGeneratorFactory factory =
+            
ExtensionLoader.instantiateExtension(AbstractXmlFeatureGeneratorFactory.class, 
className);
+        factory.init(element, null);
+        final Map<String, ArtifactSerializer<?>> map = 
factory.getArtifactSerializerMapping();
+        if (map != null) {
+          mapping.putAll(map);
         }
-      } catch (ClassNotFoundException e) {
+      } catch (InvalidFormatException ignored) {
+      } catch (Exception e) {
         throw new RuntimeException(e);
       }
     }
diff --git 
a/opennlp-tools/src/main/java/opennlp/tools/util/model/BaseModel.java 
b/opennlp-tools/src/main/java/opennlp/tools/util/model/BaseModel.java
index a6a9a226..67106b6c 100644
--- a/opennlp-tools/src/main/java/opennlp/tools/util/model/BaseModel.java
+++ b/opennlp-tools/src/main/java/opennlp/tools/util/model/BaseModel.java
@@ -24,9 +24,11 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InvalidClassException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
+import java.io.ObjectStreamClass;
 import java.io.Serializable;
 import java.net.URL;
 import java.nio.file.Path;
@@ -625,6 +627,44 @@ public abstract class BaseModel implements 
ArtifactProvider, Serializable {
     return isLoadedFromSerialized;
   }
 
+  /**
+   * Deserializes a {@link BaseModel} from the given {@link InputStream} using 
the
+   * standard {@link Serializable} mechanism, with class validation applied
+   * to reject any class outside the allowlist - including the top-level 
object itself.
+   * <p>
+   * Prefer this method (or the {@code BaseModel(String, 
InputStream|File|Path|URL)}
+   * constructors) over calling {@code new ObjectInputStream(in).readObject()} 
directly,
+   * since overriding {@link ObjectInputStream#resolveClass} ensures that 
unauthorized classes
+   * are rejected before their bytecode is loaded or instantiated.
+   *
+   * @param modelClass The expected {@link BaseModel} subclass.
+   * @param in The {@link InputStream} to read from. Must not be {@code null}.
+   * @param <T> The type of the expected model.
+   * @return A valid {@link BaseModel} instance of type {@code T}.
+   *
+   * @throws IOException Thrown if IO errors occurred or an unauthorized class 
was encountered.
+   * @throws ClassNotFoundException Thrown if required classes are not found.
+   */
+
+  public static <T extends BaseModel> T deserialize(Class<T> modelClass, 
InputStream in)
+      throws IOException, ClassNotFoundException {
+    try (ObjectInputStream ois = new ObjectInputStream(in) {
+      @Override
+      protected Class<?> resolveClass(ObjectStreamClass desc) throws 
IOException, ClassNotFoundException {
+        String name = desc.getName();
+        boolean isAllowed = name.startsWith("opennlp.tools.")
+            || "java.util.HashMap".equals(name)
+            || "java.lang.String".equals(name);
+        if (!isAllowed) {
+          throw new InvalidClassException("Unauthorized deserialization 
attempt for class: " + name);
+        }
+        return super.resolveClass(desc);
+      }
+    }) {
+      return modelClass.cast(ois.readObject());
+    }
+  }
+
   // These methods are required to serialize/deserialize the model because
   // many of the included objects in this model are not Serializable.
   // An alternative to this solution is to make all included objects

Reply via email to