From b2ccdee0fdc52cd46577a90cb50dc011d6d681bf Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 7 Sep 2016 21:11:38 -0700 Subject: [PATCH] Fix #877 --- release-notes/VERSION | 1 + .../deser/BeanDeserializerFactory.java | 10 ++++- .../jackson/databind/util/ClassUtil.java | 10 ++--- .../jackson/databind/misc/AccessFixTest.java | 42 +++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/misc/AccessFixTest.java diff --git a/release-notes/VERSION b/release-notes/VERSION index 1334c68c5a..4d07e92be3 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -6,6 +6,7 @@ Project: jackson-databind 2.7.8 (not yet released) +#877: @JsonIgnoreProperties`: ignoring the "cause" property of `Throwable` on GAE #1359: Improve `JsonNode` deserializer to create `FloatNode` if parser supports #1362: ObjectReader.readValues()` ignores offset and length when reading an array (reported by wastevenson@github) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java index 10e08fca7e..128e462676 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java @@ -709,7 +709,15 @@ protected SettableBeanProperty constructSettableProperty(DeserializationContext AnnotatedMember mutator = propDef.getNonConstructorMutator(); if (ctxt.canOverrideAccessModifiers()) { - mutator.fixAccess(ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); + // [databind#877]: explicitly prevent forced access to `cause` of `Throwable`; + // never needed and attempts may cause problems on some platforms. + // !!! NOTE: should be handled better for 2.8 and later + if ((mutator instanceof AnnotatedField) + && "cause".equals(mutator.getName())) { + ; + } else { + mutator.fixAccess(ctxt.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); + } } // note: this works since we know there's exactly one argument for methods BeanProperty.Std property = new BeanProperty.Std(propDef.getFullName(), diff --git a/src/main/java/com/fasterxml/jackson/databind/util/ClassUtil.java b/src/main/java/com/fasterxml/jackson/databind/util/ClassUtil.java index d125a7d52d..08fac8d526 100644 --- a/src/main/java/com/fasterxml/jackson/databind/util/ClassUtil.java +++ b/src/main/java/com/fasterxml/jackson/databind/util/ClassUtil.java @@ -773,7 +773,6 @@ public static void checkAndFixAccess(Member member, boolean force) * always to make it accessible (latter because it will force * skipping checks we have no use for...), so let's always call it. */ - //if (!ao.isAccessible()) { try { if (force || (!Modifier.isPublic(member.getModifiers()) @@ -781,18 +780,15 @@ public static void checkAndFixAccess(Member member, boolean force) ao.setAccessible(true); } } catch (SecurityException se) { - /* 17-Apr-2009, tatu: Related to [JACKSON-101]: this can fail on - * platforms like EJB and Google App Engine); so let's - * only fail if we really needed it... - */ + // 17-Apr-2009, tatu: Related to [JACKSON-101]: this can fail on platforms like + // Google App Engine); so let's only fail if we really needed it... if (!ao.isAccessible()) { Class declClass = member.getDeclaringClass(); throw new IllegalArgumentException("Can not access "+member+" (from class "+declClass.getName()+"; failed to set access: "+se.getMessage()); } } - //} } - + /* /********************************************************** /* Enum type detection diff --git a/src/test/java/com/fasterxml/jackson/databind/misc/AccessFixTest.java b/src/test/java/com/fasterxml/jackson/databind/misc/AccessFixTest.java new file mode 100644 index 0000000000..6e7eb98865 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/misc/AccessFixTest.java @@ -0,0 +1,42 @@ +package com.fasterxml.jackson.databind.misc; + +import java.io.IOException; +import java.security.Permission; + +import com.fasterxml.jackson.databind.*; + +// Test(s) to verify that forced access works as expected +public class AccessFixTest extends BaseMapTest +{ + static class CauseBlockingSecurityManager + extends SecurityManager + { + @Override + public void checkPermission(Permission perm) throws SecurityException { + if ("suppressAccessChecks".equals(perm.getName())) { +throw new SecurityException("Can not force permission: "+perm); + } + } + } + + // [databind#877]: avoid forcing access to `cause` field of `Throwable` + // as it is never actually used (always call `initCause()` instead) + public void testCauseOfThrowableIgnoral() throws Exception + { + final SecurityManager origSecMan = System.getSecurityManager(); + try { + System.setSecurityManager(new CauseBlockingSecurityManager()); + _testCauseOfThrowableIgnoral(); + } finally { + System.setSecurityManager(origSecMan); + } + } + + private void _testCauseOfThrowableIgnoral() throws Exception + { + ObjectMapper mapper = new ObjectMapper(); + mapper.disable(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS); + IOException e = mapper.readValue("{}", IOException.class); + assertNotNull(e); + } +}