This is an automated email from the ASF dual-hosted git repository. kusal pushed a commit to branch WW-5340-ognl-guard in repository https://gitbox.apache.org/repos/asf/struts.git
commit 200bc03616984a92e5009b17a7671f7f47526e0c Author: Kusal Kithul-Godage <g...@kusal.io> AuthorDate: Thu Aug 31 21:34:20 2023 +1000 WW-5340 Cache OgnlGuard result --- .../java/com/opensymphony/xwork2/ognl/OgnlCache.java | 16 ++++++++-------- .../com/opensymphony/xwork2/ognl/OgnlDefaultCache.java | 4 ++-- .../java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java | 6 +++--- .../main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java | 6 +++++- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlCache.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlCache.java index 83893c153..fc8366699 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlCache.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlCache.java @@ -19,23 +19,23 @@ package com.opensymphony.xwork2.ognl; * A basic cache interface for use with OGNL processing (such as Expression, BeanInfo). * All OGNL caches will have an eviction limit, but setting an extremely high value can * simulate an "effectively unlimited" cache. - * + * * @param <Key> The type for the cache key entries * @param <Value> The type for the cache value entries */ public interface OgnlCache<Key, Value> { - public Value get(Key key); + Value get(Key key); - public void put(Key key, Value value); + void put(Key key, Value value); - public void putIfAbsent(Key key, Value value); + void putIfAbsent(Key key, Value value); - public int size(); + int size(); - public void clear(); + void clear(); - public int getEvictionLimit(); + int getEvictionLimit(); - public void setEvictionLimit(int cacheEvictionLimit); + void setEvictionLimit(int cacheEvictionLimit); } diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java index 20431e133..a32736da6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlDefaultCache.java @@ -20,10 +20,10 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Default OGNL cache implementation. - * + * * Setting a very high eviction limit simulates an unlimited cache. * Setting too low an eviction limit will make the cache ineffective. - * + * * @param <Key> The type for the cache key entries * @param <Value> The type for the cache value entries */ diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java index a99adca2a..93ab56d36 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlLRUCache.java @@ -22,14 +22,14 @@ import java.util.concurrent.atomic.AtomicInteger; /** * A basic OGNL LRU cache implementation. - * + * * The implementation utilizes a {@link Collections#synchronizedMap(java.util.Map)} * backed by a {@link LinkedHashMap}. May be replaced by a more efficient implementation in the future. - * + * * Setting too low an eviction limit will produce more overhead than value. * Setting too high an eviction limit may also produce more overhead than value. * An appropriate eviction limit will need to be determined on an individual application basis. - * + * * @param <Key> The type for the cache key entries * @param <Value> The type for the cache value entries */ diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java index c080500aa..8a276435a 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java @@ -71,6 +71,7 @@ public class OgnlUtil { // Flag used to reduce flooding logs with WARNs about using DevMode excluded packages private final AtomicBoolean warnReported = new AtomicBoolean(false); + private static final String GUARD_BLOCKED = "_ognl_guard_blocked"; private final OgnlCache<String, Object> expressionCache; private final OgnlCache<Class<?>, BeanInfo> beanInfoCache; private TypeConverter defaultConverter; @@ -613,11 +614,14 @@ public class OgnlUtil { } if (tree == null) { tree = Ognl.parseExpression(expr); + if (ognlGuard.isBlocked(expr, tree)) { + tree = GUARD_BLOCKED; + } if (enableExpressionCache) { expressionCache.put(expr, tree); } } - if (ognlGuard.isBlocked(expr, tree)) { + if (GUARD_BLOCKED.equals(tree)) { throw new OgnlException("Expression blocked by OgnlGuard: " + expr); } return tree;