Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package jackson-databind for 
openSUSE:Factory checked in at 2026-07-15 16:56:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/jackson-databind (Old)
 and      /work/SRC/openSUSE:Factory/.jackson-databind.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "jackson-databind"

Wed Jul 15 16:56:19 2026 rev:21 rq:1365955 version:2.18.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/jackson-databind/jackson-databind.changes        
2026-06-27 18:09:48.295500083 +0200
+++ 
/work/SRC/openSUSE:Factory/.jackson-databind.new.1991/jackson-databind.changes  
    2026-07-15 17:12:20.569053071 +0200
@@ -1,0 +2,17 @@
+Wed Jul 15 10:52:47 UTC 2026 - Fridrich Strba <[email protected]>
+
+- Update to 2.18.8
+  * Changes
+    + #5962: Case-insensitive deserialization may use wrong
+      '@JsonIgnoreProperties' (bsc#1268902, CVE-2026-54515)
+    + #6054: Honor '@JsonView' for external-type-id
+      ('EXTERNAL_PROPERTY') properties [GHSA-mhm7-754m-9p8w]
+    + #6058: Do not allow DNS resolution when deserializing
+      'InetAddress'
+    + #6060: '@JsonView' by-passed for '@JsonUnwrapped'
+      Field/Setter properties (bsc#1271440, CVE-2026-59889)
+- Removed patch
+  * jackson-databind-CVE-2026-54515.patch
+    + integrated in this version
+
+-------------------------------------------------------------------
@@ -13 +30 @@
-      'PropertyNamingStrategy'
+      'PropertyNamingStrategy' (bsc#1271435, CVE-2026-59888)
@@ -57 +74,2 @@
-    + #4787: Wrong 'String.format()' in 'StdDelegatingDeserializer'
+    + #4787: Wrong 'String.format()' in 'StdDelegatingDeserializer'  * 
jackson-databind-CVE-2026-54515.patch
+

Old:
----
  jackson-databind-2.18.8.tar.gz
  jackson-databind-CVE-2026-54515.patch

New:
----
  jackson-databind-2.18.9.tar.gz

----------(Old B)----------
  Old:- Removed patch
  * jackson-databind-CVE-2026-54515.patch
    + integrated in this version
----------(Old E)----------

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

Other differences:
------------------
++++++ jackson-databind.spec ++++++
--- /var/tmp/diff_new_pack.HFgb1e/_old  2026-07-15 17:12:21.129072348 +0200
+++ /var/tmp/diff_new_pack.HFgb1e/_new  2026-07-15 17:12:21.129072348 +0200
@@ -20,14 +20,13 @@
 # binaries are java 8 compatible
 %define __requires_exclude java-headless
 Name:           jackson-databind
-Version:        2.18.8
+Version:        2.18.9
 Release:        0
 Summary:        General data-binding package for Jackson (2.x)
 License:        Apache-2.0
 URL:            https://github.com/FasterXML/jackson-databind/
 Source0:        
https://github.com/FasterXML/jackson-databind/archive/%{name}-%{version}.tar.gz
 Source1:        %{name}-build.xml
-Patch0:         %{name}-CVE-2026-54515.patch
 BuildRequires:  ant
 BuildRequires:  fdupes
 BuildRequires:  jackson-annotations
@@ -51,7 +50,6 @@
 %prep
 %setup -q -n %{name}-%{name}-%{version}
 cp %{SOURCE1} build.xml
-%patch -P 0 -p1
 mkdir -p lib
 
 cp -p src/main/resources/META-INF/NOTICE .

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.HFgb1e/_old  2026-07-15 17:12:21.161073449 +0200
+++ /var/tmp/diff_new_pack.HFgb1e/_new  2026-07-15 17:12:21.165073587 +0200
@@ -1,6 +1,6 @@
-mtime: 1782492145
-commit: 44f91217e3255f9588452ecc3f12d95b60d8920ab601e4947d5b83e8b62a1d00
+mtime: 1784114255
+commit: ccc864724b1ee59fbaf8e3346c1f8fa57fb0d8b7fea1f9b073905a98567985fa
 url: https://src.opensuse.org/java-packages/jackson-databind
-revision: 44f91217e3255f9588452ecc3f12d95b60d8920ab601e4947d5b83e8b62a1d00
+revision: ccc864724b1ee59fbaf8e3346c1f8fa57fb0d8b7fea1f9b073905a98567985fa
 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-15 13:17:35.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ jackson-databind-2.18.8.tar.gz -> jackson-databind-2.18.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jackson-databind-jackson-databind-2.18.8/pom.xml 
new/jackson-databind-jackson-databind-2.18.9/pom.xml
--- old/jackson-databind-jackson-databind-2.18.8/pom.xml        2026-05-29 
02:39:50.000000000 +0200
+++ new/jackson-databind-jackson-databind-2.18.9/pom.xml        2026-07-08 
02:18:37.000000000 +0200
@@ -9,11 +9,11 @@
   <parent>
     <groupId>com.fasterxml.jackson</groupId>
     <artifactId>jackson-base</artifactId>
-    <version>2.18.8</version>
+    <version>2.18.9</version>
   </parent>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
-  <version>2.18.8</version>
+  <version>2.18.9</version>
   <name>jackson-databind</name>
   <packaging>jar</packaging>
   <description>General data-binding functionality for Jackson: works on core 
streaming API</description>
@@ -31,7 +31,7 @@
     
<connection>scm:git:[email protected]:FasterXML/jackson-databind.git</connection>
     
<developerConnection>scm:git:[email protected]:FasterXML/jackson-databind.git</developerConnection>
     <url>https://github.com/FasterXML/jackson-databind</url>
-    <tag>jackson-databind-2.18.8</tag>
+    <tag>jackson-databind-2.18.9</tag>
   </scm>
 
   <properties>
@@ -68,7 +68,7 @@
     
<packageVersion.package>com.fasterxml.jackson.databind.cfg</packageVersion.package>
 
     <!-- for Reproducible Builds -->
-    
<project.build.outputTimestamp>2026-05-29T00:39:06Z</project.build.outputTimestamp>
+    
<project.build.outputTimestamp>2026-07-08T00:18:17Z</project.build.outputTimestamp>
   </properties>
 
   <dependencyManagement>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/release-notes/CREDITS-2.x 
new/jackson-databind-jackson-databind-2.18.9/release-notes/CREDITS-2.x
--- old/jackson-databind-jackson-databind-2.18.8/release-notes/CREDITS-2.x      
2026-05-29 02:39:50.000000000 +0200
+++ new/jackson-databind-jackson-databind-2.18.9/release-notes/CREDITS-2.x      
2026-07-08 02:18:37.000000000 +0200
@@ -1895,7 +1895,7 @@
   (2.18.4)
 
 Omkhar Arasaratnam (@omkhar)
- * Reported #5950: Improve `UUIDeserializer` error handling
+ * Reported #5950: Improve `UUIDDeserializer` error handling
   (2.18.8)
  * Reported #5951: Improve `InetSocketAddress` deserialization
   (2.18.8)
@@ -1910,4 +1910,7 @@
    should validate element type
   (2.18.8)
  * Reported #5988: `PolymorphicTypeValidator` needs to validate generic type 
parameters too
- (2.18.8)
+  (2.18.8)
+ * Contributed fix for #5962: Case-insensitive deserialization may use
+   wrong `@JsonIgnoreProperties`
+  (2.18.9)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/release-notes/VERSION-2.x 
new/jackson-databind-jackson-databind-2.18.9/release-notes/VERSION-2.x
--- old/jackson-databind-jackson-databind-2.18.8/release-notes/VERSION-2.x      
2026-05-29 02:39:50.000000000 +0200
+++ new/jackson-databind-jackson-databind-2.18.9/release-notes/VERSION-2.x      
2026-07-08 02:18:37.000000000 +0200
@@ -4,23 +4,38 @@
 === Releases === 
 ------------------------------------------------------------------------
 
+2.18.9 (07-Jul-2026)
+
+#5962: Case-insensitive deserialization may use wrong `@JsonIgnoreProperties`
+ [CVE-2026-54515]
+ (fixed by Omkhar A)
+#6054: Honor `@JsonView` for external-type-id (`EXTERNAL_PROPERTY`)
+  properties [GHSA-mhm7-754m-9p8w]
+ (reported by @Sharlong-Wen)
+#6058: Do not allow DNS resolution when deserializing `InetAddress`
+ (reported by @thientd)
+ (fix by @pjfanning)
+#6060: `@JsonView` by-passed for `@JsonUnwrapped` Field/Setter properties 
[CVE-2026-59889]
+
 2.18.8 (28-May-2026)
 
-#5950: Improve `UUIDeserializer` error handling
+#5950: Improve `UUIDDeserializer` error handling
  (reported by Omkhar A)
-#5951: Improve `InetSocketAddress` deserialization
+#5951: Improve `InetSocketAddress` deserialization [CVE-2026-54514]
  (reported by Omkhar A)
 #5969: `@JsonView` by-passed for some "setterless" creator properties
+ [CVE-2026-54517]
  (fixed by Omkhar A)
-#5971: `@JsonView` by-passed for unwrapped creator parameters
+#5971: `@JsonView` by-passed for unwrapped creator parameters [CVE-2026-54518]
  (fixed by Omkhar A)
 #5974: `@JsonIgnore` on Record property ignored with `PropertyNamingStrategy`
  (reported by Omkhar A)
 #5981: `BasicPolymorphicTypeValidator` setting `allowIfSubTypeIsArray()`
-  should validate element type
+  should validate element type [CVE-2026-54513]
  (reported by Omkhar A)
  (fix by @cowtowncoder, w/ Claude code)
 #5988: `PolymorphicTypeValidator` needs to validate generic type parameters too
+  [CVE-2026-54512]
  (reported by Omkhar A)
  (fix by @cowtowncoder, w/ Claude code)
 #5993: `UPPER_SNAKE_CASE` / `LOWER_CASE` `NamingStrategyImpls` fold case
@@ -638,7 +653,7 @@
   JSON `null` values on reading
 #3443: Do not strip generic type from `Class<C>` when resolving `JavaType`
  (contributed by Jan J)
-#3447: Deeply nested JsonNode throws StackOverflowError for toString()
+#3447: Deeply nested JsonNode throws StackOverflowError for toString() 
[CVE-2026-50193]
  (reported by Deniz H)
 #3475: Support use of fast double parse
  (contributed by @pjfanning)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
   2026-05-29 02:39:50.000000000 +0200
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
   2026-07-08 02:18:37.000000000 +0200
@@ -894,7 +894,10 @@
             // 16-May-2016, tatu: How about per-property case-insensitivity?
             Boolean B = 
format.getFeature(JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
             if (B != null) {
-                BeanPropertyMap propsOrig = _beanProperties;
+                // [databind#5962]: must rebuild from the (possibly filtered) 
contextual
+                // BeanPropertyMap so that per-property @JsonIgnoreProperties 
exclusions
+                // applied by _handleByNameInclusion() above are preserved.
+                BeanPropertyMap propsOrig = contextual._beanProperties;
                 BeanPropertyMap props = 
propsOrig.withCaseInsensitivity(B.booleanValue());
                 if (props != propsOrig) {
                     contextual = contextual.withBeanProperties(props);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/impl/ExternalTypeHandler.java
 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/impl/ExternalTypeHandler.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/impl/ExternalTypeHandler.java
       2026-05-29 02:39:50.000000000 +0200
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/impl/ExternalTypeHandler.java
       2026-07-08 02:18:37.000000000 +0200
@@ -201,9 +201,17 @@
     public Object complete(JsonParser p, DeserializationContext ctxt, Object 
bean)
         throws IOException
     {
+        final Class<?> activeView = ctxt.getActiveView();
         for (int i = 0, len = _properties.length; i < len; ++i) {
-            String typeId = _typeIds[i];
             final ExtTypedProperty extProp = _properties[i];
+            // 26-Jun-2026, tatu: Must honor `@JsonView` for external-type-id
+            //   properties too (see JsonViewExternalTypeIdBypassTest); 
otherwise
+            //   value for property not visible in active view would still get 
bound,
+            //   bypassing view-based filtering.
+            if ((activeView != null) && 
!extProp.getProperty().visibleInView(activeView)) {
+                continue;
+            }
+            String typeId = _typeIds[i];
             if (typeId == null) {
                 TokenBuffer tokens = _tokens[i];
                 // let's allow missing both type and property (may already 
have been set, too)
@@ -264,53 +272,71 @@
         // first things first: deserialize all data buffered:
         final int len = _properties.length;
         Object[] values = new Object[len];
+        final Class<?> activeView = ctxt.getActiveView();
         for (int i = 0; i < len; ++i) {
-            String typeId = _typeIds[i];
             final ExtTypedProperty extProp = _properties[i];
-            if (typeId == null) {
-                // let's allow missing both type and property (may already 
have been set, too)
-                TokenBuffer tb = _tokens[i];
-                if ((tb == null)
-                        // 19-Feb-2021, tatu: Both missing value and explicit 
`null`
-                        //    should be accepted...
-                        || (tb.firstToken() == JsonToken.VALUE_NULL)
-                    ) {
-                    continue;
-                }
-                // but not just one
-                // 26-Oct-2012, tatu: As per [databind#94], must allow use of 
'defaultImpl'
-                if (!extProp.hasDefaultType()) {
-                    ctxt.reportPropertyInputMismatch(_beanType, 
extProp.getProperty().getName(),
-                            "Missing external type id property '%s'",
-                            extProp.getTypePropertyName());
-                } else {
-                    typeId = extProp.getDefaultTypeId();
+            final SettableBeanProperty prop = extProp.getProperty();
+            String typeId = _typeIds[i];
+
+            // 26-Jun-2026, tatu: Must honor `@JsonView` for external-type-id
+            //   properties too (see JsonViewExternalTypeIdBypassTest): leave 
the
+            //   value of a property not visible in the active view unbound 
(null),
+            //   so it does not bypass view-based filtering. NOTE: the 
external type
+            //   id itself may be a separate, still-visible creator property, 
so that
+            //   is still assigned below ([databind#999]).
+            final boolean viewHidden = (activeView != null) && 
!prop.visibleInView(activeView);
+
+            if (!viewHidden) {
+                if (typeId == null) {
+                    // let's allow missing both type and property (may already 
have been set, too)
+                    TokenBuffer tb = _tokens[i];
+                    if ((tb == null)
+                            // 19-Feb-2021, tatu: Both missing value and 
explicit `null`
+                            //    should be accepted...
+                            || (tb.firstToken() == JsonToken.VALUE_NULL)
+                        ) {
+                        continue;
+                    }
+                    // but not just one
+                    // 26-Oct-2012, tatu: As per [databind#94], must allow use 
of 'defaultImpl'
+                    if (!extProp.hasDefaultType()) {
+                        ctxt.reportPropertyInputMismatch(_beanType, 
prop.getName(),
+                                "Missing external type id property '%s'",
+                                extProp.getTypePropertyName());
+                    } else {
+                        typeId = extProp.getDefaultTypeId();
+                    }
                 }
-            }
 
-            if (_tokens[i] != null) {
-                values[i] = _deserialize(p, ctxt, i, typeId);
-            } else {
-                if 
(ctxt.isEnabled(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY))
 {
-                    SettableBeanProperty prop = extProp.getProperty();
-                    ctxt.reportPropertyInputMismatch(_beanType, prop.getName(),
-                            "Missing property '%s' for external type id '%s'",
-                            prop.getName(), 
_properties[i].getTypePropertyName());
+                if (_tokens[i] != null) {
+                    values[i] = _deserialize(p, ctxt, i, typeId);
+                } else {
+                    if 
(ctxt.isEnabled(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY))
 {
+                        ctxt.reportPropertyInputMismatch(_beanType, 
prop.getName(),
+                                "Missing property '%s' for external type id 
'%s'",
+                                prop.getName(), extProp.getTypePropertyName());
+                    }
+                    // 03-Aug-2022, tatu: [databind#3533] to handle absent 
value matching
+                    //    present type id
+                    values[i] = _deserializeMissingToken(p, ctxt, i, typeId);
                 }
-                // 03-Aug-2022, tatu: [databind#3533] to handle absent value 
matching
-                //    present type id
-                values[i] = _deserializeMissingToken(p, ctxt, i, typeId);
             }
 
-            final SettableBeanProperty prop = extProp.getProperty();
             // also: if it's creator prop, fill in
             if (prop.getCreatorIndex() >= 0) {
-                buffer.assignParameter(prop, values[i]);
+                // ...but skip binding the value itself if hidden by the 
active view
+                if (!viewHidden) {
+                    buffer.assignParameter(prop, values[i]);
+                }
 
                 // [databind#999] And maybe there's creator property for type 
id too?
+                //   Assign it even when the value is view-hidden, provided we 
have a
+                //   type id and the type-id property is itself visible in the 
view.
                 SettableBeanProperty typeProp = extProp.getTypeProperty();
                 // for now, should only be needed for creator properties, too
-                if ((typeProp != null) && (typeProp.getCreatorIndex() >= 0)) {
+                if ((typeProp != null) && (typeProp.getCreatorIndex() >= 0)
+                        && (typeId != null)
+                        && ((activeView == null) || 
typeProp.visibleInView(activeView))) {
                     // 31-May-2018, tatu: [databind#1328] if id is NOT plain 
`String`, need to
                     //    apply deserializer... fun fun.
                     final Object v;
@@ -329,7 +355,12 @@
         Object bean = creator.build(ctxt, buffer);
         // third: assign non-creator properties
         for (int i = 0; i < len; ++i) {
-            SettableBeanProperty prop = _properties[i].getProperty();
+            final ExtTypedProperty extProp = _properties[i];
+            // 26-Jun-2026, tatu: also honor `@JsonView` here (see above)
+            final SettableBeanProperty prop = extProp.getProperty();
+            if ((activeView != null) && !prop.visibleInView(activeView)) {
+                continue;
+            }
             if (prop.getCreatorIndex() < 0) {
                 prop.set(bean, values[i]);
             }
@@ -379,6 +410,17 @@
     protected final void _deserializeAndSet(JsonParser p, 
DeserializationContext ctxt,
             Object bean, int index, String typeId) throws IOException
     {
+        // 26-Jun-2026, tatu: Must honor `@JsonView` here too (see
+        //   JsonViewExternalTypeIdBypassTest): for default-constructor beans 
the value
+        //   may be bound eagerly via this method (when the type id precedes 
the value),
+        //   so a property not visible in the active view must be skipped here 
as well.
+        //   The value is read from the buffered token (`_tokens[index]`), and 
the main
+        //   parser has already advanced past it, so we simply discard it (do 
not set).
+        final Class<?> activeView = ctxt.getActiveView();
+        if ((activeView != null) && 
!_properties[index].getProperty().visibleInView(activeView)) {
+            return;
+        }
+
         // 11-Nov-2020, tatu: Should never get `null` passed this far,
         if (typeId == null) {
             ctxt.reportInputMismatch(_beanType, "Internal error in external 
Type Id handling: `null` type id passed");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/impl/UnwrappedPropertyHandler.java
 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/impl/UnwrappedPropertyHandler.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/impl/UnwrappedPropertyHandler.java
  2026-05-29 02:39:50.000000000 +0200
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/impl/UnwrappedPropertyHandler.java
  2026-07-08 02:18:37.000000000 +0200
@@ -56,8 +56,14 @@
             Object bean, TokenBuffer buffered)
         throws IOException
     {
+        // [databind#6060]: honor active @JsonView -- skip Field/Setter 
properties not
+        // visible in the active view rather than populating them from 
buffered input.
+        final Class<?> activeView = ctxt.getActiveView();
         for (int i = 0, len = _properties.size(); i < len; ++i) {
             SettableBeanProperty prop = _properties.get(i);
+            if ((activeView != null) && !prop.visibleInView(activeView)) {
+                continue;
+            }
             JsonParser p = 
buffered.asParser(originalParser.streamReadConstraints());
             p.nextToken();
             prop.deserializeAndSet(p, ctxt, bean);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java
 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java
     2026-05-29 02:39:50.000000000 +0200
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java
     2026-07-08 02:18:37.000000000 +0200
@@ -351,6 +351,11 @@
             case STD_TIME_ZONE:
                 return TimeZone.getTimeZone(value);
             case STD_INET_ADDRESS:
+                // 05-Jul-2026, tatu: [databind#6058] Prevent DNS lookup: only 
accept valid IP address literals
+                if (!InetAddressValidator.isInetAddress(value)) {
+                    return ctxt.handleWeirdStringValue(_valueClass, value,
+                            "Not a valid IP address string literal");
+                }
                 return InetAddress.getByName(value);
             case STD_INET_SOCKET_ADDRESS:
                 if (value.startsWith("[")) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/std/InetAddressValidator.java
 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/std/InetAddressValidator.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/main/java/com/fasterxml/jackson/databind/deser/std/InetAddressValidator.java
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/main/java/com/fasterxml/jackson/databind/deser/std/InetAddressValidator.java
       2026-07-08 02:18:37.000000000 +0200
@@ -0,0 +1,218 @@
+package com.fasterxml.jackson.databind.deser.std;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Helper that validates whether a string is a valid IP address literal (IPv4 
or IPv6)
+ * without performing any DNS lookup.
+ *<p>
+ * Logic is adapted from Google Guava's {@code InetAddresses.isInetAddress()} 
under the
+ * Apache License 2.0:
+ * 
https://github.com/google/guava/blob/master/guava/src/com/google/common/net/InetAddresses.java
+ *
+ * @since 2.18.9
+ */
+class InetAddressValidator
+{
+    private static final int IPV4_PART_COUNT = 4;
+    private static final int IPV6_PART_COUNT = 8;
+
+    private InetAddressValidator() { }
+
+    /**
+     * Returns {@code true} if the supplied string is a valid IP string literal
+     * (IPv4 or IPv6), {@code false} otherwise.
+     * This method never causes a DNS lookup.
+     */
+    static boolean isInetAddress(String ipString) {
+        return _ipStringToBytes(ipString) != null;
+    }
+
+    // Returns null if unable to parse into a byte array.
+    private static byte[] _ipStringToBytes(String ipString) {
+        boolean hasColon = false;
+        boolean hasDot = false;
+        int percentIndex = -1;
+        for (int i = 0; i < ipString.length(); i++) {
+            char c = ipString.charAt(i);
+            if (c == '.') {
+                hasDot = true;
+            } else if (c == ':') {
+                if (hasDot) {
+                    return null; // Colons must not appear after dots.
+                }
+                hasColon = true;
+            } else if (c == '%') {
+                percentIndex = i;
+                break; // Scope ID; stop scanning
+            } else if (Character.digit(c, 16) == -1) {
+                return null; // Everything else must be a decimal or hex digit.
+            }
+        }
+
+        if (hasColon) {
+            if (hasDot) {
+                ipString = _convertDottedQuadToHex(ipString);
+                if (ipString == null) {
+                    return null;
+                }
+            }
+            if (percentIndex != -1) {
+                ipString = ipString.substring(0, percentIndex);
+            }
+            return _textToNumericFormatV6(ipString);
+        } else if (hasDot) {
+            if (percentIndex != -1) {
+                return null; // Scope IDs not supported for IPv4
+            }
+            return _textToNumericFormatV4(ipString);
+        }
+        return null;
+    }
+
+    private static byte[] _textToNumericFormatV4(String ipString) {
+        int dotCount = 0;
+        for (int i = 0; i < ipString.length(); i++) {
+            if (ipString.charAt(i) == '.') {
+                dotCount++;
+            }
+        }
+        if (dotCount + 1 != IPV4_PART_COUNT) {
+            return null; // Wrong number of parts
+        }
+
+        byte[] bytes = new byte[IPV4_PART_COUNT];
+        int start = 0;
+        for (int i = 0; i < IPV4_PART_COUNT; i++) {
+            int end = ipString.indexOf('.', start);
+            if (end == -1) {
+                end = ipString.length();
+            }
+            try {
+                bytes[i] = _parseOctet(ipString, start, end);
+            } catch (NumberFormatException ex) {
+                return null;
+            }
+            start = end + 1;
+        }
+        return bytes;
+    }
+
+    private static byte[] _textToNumericFormatV6(String ipString) {
+        int delimiterCount = 0;
+        for (int i = 0; i < ipString.length(); i++) {
+            if (ipString.charAt(i) == ':') {
+                delimiterCount++;
+            }
+        }
+        if (delimiterCount < 2 || delimiterCount > IPV6_PART_COUNT) {
+            return null;
+        }
+        int partsSkipped = IPV6_PART_COUNT - (delimiterCount + 1); // 
estimate; may be modified
+        boolean hasSkip = false;
+        for (int i = 0; i < ipString.length() - 1; i++) {
+            if (ipString.charAt(i) == ':' && ipString.charAt(i + 1) == ':') {
+                if (hasSkip) {
+                    return null; // Can't have more than one ::
+                }
+                hasSkip = true;
+                partsSkipped++; // :: means we skipped an extra part
+                if (i == 0) {
+                    partsSkipped++; // Begins with ::
+                }
+                if (i == ipString.length() - 2) {
+                    partsSkipped++; // Ends with ::
+                }
+            }
+        }
+        if (ipString.charAt(0) == ':' && ipString.charAt(1) != ':') {
+            return null; // ^: requires ^::
+        }
+        if (ipString.charAt(ipString.length() - 1) == ':'
+                && ipString.charAt(ipString.length() - 2) != ':') {
+            return null; // :$ requires ::$
+        }
+        if (hasSkip && partsSkipped <= 0) {
+            return null; // :: must expand to at least one '0'
+        }
+        if (!hasSkip && delimiterCount + 1 != IPV6_PART_COUNT) {
+            return null; // Incorrect number of parts
+        }
+
+        ByteBuffer rawBytes = ByteBuffer.allocate(2 * IPV6_PART_COUNT);
+        try {
+            int start = 0;
+            if (ipString.charAt(0) == ':') {
+                start = 1;
+            }
+            while (start < ipString.length()) {
+                int end = ipString.indexOf(':', start);
+                if (end == -1) {
+                    end = ipString.length();
+                }
+                if (ipString.charAt(start) == ':') {
+                    // expand zeroes
+                    for (int i = 0; i < partsSkipped; i++) {
+                        rawBytes.putShort((short) 0);
+                    }
+                } else {
+                    rawBytes.putShort(_parseHextet(ipString, start, end));
+                }
+                start = end + 1;
+            }
+        } catch (NumberFormatException ex) {
+            return null;
+        }
+        return rawBytes.array();
+    }
+
+    private static String _convertDottedQuadToHex(String ipString) {
+        int lastColon = ipString.lastIndexOf(':');
+        String initialPart = ipString.substring(0, lastColon + 1);
+        String dottedQuad = ipString.substring(lastColon + 1);
+        byte[] quad = _textToNumericFormatV4(dottedQuad);
+        if (quad == null) {
+            return null;
+        }
+        String penultimate = Integer.toHexString(((quad[0] & 0xff) << 8) | 
(quad[1] & 0xff));
+        String ultimate = Integer.toHexString(((quad[2] & 0xff) << 8) | 
(quad[3] & 0xff));
+        return initialPart + penultimate + ":" + ultimate;
+    }
+
+    private static byte _parseOctet(String ipString, int start, int end) {
+        int length = end - start;
+        if (length <= 0 || length > 3) {
+            throw new NumberFormatException();
+        }
+        // Disallow leading zeroes (ambiguous: decimal vs octal)
+        if (length > 1 && ipString.charAt(start) == '0') {
+            throw new NumberFormatException();
+        }
+        int octet = 0;
+        for (int i = start; i < end; i++) {
+            octet *= 10;
+            int digit = Character.digit(ipString.charAt(i), 10);
+            if (digit < 0) {
+                throw new NumberFormatException();
+            }
+            octet += digit;
+        }
+        if (octet > 255) {
+            throw new NumberFormatException();
+        }
+        return (byte) octet;
+    }
+
+    private static short _parseHextet(String ipString, int start, int end) {
+        int length = end - start;
+        if (length <= 0 || length > 4) {
+            throw new NumberFormatException();
+        }
+        int hextet = 0;
+        for (int i = start; i < end; i++) {
+            hextet = hextet << 4;
+            hextet |= Character.digit(ipString.charAt(i), 16);
+        }
+        return (short) hextet;
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/deser/filter/IgnorePropertiesCaseInsensitive5962Test.java
 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/deser/filter/IgnorePropertiesCaseInsensitive5962Test.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/deser/filter/IgnorePropertiesCaseInsensitive5962Test.java
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/deser/filter/IgnorePropertiesCaseInsensitive5962Test.java
 2026-07-08 02:18:37.000000000 +0200
@@ -0,0 +1,94 @@
+package com.fasterxml.jackson.databind.deser.filter;
+
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * [databind#5962]: Case-insensitive BeanPropertyMap rebuild undoes 
per-property
+ * {@code @JsonIgnoreProperties}.
+ *
+ * {@code BeanDeserializerBase.createContextual()} calls {@code 
_handleByNameInclusion()}
+ * to filter properties according to per-property {@code 
@JsonIgnoreProperties}, producing
+ * a contextual deserializer with the restricted {@code BeanPropertyMap}. 
However, the
+ * subsequent case-insensitivity block read {@code _beanProperties} (the 
*original*
+ * unfiltered map from {@code this}) rather than {@code 
contextual._beanProperties} (the
+ * filtered map). {@code withCaseInsensitivity()} then rebuilt the map from 
the unfiltered
+ * source, and {@code contextual.withBeanProperties(props)} overwrote the 
filtered map with
+ * the unfiltered one — any properties removed by {@code 
_handleByNameInclusion} were
+ * restored.
+ *
+ * Patch: source the case-insensitive rebuild from {@code 
contextual._beanProperties}.
+ */
+public class IgnorePropertiesCaseInsensitive5962Test extends DatabindTestUtil
+{
+    static class AdminDto {
+        public String adminKey = "DEFAULT";
+        public String username;
+    }
+
+    // Container that ignores "adminKey" on the AdminDto field AND enables 
case-insensitive matching
+    static class Container {
+        @JsonIgnoreProperties("adminKey")
+        @JsonFormat(with = 
JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
+        public AdminDto admin;
+    }
+
+    // Baseline container: only @JsonIgnoreProperties, no case-insensitive 
format override
+    static class BaselineContainer {
+        @JsonIgnoreProperties("adminKey")
+        public AdminDto admin;
+    }
+
+    /**
+     * NEGATIVE CONTROL: without the @JsonFormat case-insensitive override, 
@JsonIgnoreProperties
+     * correctly suppresses adminKey on the nested AdminDto field.
+     */
+    @Test
+    public void test5962_negativeControl_withoutCaseInsensitivity() throws 
Exception {
+        ObjectMapper mapper = jsonMapperBuilder().build();
+        String json = 
"{\"admin\":{\"adminKey\":\"HACKED\",\"username\":\"alice\"}}";
+        BaselineContainer result = mapper.readValue(json, 
BaselineContainer.class);
+        // Without case-insensitive format, @JsonIgnoreProperties blocks 
adminKey
+        assertNotEquals("HACKED", result.admin.adminKey,
+                "@JsonIgnoreProperties alone (no case-insensitive format) 
should block adminKey");
+        assertEquals("alice", result.admin.username);
+    }
+
+    /**
+     * EXPLOIT PATH: the case-insensitive BeanPropertyMap rebuild (triggered by
+     * @JsonFormat ACCEPT_CASE_INSENSITIVE_PROPERTIES) restores the unfiltered 
original
+     * _beanProperties, undoing the @JsonIgnoreProperties("adminKey") 
exclusion.
+     * Case-insensitive matching then routes "adminKey" (or "ADMINKEY") to the 
setter.
+     *
+     * Security assertion: adminKey must NOT be settable via JSON when the 
enclosing
+     * container declares @JsonIgnoreProperties("adminKey") on the field.
+     */
+    @Test
+    public void test5962_caseInsensitiveRebuildRestoresIgnoredProperty() 
throws Exception {
+        ObjectMapper mapper = jsonMapperBuilder()
+                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                .build();
+
+        // Exact case — should be blocked by @JsonIgnoreProperties
+        String json = 
"{\"admin\":{\"adminKey\":\"HACKED\",\"username\":\"alice\"}}";
+        Container result = mapper.readValue(json, Container.class);
+        assertNotEquals("HACKED", result.admin.adminKey,
+                "[databind#5962]: case-insensitive BeanPropertyMap rebuild 
restored 'adminKey' " +
+                        "after it was removed by @JsonIgnoreProperties. The 
property was set to 'HACKED'.");
+        assertEquals("alice", result.admin.username);
+
+        // Mixed case — exploits the case-insensitive rebuild more directly
+        String jsonMixed = 
"{\"admin\":{\"AdminKey\":\"HACKED2\",\"username\":\"bob\"}}";
+        Container result2 = mapper.readValue(jsonMixed, Container.class);
+        assertNotEquals("HACKED2", result2.admin.adminKey,
+                "[databind#5962]: 'AdminKey' (mixed case) matched 'adminKey' 
via case-insensitive " +
+                        "lookup that was rebuilt from the unfiltered property 
map.");
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKStringLikeTypeDeserTest.java
 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKStringLikeTypeDeserTest.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKStringLikeTypeDeserTest.java
 2026-05-29 02:39:50.000000000 +0200
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKStringLikeTypeDeserTest.java
 2026-07-08 02:18:37.000000000 +0200
@@ -171,13 +171,39 @@
     @Test
     public void testInetAddress() throws IOException
     {
+        // Valid IPv4 address
         InetAddress address = MAPPER.readValue(q("127.0.0.1"), 
InetAddress.class);
         assertEquals("127.0.0.1", address.getHostAddress());
 
-        // should we try resolving host names? That requires connectivity...
-        final String HOST = "google.com";
-        address = MAPPER.readValue(q(HOST), InetAddress.class);
-        assertEquals(HOST, address.getHostName());
+        // Valid IPv6 address
+        InetAddress ip6 = MAPPER.readValue(
+                q("2001:db8:85a3:8d3:1319:8a2e:370:7348"), InetAddress.class);
+        assertEquals("2001:db8:85a3:8d3:1319:8a2e:370:7348", 
ip6.getHostAddress());
+
+        // IPv6 loopback
+        InetAddress loopback6 = MAPPER.readValue(q("::1"), InetAddress.class);
+        assertEquals("0:0:0:0:0:0:0:1", loopback6.getHostAddress());
+    }
+
+    @Test
+    public void testInetAddressNoDNSLookup() throws Exception
+    {
+        // [databind#6058]: should NOT perform DNS lookup — only IP address 
literals accepted
+        expectInvalidInetAddress("localhost");
+        expectInvalidInetAddress("google.com");
+        // starts off looking like an IP address (edge case)
+        expectInvalidInetAddress("1.2.3.4.example.com");
+        // punycode
+        expectInvalidInetAddress("xn--bcher-kva.example.com");
+    }
+
+    private void expectInvalidInetAddress(String address) throws Exception {
+        try {
+            MAPPER.readValue(q(address), InetAddress.class);
+            fail("Should not pass");
+        } catch (InvalidFormatException e) {
+            verifyException(e, "Not a valid IP address string literal");
+        }
     }
 
     @Test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/ser/jdk/JDKTypeSerializationTest.java
 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/ser/jdk/JDKTypeSerializationTest.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/ser/jdk/JDKTypeSerializationTest.java
     2026-05-29 02:39:50.000000000 +0200
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/ser/jdk/JDKTypeSerializationTest.java
     2026-07-08 02:18:37.000000000 +0200
@@ -104,20 +104,27 @@
     }
 
     @Test
-    public void testInetAddress() throws IOException
+    public void testInetAddress() throws Exception
     {
-        assertEquals(q("127.0.0.1"), 
MAPPER.writeValueAsString(InetAddress.getByName("127.0.0.1")));
-        InetAddress input = InetAddress.getByName("google.com");
-        assertEquals(q("google.com"), MAPPER.writeValueAsString(input));
+        // Default shape: textual form (host part of InetAddress.toString())
+        InetAddress input = InetAddress.getByName("127.0.0.1");
+        assertEquals(q("127.0.0.1"), MAPPER.writeValueAsString(input));
 
+        // Address carrying a host name (constructed WITHOUT a DNS lookup, via
+        // getByAddress()) still serializes the name in the default shape
+        InetAddress named = InetAddress.getByAddress("myhost.example.com",
+                new byte[] { 1, 2, 3, 4 });
+        assertEquals(q("myhost.example.com"), 
MAPPER.writeValueAsString(named));
+
+        // NUMBER shape: numeric host address regardless of host name
         ObjectMapper mapper = newJsonMapper();
         mapper.configOverride(InetAddress.class)
             .setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.NUMBER));
-        String json = mapper.writeValueAsString(input);
-        assertEquals(q(input.getHostAddress()), json);
+        assertEquals(q(named.getHostAddress()), 
mapper.writeValueAsString(named));
 
-        assertEquals(String.format("{\"value\":\"%s\"}", 
input.getHostAddress()),
-                mapper.writeValueAsString(new InetAddressBean(input)));
+        // ... also as a bean property
+        assertEquals(String.format("{\"value\":\"%s\"}", 
named.getHostAddress()),
+                mapper.writeValueAsString(new InetAddressBean(named)));
     }
 
     @Test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/views/JsonViewExternalTypeIdBypassTest.java
 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/views/JsonViewExternalTypeIdBypassTest.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/views/JsonViewExternalTypeIdBypassTest.java
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/views/JsonViewExternalTypeIdBypassTest.java
       2026-07-08 02:18:37.000000000 +0200
@@ -0,0 +1,341 @@
+package com.fasterxml.jackson.databind.views;
+
+import com.fasterxml.jackson.annotation.*;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+// Tests to verify that {@code @JsonView} is honored for polymorphic properties
+// that use an EXTERNAL_PROPERTY type id. A {@code @JsonView} never changes the
+// type id, so these tests check the two distinct things a view CAN do -- (a) 
hide
+// the whole polymorphic property (left null), or (b) hide a field of the 
resolved
+// subtype (subtype built, field left null) -- across the different ways such a
+// property gets bound:
+//
+//  (1) property-based (@JsonCreator) constructor, property hidden      -> null
+//  (2) field of the resolved subtype hidden (property-based creator)   -> 
field null
+//  (3) type id is ITSELF a creator param, only the value hidden        -> 
value null, type id kept
+//  (4) default-constructor bean (eager binding), property hidden       -> null
+//  (5) @JsonPOJOBuilder-based bean, property hidden                    -> null
+//  (6) reverse of (3): type id creator param hidden, value visible     -> 
value kept, type id null
+public class JsonViewExternalTypeIdBypassTest extends DatabindTestUtil
+{
+    static class PublicView { }
+    static class AdminView extends PublicView { }
+
+    static abstract class Asset {
+        public String name;
+    }
+
+    static class PublicAsset extends Asset { }
+
+    static class AdminAsset extends Asset {
+        public String secret;
+    }
+
+    // Subtype used by case (2): here the admin-only marker is on the field, 
not
+    // on the owning property.
+    static class FieldGatedAdminAsset extends Asset {
+        @JsonView(AdminView.class)
+        public String secret;
+    }
+
+    // Case (1): the entire polymorphic property is admin-only.
+    static class PropertyGatedContainer {
+        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
+                include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+                property = "kind")
+        @JsonSubTypes({
+                @JsonSubTypes.Type(value = PublicAsset.class, name = "pub"),
+                @JsonSubTypes.Type(value = AdminAsset.class, name = "admin")
+        })
+        @JsonView(AdminView.class)
+        public Asset asset;
+
+        public String label;
+
+        @JsonCreator
+        public PropertyGatedContainer(
+                @JsonProperty("label") String label,
+                @JsonProperty("asset") @JsonView(AdminView.class) Asset asset) 
{
+            this.label = label;
+            this.asset = asset;
+        }
+    }
+
+    // Case (2): the property is always visible, but the resolved subtype has 
an
+    // admin-only field.
+    static class FieldGatedContainer {
+        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
+                include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+                property = "kind")
+        @JsonSubTypes({
+                @JsonSubTypes.Type(value = PublicAsset.class, name = "pub"),
+                @JsonSubTypes.Type(value = FieldGatedAdminAsset.class, name = 
"admin")
+        })
+        public Asset asset;
+
+        public String label;
+
+        @JsonCreator
+        public FieldGatedContainer(
+                @JsonProperty("label") String label,
+                @JsonProperty("asset") Asset asset) {
+            this.label = label;
+            this.asset = asset;
+        }
+    }
+
+    // Case (3): like case (1), but the external type id "kind" is ITSELF a 
creator
+    // parameter ([databind#999]). The value "asset" is admin-only, but "kind" 
carries
+    // no view, so hiding the value must not also drop the (visible) type id 
property.
+    static class TypeIdCreatorContainer {
+        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
+                include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+                property = "kind",
+                visible = true)
+        @JsonSubTypes({
+                @JsonSubTypes.Type(value = PublicAsset.class, name = "pub"),
+                @JsonSubTypes.Type(value = AdminAsset.class, name = "admin")
+        })
+        @JsonView(AdminView.class)
+        public Asset asset;
+
+        public String label;
+        public String kind;
+
+        @JsonCreator
+        public TypeIdCreatorContainer(
+                @JsonProperty("label") String label,
+                @JsonProperty("kind") String kind,
+                @JsonProperty("asset") @JsonView(AdminView.class) Asset asset) 
{
+            this.label = label;
+            this.kind = kind;
+            this.asset = asset;
+        }
+    }
+
+    // Case (4): admin-only external-type property on a default-constructor (no
+    // @JsonCreator) bean -- exercises the other 
ExternalTypeHandler.complete() path.
+    static class DefaultCtorContainer {
+        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
+                include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+                property = "kind")
+        @JsonSubTypes({
+                @JsonSubTypes.Type(value = PublicAsset.class, name = "pub"),
+                @JsonSubTypes.Type(value = AdminAsset.class, name = "admin")
+        })
+        @JsonView(AdminView.class)
+        public Asset asset;
+
+        public String label;
+    }
+
+    // Case (5): admin-only external-type property on a @JsonPOJOBuilder-based 
bean --
+    // exercises the BuilderBasedDeserializer external-type path.
+    @JsonDeserialize(builder = BuilderContainer.Builder.class)
+    static class BuilderContainer {
+        public final String label;
+        public final Asset asset;
+
+        BuilderContainer(String label, Asset asset) {
+            this.label = label;
+            this.asset = asset;
+        }
+
+        @JsonPOJOBuilder(withPrefix = "with")
+        static class Builder {
+            String label;
+            Asset asset;
+
+            public Builder withLabel(String label) {
+                this.label = label;
+                return this;
+            }
+
+            @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
+                    include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+                    property = "kind")
+            @JsonSubTypes({
+                    @JsonSubTypes.Type(value = PublicAsset.class, name = 
"pub"),
+                    @JsonSubTypes.Type(value = AdminAsset.class, name = 
"admin")
+            })
+            @JsonView(AdminView.class)
+            public Builder withAsset(Asset asset) {
+                this.asset = asset;
+                return this;
+            }
+
+            public BuilderContainer build() {
+                return new BuilderContainer(label, asset);
+            }
+        }
+    }
+
+    // Case (6): reverse of (3) -- the type id "kind" is a creator parameter 
carrying
+    // the view, while the value "asset" is visible. Under PublicView the 
value must
+    // still be bound and resolve correctly (the type id string still drives 
type
+    // resolution), but the hidden "kind" creator parameter must be left null.
+    static class TypeIdGatedContainer {
+        @JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
+                include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
+                property = "kind",
+                visible = true)
+        @JsonSubTypes({
+                @JsonSubTypes.Type(value = PublicAsset.class, name = "pub"),
+                @JsonSubTypes.Type(value = AdminAsset.class, name = "admin")
+        })
+        public Asset asset;
+
+        public String label;
+        public String kind;
+
+        @JsonCreator
+        public TypeIdGatedContainer(
+                @JsonProperty("label") String label,
+                @JsonProperty("kind") @JsonView(AdminView.class) String kind,
+                @JsonProperty("asset") Asset asset) {
+            this.label = label;
+            this.kind = kind;
+            this.asset = asset;
+        }
+    }
+
+    private final ObjectMapper MAPPER = newJsonMapper();
+
+    // Case (1): admin-only polymorphic property must NOT be bound when reading
+    // with the less-privileged PublicView. A view never rewrites the type id, 
so
+    // the only correct outcome is that "asset" is skipped entirely (left 
null).
+    @Test
+    void testViewGatedExternalTypeProperty() throws Exception
+    {
+        String json = a2q("{'label':'hello','kind':'admin',"
+                + "'asset':{'name':'foo','secret':'LEAKED'}}");
+
+        PropertyGatedContainer result = MAPPER.readerWithView(PublicView.class)
+                .forType(PropertyGatedContainer.class)
+                .readValue(json);
+
+        assertEquals("hello", result.label);
+        // Admin-only property hidden from PublicView -> not bound at all
+        assertNull(result.asset, "Admin-only 'asset' must not be bound under 
PublicView");
+    }
+
+    // Sanity check: with the AdminView active, the same property IS bound, and
+    // resolves to AdminAsset (the type id is "admin").
+    @Test
+    void testViewGatedExternalTypePropertyVisibleForAdmin() throws Exception
+    {
+        String json = a2q("{'label':'hello','kind':'admin',"
+                + "'asset':{'name':'foo','secret':'shh'}}");
+
+        PropertyGatedContainer result = MAPPER.readerWithView(AdminView.class)
+                .forType(PropertyGatedContainer.class)
+                .readValue(json);
+
+        AdminAsset asset = assertInstanceOf(AdminAsset.class, result.asset);
+        assertEquals("foo", asset.name);
+        assertEquals("shh", asset.secret);
+    }
+
+    // Case (2): the property itself is always visible, so the type id "admin"
+    // correctly produces the admin subtype -- but its admin-only "secret" 
field
+    // must be left out when reading with PublicView.
+    @Test
+    void testViewGatedFieldOfExternalTypeSubtype() throws Exception
+    {
+        String json = a2q("{'label':'hello','kind':'admin',"
+                + "'asset':{'name':'foo','secret':'LEAKED'}}");
+
+        FieldGatedContainer result = MAPPER.readerWithView(PublicView.class)
+                .forType(FieldGatedContainer.class)
+                .readValue(json);
+
+        assertEquals("hello", result.label);
+        // View does not change the type id: still the admin subtype...
+        FieldGatedAdminAsset asset = 
assertInstanceOf(FieldGatedAdminAsset.class, result.asset);
+        assertEquals("foo", asset.name);
+        // ...but the admin-only field must not leak under PublicView
+        assertNull(asset.secret, "Admin-only 'secret' must not leak under 
PublicView");
+    }
+
+    // Case (3): hiding the admin-only value must NOT drop the (non-view) type 
id
+    // property when the type id is itself a creator parameter 
([databind#999]).
+    @Test
+    void testViewGatedValueKeepsVisibleTypeIdCreatorProp() throws Exception
+    {
+        String json = a2q("{'label':'hello','kind':'admin',"
+                + "'asset':{'name':'foo','secret':'LEAKED'}}");
+
+        TypeIdCreatorContainer result = MAPPER.readerWithView(PublicView.class)
+                .forType(TypeIdCreatorContainer.class)
+                .readValue(json);
+
+        assertEquals("hello", result.label);
+        // Admin-only value is hidden...
+        assertNull(result.asset, "Admin-only 'asset' must not be bound under 
PublicView");
+        // ...but the visible type id creator property must still be bound
+        assertEquals("admin", result.kind, "Visible type id 'kind' must still 
be bound");
+    }
+
+    // Case (4): admin-only external-type property on a default-constructor 
bean must
+    // also be skipped under PublicView (covers the other complete() overload).
+    @Test
+    void testViewGatedExternalTypePropertyDefaultCtor() throws Exception
+    {
+        String json = a2q("{'label':'hello','kind':'admin',"
+                + "'asset':{'name':'foo','secret':'LEAKED'}}");
+
+        DefaultCtorContainer result = MAPPER.readerWithView(PublicView.class)
+                .forType(DefaultCtorContainer.class)
+                .readValue(json);
+
+        assertEquals("hello", result.label);
+        assertNull(result.asset, "Admin-only 'asset' must not be bound under 
PublicView");
+    }
+
+    // Case (5): admin-only external-type property on a @JsonPOJOBuilder bean 
must be
+    // skipped under PublicView (covers the BuilderBasedDeserializer 
external-type path).
+    @Test
+    void testViewGatedExternalTypePropertyBuilder() throws Exception
+    {
+        String json = a2q("{'label':'hello','kind':'admin',"
+                + "'asset':{'name':'foo','secret':'LEAKED'}}");
+
+        BuilderContainer result = MAPPER.readerWithView(PublicView.class)
+                .forType(BuilderContainer.class)
+                .readValue(json);
+
+        assertEquals("hello", result.label);
+        assertNull(result.asset, "Admin-only 'asset' must not be bound under 
PublicView");
+    }
+
+    // Case (6): reverse of case (3) -- @JsonView on the type-id creator param 
but not
+    // the value. Under PublicView the value is still bound (and resolves to 
the admin
+    // subtype via the type id), but the hidden type-id property must be left 
null.
+    @Test
+    void testViewGatedTypeIdCreatorPropKeepsVisibleValue() throws Exception
+    {
+        String json = a2q("{'label':'hello','kind':'admin',"
+                + "'asset':{'name':'foo','secret':'shh'}}");
+
+        TypeIdGatedContainer result = MAPPER.readerWithView(PublicView.class)
+                .forType(TypeIdGatedContainer.class)
+                .readValue(json);
+
+        assertEquals("hello", result.label);
+        // Value carries no view -> still bound, and the type id still selects 
the subtype
+        AdminAsset asset = assertInstanceOf(AdminAsset.class, result.asset);
+        assertEquals("foo", asset.name);
+        // ...but the admin-only type id creator property must not be bound
+        assertNull(result.kind, "Admin-only type id 'kind' must not be bound 
under PublicView");
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/views/UnwrappedViewBypass6060Test.java
 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/views/UnwrappedViewBypass6060Test.java
--- 
old/jackson-databind-jackson-databind-2.18.8/src/test/java/com/fasterxml/jackson/databind/views/UnwrappedViewBypass6060Test.java
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/jackson-databind-jackson-databind-2.18.9/src/test/java/com/fasterxml/jackson/databind/views/UnwrappedViewBypass6060Test.java
    2026-07-08 02:18:37.000000000 +0200
@@ -0,0 +1,117 @@
+package com.fasterxml.jackson.databind.views;
+
+import com.fasterxml.jackson.annotation.*;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+// [databind#6060]: `@JsonView` by-passed for `@JsonUnwrapped` Field/Setter 
properties
+public class UnwrappedViewBypass6060Test extends DatabindTestUtil {
+    public static class PublicView {}
+    public static class AdminView extends PublicView {}
+
+    public static class AccountFlags {       // admin-only block
+        public String role;
+        public boolean approved;
+        public long creditBalance;
+    }
+    public static class Registration {       // bound at the public 
registration endpoint
+        @JsonView(PublicView.class) public String email;
+        @JsonView(PublicView.class) public String password;
+        @JsonView(AdminView.class) @JsonUnwrapped public AccountFlags flags;   
// admin-only, unwrapped
+    }
+    public static class Control {            // identical block, NOT unwrapped
+        @JsonView(PublicView.class) public String email;
+        @JsonView(AdminView.class)  public AccountFlags flags;
+    }
+
+    public static class RegistrationWithSetters {   // same as Registration, 
but via setters
+        String email;
+        String password;
+        AccountFlags flags;
+
+        @JsonView(PublicView.class)
+        public void setEmail(String email) { this.email = email; }
+
+        @JsonView(PublicView.class)
+        public void setPassword(String password) { this.password = password; }
+
+        @JsonView(AdminView.class) @JsonUnwrapped
+        public void setFlags(AccountFlags flags) { this.flags = flags; }
+    }
+
+    @Test
+    void testUnwrappedBypass() throws Exception {
+        ObjectMapper mapper = sharedMapper();
+
+        String jsonC = 
a2q("{'email':'e','flags':{'role':'ADMIN','approved':true,'creditBalance':1000000}}");
+        Control c = mapper.readerWithView(PublicView.class)
+                .forType(Control.class)
+                .readValue(jsonC);
+        assertEquals("e", c.email);
+        assertNull(c.flags, "expected control flag to be null in PublicView 
read");
+
+        String jsonR = a2q("{'email':'[email protected]','password':'pw',"
+                + "'role':'ADMIN','approved':true,'creditBalance':1000000}");
+        Registration r = mapper.readerWithView(PublicView.class)
+                .forType(Registration.class)
+                .readValue(jsonR);
+        assertEquals("[email protected]", r.email);
+        assertEquals("pw", r.password);
+        // JsonUnwrapped flag in Registration class may affect this
+        assertNull(r.flags, "expected registration flag to be null in 
PublicView read");
+    }
+
+    // Negative control: AdminView read MUST populate the unwrapped admin-only 
block,
+    // so the PublicView assertion above is not passing vacuously.
+    @Test
+    void testUnwrappedVisibleInAdminView() throws Exception {
+        ObjectMapper mapper = sharedMapper();
+
+        String jsonR = a2q("{'email':'[email protected]','password':'pw',"
+                + "'role':'ADMIN','approved':true,'creditBalance':1000000}");
+        Registration r = mapper.readerWithView(AdminView.class)
+                .forType(Registration.class)
+                .readValue(jsonR);
+        assertEquals("[email protected]", r.email);
+        assertNotNull(r.flags, "expected registration flag to be populated in 
AdminView read");
+        assertEquals("ADMIN", r.flags.role);
+        assertEquals(1000000, r.flags.creditBalance);
+    }
+
+    @Test
+    void testUnwrappedBypassWithSetters() throws Exception {
+        ObjectMapper mapper = sharedMapper();
+
+        String jsonR = a2q("{'email':'[email protected]','password':'pw',"
+                + "'role':'ADMIN','approved':true,'creditBalance':1000000}");
+        RegistrationWithSetters r = mapper.readerWithView(PublicView.class)
+                .forType(RegistrationWithSetters.class)
+                .readValue(jsonR);
+        assertEquals("[email protected]", r.email);
+        assertEquals("pw", r.password);
+        // JsonUnwrapped flag in RegistrationWithSetters class may affect this
+        assertNull(r.flags, "expected registration flag to be null in 
PublicView read");
+    }
+
+    // Negative control for the setter variant: AdminView read MUST populate 
flags.
+    @Test
+    void testUnwrappedVisibleInAdminViewWithSetters() throws Exception {
+        ObjectMapper mapper = sharedMapper();
+
+        String jsonR = a2q("{'email':'[email protected]','password':'pw',"
+                + "'role':'ADMIN','approved':true,'creditBalance':1000000}");
+        RegistrationWithSetters r = mapper.readerWithView(AdminView.class)
+                .forType(RegistrationWithSetters.class)
+                .readValue(jsonR);
+        assertEquals("[email protected]", r.email);
+        assertNotNull(r.flags, "expected registration flag to be populated in 
AdminView read");
+        assertEquals("ADMIN", r.flags.role);
+        assertEquals(1000000, r.flags.creditBalance);
+    }
+
+}

++++++ jackson-databind-build.xml ++++++
--- /var/tmp/diff_new_pack.HFgb1e/_old  2026-07-15 17:12:22.217109799 +0200
+++ /var/tmp/diff_new_pack.HFgb1e/_new  2026-07-15 17:12:22.221109936 +0200
@@ -11,7 +11,7 @@
   <property name="project.groupId" value="com.fasterxml.jackson.core"/>
   <property name="project.artifactId" value="jackson-databind"/>
   <property name="project.name" value="jackson-databind"/>
-  <property name="project.version" value="2.18.8"/>
+  <property name="project.version" value="2.18.9"/>
   <property name="project.vendor" value="FasterXML"/>
   <property name="project.description" value="General data-binding 
functionality for Jackson: works on core streaming API"/>
   <property name="bundle.version" value="${project.version}"/>

Reply via email to