freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [freemarker] branch 2.3-gae updated: To be on the safe side, stopped using the deprecated static DefaultObjectWrapper instance in most SimpleSequence-s and SimpleHash-s, as that doesn't have MemberAccessPolicy specified by the user in the Configuration.
Date Sat, 04 Jan 2020 10:09:07 GMT
This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch 2.3-gae
in repository https://gitbox.apache.org/repos/asf/freemarker.git


The following commit(s) were added to refs/heads/2.3-gae by this push:
     new af26d4c  To be on the safe side, stopped using the deprecated static DefaultObjectWrapper
instance in most SimpleSequence-s and SimpleHash-s, as that doesn't have MemberAccessPolicy
specified by the user in the Configuration.
af26d4c is described below

commit af26d4c1812b0689eb3a8e6433ef324ffa7e2bb8
Author: ddekany <ddekany@apache.org>
AuthorDate: Wed Jan 1 20:08:02 2020 +0100

    To be on the safe side, stopped using the deprecated static DefaultObjectWrapper instance
in most SimpleSequence-s and SimpleHash-s, as that doesn't have MemberAccessPolicy specified
by the user in the Configuration.
---
 .../java/freemarker/core/AddConcatExpression.java  |  5 ++--
 .../java/freemarker/core/BuiltInsForNodes.java     |  4 +++-
 .../java/freemarker/core/BuiltInsForSequences.java |  9 +++++---
 .../freemarker/core/BuiltInsForStringsBasic.java   |  3 ++-
 .../freemarker/core/BuiltInsForStringsRegexp.java  |  5 ++--
 src/main/java/freemarker/core/DynamicKeyName.java  | 13 +++++------
 src/main/java/freemarker/core/Environment.java     |  9 +++++---
 .../freemarker/core/GetOptionalTemplateMethod.java |  3 ++-
 src/main/java/freemarker/core/HashLiteral.java     | 14 ++++++-----
 src/main/java/freemarker/core/ListLiteral.java     | 11 ++++-----
 src/main/java/freemarker/core/Macro.java           |  6 +++--
 src/main/java/freemarker/core/RecurseNode.java     |  3 ++-
 src/main/java/freemarker/core/TemplateElement.java |  3 +--
 src/main/java/freemarker/core/VisitNode.java       |  3 ++-
 .../java/freemarker/ext/ant/FreemarkerXmlTask.java |  3 ++-
 .../java/freemarker/ext/jdom/NodeListModel.java    |  3 ++-
 .../ext/servlet/AllHttpScopesHashModel.java        |  8 ++++---
 src/main/java/freemarker/template/SimpleHash.java  |  4 ++++
 src/main/java/freemarker/template/SimpleList.java  |  2 +-
 .../java/freemarker/template/SimpleSequence.java   | 14 ++++++++++-
 .../java/freemarker/template/_TemplateAPI.java     | 27 ++++++++++++++++++++++
 .../freemarker/template/utility/DOMNodeModel.java  |  3 ++-
 .../template/utility/TemplateModelUtils.java       |  5 ++--
 src/manual/en_US/book.xml                          | 12 +++++++++-
 .../test/templatesuite/models/LegacyList.java      |  5 ++++
 .../test/templatesuite/models/MultiModel1.java     | 13 +++++++----
 .../templatesuite/models/TransformHashWrapper.java |  3 ++-
 27 files changed, 139 insertions(+), 54 deletions(-)

diff --git a/src/main/java/freemarker/core/AddConcatExpression.java b/src/main/java/freemarker/core/AddConcatExpression.java
index 40d0bb6..b89b472 100644
--- a/src/main/java/freemarker/core/AddConcatExpression.java
+++ b/src/main/java/freemarker/core/AddConcatExpression.java
@@ -35,6 +35,7 @@ import freemarker.template.TemplateModelIterator;
 import freemarker.template.TemplateNumberModel;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 
 /**
  * An operator for the + operator. Note that this is treated
@@ -266,7 +267,7 @@ final class AddConcatExpression extends Expression {
         throws TemplateModelException {
             if (keys == null) {
                 HashSet keySet = new HashSet();
-                SimpleSequence keySeq = new SimpleSequence(32);
+                SimpleSequence keySeq = new SimpleSequence(32, _TemplateAPI.SAFE_OBJECT_WRAPPER);
                 addKeys(keySet, keySeq, (TemplateHashModelEx) this.left);
                 addKeys(keySet, keySeq, (TemplateHashModelEx) this.right);
                 keys = new CollectionAndSequence(keySeq);
@@ -289,7 +290,7 @@ final class AddConcatExpression extends Expression {
         private void initValues()
         throws TemplateModelException {
             if (values == null) {
-                SimpleSequence seq = new SimpleSequence(size());
+                SimpleSequence seq = new SimpleSequence(size(), _TemplateAPI.SAFE_OBJECT_WRAPPER);
                 // Note: size() invokes initKeys() if needed.
             
                 int ln = keys.size();
diff --git a/src/main/java/freemarker/core/BuiltInsForNodes.java b/src/main/java/freemarker/core/BuiltInsForNodes.java
index efeae9b..acd9fdf 100644
--- a/src/main/java/freemarker/core/BuiltInsForNodes.java
+++ b/src/main/java/freemarker/core/BuiltInsForNodes.java
@@ -30,8 +30,9 @@ import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateNodeModel;
 import freemarker.template.TemplateNodeModelEx;
+import freemarker.template._TemplateAPI;
 
-/**
+        /**
  * A holder for builtins that operate exclusively on (XML-)node left-hand value.
  */
 class BuiltInsForNodes {
@@ -122,6 +123,7 @@ class BuiltInsForNodes {
         private Environment env;
         
         AncestorSequence(Environment env) {
+            super(_TemplateAPI.SAFE_OBJECT_WRAPPER);
             this.env = env;
         }
         
diff --git a/src/main/java/freemarker/core/BuiltInsForSequences.java b/src/main/java/freemarker/core/BuiltInsForSequences.java
index 6d76e1d..fcaeebd 100644
--- a/src/main/java/freemarker/core/BuiltInsForSequences.java
+++ b/src/main/java/freemarker/core/BuiltInsForSequences.java
@@ -45,6 +45,7 @@ import freemarker.template.TemplateModelListSequence;
 import freemarker.template.TemplateNumberModel;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 import freemarker.template.utility.Constants;
 import freemarker.template.utility.StringUtil;
 
@@ -805,7 +806,7 @@ class BuiltInsForSequences {
                 }
             }
 
-            // Sort tje List[KVP]:
+            // Sort the List[KVP]:
             try {
                 Collections.sort(res, keyComparator);
             } catch (Exception exc) {
@@ -870,8 +871,10 @@ class BuiltInsForSequences {
             if (!lazilyGeneratedResultEnabled) {
                 SimpleSequence seq =
                         coll instanceof TemplateCollectionModelEx
-                                ? new SimpleSequence(((TemplateCollectionModelEx) coll).size())
-                                : new SimpleSequence();
+                                ? new SimpleSequence(
+                                        ((TemplateCollectionModelEx) coll).size(),
+                                        _TemplateAPI.SAFE_OBJECT_WRAPPER)
+                                : new SimpleSequence(_TemplateAPI.SAFE_OBJECT_WRAPPER);
                 for (TemplateModelIterator iter = coll.iterator(); iter.hasNext(); ) {
                     seq.add(iter.next());
                 }
diff --git a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
index 7583984..4afffb8 100644
--- a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
+++ b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java
@@ -35,6 +35,7 @@ import freemarker.template.TemplateMethodModelEx;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateScalarModel;
+import freemarker.template._TemplateAPI;
 import freemarker.template.utility.StringUtil;
 
 class BuiltInsForStringsBasic {
@@ -804,7 +805,7 @@ class BuiltInsForStringsBasic {
     static class word_listBI extends BuiltInForString {
         @Override
         TemplateModel calculateResult(String s, Environment env) {
-            SimpleSequence result = new SimpleSequence();
+            SimpleSequence result = new SimpleSequence(_TemplateAPI.SAFE_OBJECT_WRAPPER);
             StringTokenizer st = new StringTokenizer(s);
             while (st.hasMoreTokens()) {
                result.add(st.nextToken());
diff --git a/src/main/java/freemarker/core/BuiltInsForStringsRegexp.java b/src/main/java/freemarker/core/BuiltInsForStringsRegexp.java
index 584833d..d6d3082 100644
--- a/src/main/java/freemarker/core/BuiltInsForStringsRegexp.java
+++ b/src/main/java/freemarker/core/BuiltInsForStringsRegexp.java
@@ -35,6 +35,7 @@ import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateModelIterator;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 import freemarker.template.utility.StringUtil;
 
 
@@ -138,11 +139,11 @@ class BuiltInsForStringsRegexp {
         static class MatchWithGroups implements TemplateScalarModel {
             final String matchedInputPart;
             final SimpleSequence groupsSeq;
-            
+
             MatchWithGroups(String input, Matcher matcher) {
                 matchedInputPart = input.substring(matcher.start(), matcher.end());
                 final int grpCount = matcher.groupCount() + 1;
-                groupsSeq = new SimpleSequence(grpCount);
+                groupsSeq = new SimpleSequence(grpCount, _TemplateAPI.SAFE_OBJECT_WRAPPER);
                 for (int i = 0; i < grpCount; i++) {
                     groupsSeq.add(matcher.group(i));
                 }
diff --git a/src/main/java/freemarker/core/DynamicKeyName.java b/src/main/java/freemarker/core/DynamicKeyName.java
index 4a72543..e455b94 100644
--- a/src/main/java/freemarker/core/DynamicKeyName.java
+++ b/src/main/java/freemarker/core/DynamicKeyName.java
@@ -21,7 +21,6 @@ package freemarker.core;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 
 import freemarker.template.SimpleScalar;
@@ -291,8 +290,8 @@ final class DynamicKeyName extends Expression {
                 resultList.add(targetSeq.get(srcIdx));
                 srcIdx += step;
             }
-            // List items are already wrapped, so the wrapper will be null:
-            return new SimpleSequence(resultList, null);
+            // List items are already wrapped:
+            return new SimpleSequence(resultList, _TemplateAPI.SAFE_OBJECT_WRAPPER);
         } else if (targetLazySeq != null) {
             // As a targetLazySeq can only occur if a new built-in like ?filter or ?map was
used somewhere in the target
             // expression, in this case we can return lazily generated sequence without breaking
backward compatibility.
@@ -384,8 +383,8 @@ final class DynamicKeyName extends Expression {
                 }
                 resultList.add(targetIter.next());
             }
-            // List items are already wrapped, so the wrapper will be null:
-            return new SimpleSequence(resultList, null);
+            // List items are already wrapped:
+            return new SimpleSequence(resultList, _TemplateAPI.SAFE_OBJECT_WRAPPER);
         }
     }
 
@@ -432,13 +431,13 @@ final class DynamicKeyName extends Expression {
                     "Range top index " + highIndex + " (0-based) is outside the sliced sequence
of length " +
                     srcIdx + ".");
         }
-        return new SimpleSequence(Arrays.asList(resultElements), null);
+        return new SimpleSequence(Arrays.asList(resultElements), _TemplateAPI.SAFE_OBJECT_WRAPPER);
     }
 
     private TemplateModel emptyResult(boolean seq) {
         return seq
                 ? (_TemplateAPI.getTemplateLanguageVersionAsInt(this) < _TemplateAPI.VERSION_INT_2_3_21
-                        ? new SimpleSequence(Collections.EMPTY_LIST, null)
+                        ? new SimpleSequence(_TemplateAPI.SAFE_OBJECT_WRAPPER)
                         : Constants.EMPTY_SEQUENCE)
                 : TemplateScalarModel.EMPTY_STRING;
     }
diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index fcce497..c48954e 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -725,7 +725,7 @@ public final class Environment extends Configurable {
     void invokeNodeHandlerFor(TemplateNodeModel node, TemplateSequenceModel namespaces)
             throws TemplateException, IOException {
         if (nodeNamespaces == null) {
-            SimpleSequence ss = new SimpleSequence(1);
+            SimpleSequence ss = new SimpleSequence(1, _TemplateAPI.SAFE_OBJECT_WRAPPER);
             ss.add(currentNamespace);
             nodeNamespaces = ss;
         }
@@ -1122,14 +1122,15 @@ public final class Environment extends Configurable {
 
     private static SimpleSequence initPositionalCatchAllParameter(Macro.Context macroCtx,
String catchAllParamName) {
         SimpleSequence positionalCatchAllParamValue;
-        positionalCatchAllParamValue = new SimpleSequence((ObjectWrapper) null);
+        positionalCatchAllParamValue = new SimpleSequence(_TemplateAPI.SAFE_OBJECT_WRAPPER);
         macroCtx.setLocalVar(catchAllParamName, positionalCatchAllParamValue);
         return positionalCatchAllParamValue;
     }
 
     private static SimpleHash initNamedCatchAllParameter(Macro.Context macroCtx, String catchAllParamName)
{
         SimpleHash namedCatchAllParamValue;
-        namedCatchAllParamValue = new SimpleHash(new LinkedHashMap<String, Object>(),
null, 0);
+        namedCatchAllParamValue = new SimpleHash(
+                new LinkedHashMap<String, Object>(), _TemplateAPI.SAFE_OBJECT_WRAPPER,
0);
         macroCtx.setLocalVar(catchAllParamName, namedCatchAllParamValue);
         return namedCatchAllParamValue;
     }
@@ -3230,10 +3231,12 @@ public final class Environment extends Configurable {
         private Template template;
 
         Namespace() {
+            super(_TemplateAPI.SAFE_OBJECT_WRAPPER);
             this.template = Environment.this.getTemplate();
         }
 
         Namespace(Template template) {
+            super(_TemplateAPI.SAFE_OBJECT_WRAPPER);
             this.template = template;
         }
 
diff --git a/src/main/java/freemarker/core/GetOptionalTemplateMethod.java b/src/main/java/freemarker/core/GetOptionalTemplateMethod.java
index 158b08c..be6c822 100644
--- a/src/main/java/freemarker/core/GetOptionalTemplateMethod.java
+++ b/src/main/java/freemarker/core/GetOptionalTemplateMethod.java
@@ -37,6 +37,7 @@ import freemarker.template.TemplateMethodModelEx;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateScalarModel;
+import freemarker.template._TemplateAPI;
 import freemarker.template.utility.TemplateModelUtils;
 
 /**
@@ -142,7 +143,7 @@ class GetOptionalTemplateMethod implements TemplateMethodModelEx {
                         "; see cause exception");
         }
         
-        SimpleHash result = new SimpleHash(env.getObjectWrapper());
+        SimpleHash result = new SimpleHash(_TemplateAPI.SAFE_OBJECT_WRAPPER);
         result.put(RESULT_EXISTS, template != null);
         // If the template is missing, result.include and such will be missing too, so that
a default can be
         // conveniently provided like in <@optTemp.include!myDefaultMacro />.
diff --git a/src/main/java/freemarker/core/HashLiteral.java b/src/main/java/freemarker/core/HashLiteral.java
index 113b94d..7b4607c 100644
--- a/src/main/java/freemarker/core/HashLiteral.java
+++ b/src/main/java/freemarker/core/HashLiteral.java
@@ -127,8 +127,8 @@ final class HashLiteral extends Expression {
                 // Legacy hash literal, where repeated keys were kept when doing ?values
or ?keys, yet overwritten when
                 // doing hash[key].
                 map = new HashMap<String, TemplateModel>();
-                List<String> keyList = new ArrayList<String>(size);
-                List<TemplateModel> valueList = new ArrayList<TemplateModel>(size);
+                SimpleSequence keyList = new SimpleSequence(size, _TemplateAPI.SAFE_OBJECT_WRAPPER);
+                SimpleSequence valueList = new SimpleSequence(size, _TemplateAPI.SAFE_OBJECT_WRAPPER);
                 for (int i = 0; i < size; i++) {
                     Expression keyExp = keys.get(i);
                     Expression valExp = values.get(i);
@@ -141,8 +141,8 @@ final class HashLiteral extends Expression {
                     keyList.add(key);
                     valueList.add(value);
                 }
-                keyCollection = new CollectionAndSequence(new SimpleSequence(keyList));
-                valueCollection = new CollectionAndSequence(new SimpleSequence(valueList));
+                keyCollection = new CollectionAndSequence(keyList);
+                valueCollection = new CollectionAndSequence(valueList);
             }
         }
 
@@ -153,7 +153,8 @@ final class HashLiteral extends Expression {
         public TemplateCollectionModel keys() {
             if (keyCollection == null) {
                 // This can only happen when IcI >= 2.3.21, an the map is a LinkedHashMap.
-                keyCollection = new CollectionAndSequence(new SimpleSequence(map.keySet()));
+                keyCollection = new CollectionAndSequence(
+                        new SimpleSequence(map.keySet(), _TemplateAPI.SAFE_OBJECT_WRAPPER));
             }
             return keyCollection;
         }
@@ -161,7 +162,8 @@ final class HashLiteral extends Expression {
         public TemplateCollectionModel values() {
             if (valueCollection == null) {
                 // This can only happen when IcI >= 2.3.21, an the map is a LinkedHashMap.
-                valueCollection = new CollectionAndSequence(new SimpleSequence(map.values()));
+                valueCollection = new CollectionAndSequence(
+                        new SimpleSequence(map.values(), _TemplateAPI.SAFE_OBJECT_WRAPPER));
             }
             return valueCollection;
         }
diff --git a/src/main/java/freemarker/core/ListLiteral.java b/src/main/java/freemarker/core/ListLiteral.java
index 02b42be..e384cd0 100644
--- a/src/main/java/freemarker/core/ListLiteral.java
+++ b/src/main/java/freemarker/core/ListLiteral.java
@@ -22,7 +22,6 @@ package freemarker.core;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 
@@ -32,6 +31,7 @@ import freemarker.template.TemplateMethodModel;
 import freemarker.template.TemplateMethodModelEx;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 
 final class ListLiteral extends Expression {
 
@@ -44,11 +44,10 @@ final class ListLiteral extends Expression {
 
     @Override
     TemplateModel _eval(Environment env) throws TemplateException {
-        SimpleSequence list = new SimpleSequence(items.size());
-        for (Iterator it = items.iterator(); it.hasNext(); ) {
-            Expression exp = (Expression) it.next();
+        SimpleSequence list = new SimpleSequence(items.size(), _TemplateAPI.SAFE_OBJECT_WRAPPER);
+        for (Expression exp : items) {
             TemplateModel tm = exp.eval(env);
-            if (env == null || !env.isClassicCompatible()) {            
+            if (env == null || !env.isClassicCompatible()) {
                 exp.assertNonNull(tm, env);
             }
             list.add(tm);
@@ -141,7 +140,7 @@ final class ListLiteral extends Expression {
     
     TemplateSequenceModel evaluateStringsToNamespaces(Environment env) throws TemplateException
{
         TemplateSequenceModel val = (TemplateSequenceModel) eval(env);
-        SimpleSequence result = new SimpleSequence(val.size());
+        SimpleSequence result = new SimpleSequence(val.size(), _TemplateAPI.SAFE_OBJECT_WRAPPER);
         for (int i = 0; i < items.size(); i++) {
             Object itemExpr = items.get(i);
             if (itemExpr instanceof StringLiteral) {
diff --git a/src/main/java/freemarker/core/Macro.java b/src/main/java/freemarker/core/Macro.java
index 4e564ef..79b0c83 100644
--- a/src/main/java/freemarker/core/Macro.java
+++ b/src/main/java/freemarker/core/Macro.java
@@ -37,6 +37,7 @@ import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateModelIterator;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 import freemarker.template.utility.Constants;
 
 /**
@@ -342,7 +343,8 @@ public final class Macro extends TemplateElement implements TemplateModel
{
                         lengthWithCatchAlls += ((TemplateSequenceModel) catchAllArgValue).size();
                     }
 
-                    SimpleSequence argsSpecVarValue = new SimpleSequence(lengthWithCatchAlls);
+                    SimpleSequence argsSpecVarValue = new SimpleSequence(
+                            lengthWithCatchAlls, _TemplateAPI.SAFE_OBJECT_WRAPPER);
                     for (int paramIndex = 0; paramIndex < argsSpecVarDraft.length; paramIndex++)
{
                         argsSpecVarValue.add(argsSpecVarDraft[paramIndex]);
                     }
@@ -377,7 +379,7 @@ public final class Macro extends TemplateElement implements TemplateModel
{
 
                     SimpleHash argsSpecVarValue = new SimpleHash(
                             new LinkedHashMap<String, Object>(lengthWithCatchAlls *
4 / 3, 1.0f),
-                            null, 0);
+                            _TemplateAPI.SAFE_OBJECT_WRAPPER, 0);
                     for (int paramIndex = 0; paramIndex < argsSpecVarDraft.length; paramIndex++)
{
                         argsSpecVarValue.put(paramNames[paramIndex], argsSpecVarDraft[paramIndex]);
                     }
diff --git a/src/main/java/freemarker/core/RecurseNode.java b/src/main/java/freemarker/core/RecurseNode.java
index 42a8d32..c7a4b09 100644
--- a/src/main/java/freemarker/core/RecurseNode.java
+++ b/src/main/java/freemarker/core/RecurseNode.java
@@ -28,6 +28,7 @@ import freemarker.template.TemplateModel;
 import freemarker.template.TemplateNodeModel;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 
 
 /**
@@ -57,7 +58,7 @@ final class RecurseNode extends TemplateElement {
         }
         if (nss != null) {
             if (nss instanceof TemplateHashModel) {
-                SimpleSequence ss = new SimpleSequence(1);
+                SimpleSequence ss = new SimpleSequence(1, _TemplateAPI.SAFE_OBJECT_WRAPPER);
                 ss.add(nss);
                 nss = ss;
             } else if (!(nss instanceof TemplateSequenceModel)) {
diff --git a/src/main/java/freemarker/core/TemplateElement.java b/src/main/java/freemarker/core/TemplateElement.java
index 5f90b60..6cb9b54 100644
--- a/src/main/java/freemarker/core/TemplateElement.java
+++ b/src/main/java/freemarker/core/TemplateElement.java
@@ -22,7 +22,6 @@ package freemarker.core;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Enumeration;
-import java.util.Map;
 
 import freemarker.template.SimpleSequence;
 import freemarker.template.TemplateException;
@@ -53,7 +52,7 @@ abstract public class TemplateElement extends TemplateObject {
      * Contains 1 or more nested elements with optional trailing {@code null}-s, or is {@code
null} exactly if there are
      * no nested elements. Normally, the {@link #parent} of these is the {@code this}, however,
in some exceptional
      * cases it's not so, to avoid copying the whole descendant tree with a different parent
(as in the result of
-     * {@link Macro#Macro(Macro, Map)}.
+     * {@link Macro#Macro(Macro, Macro.WithArgs)}.
      */
     private TemplateElement[] childBuffer;
 
diff --git a/src/main/java/freemarker/core/VisitNode.java b/src/main/java/freemarker/core/VisitNode.java
index be80fe2..daaf0a7 100644
--- a/src/main/java/freemarker/core/VisitNode.java
+++ b/src/main/java/freemarker/core/VisitNode.java
@@ -27,6 +27,7 @@ import freemarker.template.TemplateModel;
 import freemarker.template.TemplateNodeModel;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 
 
 /**
@@ -56,7 +57,7 @@ final class VisitNode extends TemplateElement {
         }
         if (nss != null) {
             if (nss instanceof Environment.Namespace) {
-                SimpleSequence ss = new SimpleSequence(1);
+                SimpleSequence ss = new SimpleSequence(1, _TemplateAPI.SAFE_OBJECT_WRAPPER);
                 ss.add(nss);
                 nss = ss;
             } else if (!(nss instanceof TemplateSequenceModel)) {
diff --git a/src/main/java/freemarker/ext/ant/FreemarkerXmlTask.java b/src/main/java/freemarker/ext/ant/FreemarkerXmlTask.java
index 59fed7b..c8943e5 100644
--- a/src/main/java/freemarker/ext/ant/FreemarkerXmlTask.java
+++ b/src/main/java/freemarker/ext/ant/FreemarkerXmlTask.java
@@ -49,6 +49,7 @@ import freemarker.template.SimpleScalar;
 import freemarker.template.Template;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateNodeModel;
+import freemarker.template._TemplateAPI;
 import freemarker.template.utility.ClassUtil;
 import freemarker.template.utility.SecurityUtilities;
 
@@ -603,7 +604,7 @@ extends
     }
 
     private static TemplateModel wrapMap(Map table) {
-        SimpleHash model = new SimpleHash();
+        SimpleHash model = new SimpleHash(_TemplateAPI.SAFE_OBJECT_WRAPPER);
         for (Iterator it = table.entrySet().iterator(); it.hasNext(); ) {
             Map.Entry entry = (Map.Entry) it.next();
             model.put(String.valueOf(entry.getKey()), new SimpleScalar(String.valueOf(entry.getValue())));
diff --git a/src/main/java/freemarker/ext/jdom/NodeListModel.java b/src/main/java/freemarker/ext/jdom/NodeListModel.java
index bc39bef..ef44832 100644
--- a/src/main/java/freemarker/ext/jdom/NodeListModel.java
+++ b/src/main/java/freemarker/ext/jdom/NodeListModel.java
@@ -60,6 +60,7 @@ import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateModelIterator;
 import freemarker.template.TemplateScalarModel;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 
 /**
  * Provides a template for wrapping JDOM objects. It is capable of storing not only
@@ -1138,7 +1139,7 @@ implements
     throws Exception {
         org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
         Document document = builder.build(System.in);
-        SimpleHash model = new SimpleHash();
+        SimpleHash model = new SimpleHash(_TemplateAPI.SAFE_OBJECT_WRAPPER);
         model.put("document", new NodeListModel(document));
         FileReader fr = new FileReader(args[0]);
         Template template = new Template(args[0], fr);
diff --git a/src/main/java/freemarker/ext/servlet/AllHttpScopesHashModel.java b/src/main/java/freemarker/ext/servlet/AllHttpScopesHashModel.java
index 6428dda..16d9eab 100644
--- a/src/main/java/freemarker/ext/servlet/AllHttpScopesHashModel.java
+++ b/src/main/java/freemarker/ext/servlet/AllHttpScopesHashModel.java
@@ -30,6 +30,7 @@ import freemarker.template.ObjectWrapper;
 import freemarker.template.SimpleHash;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
+import freemarker.template.utility.NullArgumentException;
 
 /**
  * An extension of SimpleHash that looks up keys in the hash, then in the
@@ -51,13 +52,14 @@ public class AllHttpScopesHashModel extends SimpleHash {
     /**
      * Creates a new instance of AllHttpScopesHashModel for handling a single 
      * HTTP servlet request.
-     * @param wrapper the object wrapper to use
+     * @param objectWrapper the object wrapper to use; not {@code null}.
      * @param context the servlet context of the web application
      * @param request the HTTP servlet request being processed
      */
-    public AllHttpScopesHashModel(ObjectWrapper wrapper, 
+    public AllHttpScopesHashModel(ObjectWrapper objectWrapper,
             ServletContext context, HttpServletRequest request) {
-        setObjectWrapper(wrapper);
+        super(objectWrapper);
+        NullArgumentException.check("wrapper", objectWrapper);
         this.context = context;
         this.request = request;
     }
diff --git a/src/main/java/freemarker/template/SimpleHash.java b/src/main/java/freemarker/template/SimpleHash.java
index f32ebb2..d950ce0 100644
--- a/src/main/java/freemarker/template/SimpleHash.java
+++ b/src/main/java/freemarker/template/SimpleHash.java
@@ -30,6 +30,7 @@ import java.util.TreeMap;
 import freemarker.core._DelayedJQuote;
 import freemarker.core._TemplateModelException;
 import freemarker.ext.beans.BeansWrapper;
+import freemarker.template.utility.NullArgumentException;
 
 /**
  * A simple implementation of the {@link TemplateHashModelEx} interface, using its own underlying
{@link Map} or
@@ -111,6 +112,7 @@ public class SimpleHash extends WrappingTemplateModel implements TemplateHashMod
      */
     public SimpleHash(ObjectWrapper wrapper) {
         super(wrapper);
+        NullArgumentException.check(wrapper); //!!T
         map = new HashMap();
     }
 
@@ -133,6 +135,7 @@ public class SimpleHash extends WrappingTemplateModel implements TemplateHashMod
      */
     public SimpleHash(Map<String, Object> directMap, ObjectWrapper wrapper, int overloadDistinction)
{
         super(wrapper);
+        NullArgumentException.check(wrapper); //!!T
         this.map = directMap;
     }
 
@@ -150,6 +153,7 @@ public class SimpleHash extends WrappingTemplateModel implements TemplateHashMod
      */
     public SimpleHash(Map map, ObjectWrapper wrapper) {
         super(wrapper);
+        NullArgumentException.check(wrapper); //!!T
         Map mapCopy;
         try {
             mapCopy = copyMap(map);
diff --git a/src/main/java/freemarker/template/SimpleList.java b/src/main/java/freemarker/template/SimpleList.java
index 414fd11..af9506c 100644
--- a/src/main/java/freemarker/template/SimpleList.java
+++ b/src/main/java/freemarker/template/SimpleList.java
@@ -25,7 +25,7 @@ package freemarker.template;
  *
  * <p>This class is thread-safe.
  *
- * @deprecated Use SimpleSequence instead.
+ * @deprecated Use {@link SimpleSequence} instead.
  * @see SimpleSequence
  */
 
diff --git a/src/main/java/freemarker/template/SimpleSequence.java b/src/main/java/freemarker/template/SimpleSequence.java
index 24b44e1..6815a27 100644
--- a/src/main/java/freemarker/template/SimpleSequence.java
+++ b/src/main/java/freemarker/template/SimpleSequence.java
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.List;
 
 import freemarker.ext.beans.BeansWrapper;
+import freemarker.template.utility.NullArgumentException;
 
 /**
  * A simple implementation of the {@link TemplateSequenceModel} interface, using its own
underlying {@link List} for
@@ -91,7 +92,7 @@ public class SimpleSequence extends WrappingTemplateModel implements TemplateSeq
      * the default object wrapper set in 
      * {@link WrappingTemplateModel#setDefaultObjectWrapper(ObjectWrapper)}.
      * 
-     * @deprecated Use {@link #SimpleSequence(Collection, ObjectWrapper)}.
+     * @deprecated Use {@link #SimpleSequence(int, ObjectWrapper)}.
      */
     @Deprecated
     public SimpleSequence(int capacity) {
@@ -138,6 +139,7 @@ public class SimpleSequence extends WrappingTemplateModel implements TemplateSeq
      */
     public SimpleSequence(ObjectWrapper wrapper) {
         super(wrapper);
+        NullArgumentException.check(wrapper); //!!T
         list = new ArrayList();
     }
     
@@ -151,6 +153,7 @@ public class SimpleSequence extends WrappingTemplateModel implements TemplateSeq
      */
     public SimpleSequence(int capacity, ObjectWrapper wrapper) {
         super(wrapper);
+        NullArgumentException.check(wrapper); //!!T
         list = new ArrayList(capacity);
     }    
     
@@ -168,6 +171,7 @@ public class SimpleSequence extends WrappingTemplateModel implements TemplateSeq
      */
     public SimpleSequence(Collection collection, ObjectWrapper wrapper) {
         super(wrapper);
+        NullArgumentException.check(wrapper); //!!T
         list = new ArrayList(collection);
     }
 
@@ -264,6 +268,9 @@ public class SimpleSequence extends WrappingTemplateModel implements TemplateSeq
     }
 
     private class SynchronizedSequence extends SimpleSequence {
+        private SynchronizedSequence() {
+            super(SimpleSequence.this.getObjectWrapper());
+        }
 
         @Override
         public void add(Object obj) {
@@ -292,6 +299,11 @@ public class SimpleSequence extends WrappingTemplateModel implements
TemplateSeq
                 return SimpleSequence.this.toList();
             }
         }
+
+        @Override
+        public SimpleSequence synchronizedWrapper() {
+            return this;
+        }
     }
     
 }
\ No newline at end of file
diff --git a/src/main/java/freemarker/template/_TemplateAPI.java b/src/main/java/freemarker/template/_TemplateAPI.java
index 1b7bb0b..8d1683f 100644
--- a/src/main/java/freemarker/template/_TemplateAPI.java
+++ b/src/main/java/freemarker/template/_TemplateAPI.java
@@ -54,6 +54,33 @@ public class _TemplateAPI {
     public static final int VERSION_INT_2_3_29 = Configuration.VERSION_2_3_29.intValue();
     public static final int VERSION_INT_2_3_30 = Configuration.VERSION_2_3_30.intValue();
     public static final int VERSION_INT_2_4_0 = Version.intValueFor(2, 4, 0);
+
+    /**
+     * Kind of a dummy {@link ObjectWrapper} used at places where the internal code earlier
used the
+     * {@link ObjectWrapper#DEFAULT_WRAPPER} singleton, because it wasn't supposed to wrap/unwrap
anything with it;
+     * never use this {@link ObjectWrapper}r in situations where values of arbitrary types
need to be wrapped!
+     * The typical situation is that we are using {@link SimpleSequence}, or {@link SimpleHash},
which always has an
+     * {@link ObjectWrapper} field, even if we don't care in the given situation, and so
we didn't set it explicitly.
+     * The concern with the old way is that the {@link ObjectWrapper} set in the {@link Configuration}
is possibly
+     * more restrictive than the default, so if the template author can somehow make FreeMarker
wrap something with the
+     * default {@link ObjectWrapper}, then we got a security problem. So we try not to have
that around, if possible.
+     * The obvious fix, and the better engineering would be just use a such {@link TemplateSequenceModel}
or
+     * {@link TemplateHashModelEx2} implementation at those places, which doesn't have an
{@link ObjectWrapper} (and
+     * doesn't have the overhead of said implementations either). But, some user code might
casts the values it
+     * receives (as directive argument for example) to {@link SimpleSequence} or {@link SimpleHash},
instead of to
+     * {@link TemplateSequenceModel} or {@link TemplateHashModelEx2}. Such user code is wrong,
but still, if it worked
+     * so far fine (especially as sequence/hash literals are implemented by these "Simple"
classes), it's better if it
+     * keeps working when they upgrade to 2.3.30. Such user code will be still out of luck
if it also tries to add items
+     * which are not handled by {@link SimpleObjectWrapper}, but such abuse is even more
unlikely, and this is how far
+     * we could go with this backward compatibility hack.
+     *
+     * @since 2.3.30
+     */
+    public static final SimpleObjectWrapper SAFE_OBJECT_WRAPPER;
+    static {
+        SAFE_OBJECT_WRAPPER = new SimpleObjectWrapper(Configuration.VERSION_2_3_0);
+        SAFE_OBJECT_WRAPPER.writeProtect();
+    }
     
     public static void checkVersionNotNullAndSupported(Version incompatibleImprovements)
{
         NullArgumentException.check("incompatibleImprovements", incompatibleImprovements);
diff --git a/src/main/java/freemarker/template/utility/DOMNodeModel.java b/src/main/java/freemarker/template/utility/DOMNodeModel.java
index 5bb0b29..404fe45 100644
--- a/src/main/java/freemarker/template/utility/DOMNodeModel.java
+++ b/src/main/java/freemarker/template/utility/DOMNodeModel.java
@@ -38,6 +38,7 @@ import freemarker.template.TemplateMethodModel;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateSequenceModel;
+import freemarker.template._TemplateAPI;
 
 /**
  * A convenient wrapper class for wrapping a Node in the W3C DOM API.
@@ -72,7 +73,7 @@ public class DOMNodeModel implements TemplateHashModel {
             if ("attributes".equals(key)) {
                 NamedNodeMap attributes = node.getAttributes();
                 if (attributes != null) {
-                    SimpleHash hash = new SimpleHash();
+                    SimpleHash hash = new SimpleHash(_TemplateAPI.SAFE_OBJECT_WRAPPER);
                     for (int i = 0; i < attributes.getLength(); i++) {
                         Attr att = (Attr) attributes.item(i);
                         hash.put(att.getName(), att.getValue());
diff --git a/src/main/java/freemarker/template/utility/TemplateModelUtils.java b/src/main/java/freemarker/template/utility/TemplateModelUtils.java
index be38312..aaadb33 100644
--- a/src/main/java/freemarker/template/utility/TemplateModelUtils.java
+++ b/src/main/java/freemarker/template/utility/TemplateModelUtils.java
@@ -39,6 +39,7 @@ import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateModelIterator;
 import freemarker.template.TemplateScalarModel;
+import freemarker.template._TemplateAPI;
 
 /**
  * Static utility method related to {@link TemplateModel}-s that didn't fit elsewhere.
@@ -248,7 +249,7 @@ public final class TemplateModelUtils {
         private void initKeys() throws TemplateModelException {
             if (keys == null) {
                 Set<String> keySet = new HashSet<String>();
-                SimpleSequence keySeq = new SimpleSequence((ObjectWrapper) null);
+                SimpleSequence keySeq = new SimpleSequence(_TemplateAPI.SAFE_OBJECT_WRAPPER);
                 for (TemplateHashModelEx hash : hashes) {
                     addKeys(keySet, keySeq, hash);
                 }
@@ -271,7 +272,7 @@ public final class TemplateModelUtils {
 
         private void initValues() throws TemplateModelException {
             if (values == null) {
-                SimpleSequence seq = new SimpleSequence(size(), null);
+                SimpleSequence seq = new SimpleSequence(size(), _TemplateAPI.SAFE_OBJECT_WRAPPER);
                 // Note: size() invokes initKeys() if needed.
             
                 int ln = keys.size();
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index a2732b6..f736f8a 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -28925,6 +28925,16 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
                 <literal>ObjectWrapper</literal> implementation of
                 course.)</para>
 
+                <para>If you are creating <literal>TemplateModel</literal>-s
+                in custom code (instead of the
+                <literal>ObjectWrapper</literal> creating those), be sure you
+                avoid deprecated container constructors like <literal>new
+                SimpleSequence()</literal>, as those will use the also
+                deprecated default object wrapper instance, which doesn't have
+                the same restrictions than the
+                <literal>ObjectWrapper</literal> you have set on the
+                <literal>Configuration</literal>.</para>
+
                 <para>Also, don't forget about the <link
                 linkend="ref_buitin_api_and_has_api"><literal>?api</literal>
                 built-in</link>, if you have enabled it (it's disabled by
@@ -29244,7 +29254,7 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
               where the caller can provide the <literal>Map</literal> instance
               used as the backing storage, thus allows controlling the
               ordering, and other technical aspects (like the initial
-              capacity) of the underlying <literal>Map</literal>.</para>
+              capacity) of it.</para>
             </listitem>
           </itemizedlist>
         </section>
diff --git a/src/test/java/freemarker/test/templatesuite/models/LegacyList.java b/src/test/java/freemarker/test/templatesuite/models/LegacyList.java
index 06abaca..a02199b 100644
--- a/src/test/java/freemarker/test/templatesuite/models/LegacyList.java
+++ b/src/test/java/freemarker/test/templatesuite/models/LegacyList.java
@@ -24,6 +24,7 @@ import java.util.Iterator;
 import freemarker.template.SimpleSequence;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
+import freemarker.template._TemplateAPI;
 
 /**
  * A little bridge class that subclasses the new SimpleList
@@ -33,6 +34,10 @@ public class LegacyList extends SimpleSequence {
 
     private Iterator iterator;
 
+    public LegacyList() {
+        super(_TemplateAPI.SAFE_OBJECT_WRAPPER);
+    }
+
     /**
      * Resets the cursor to the beginning of the list.
      */
diff --git a/src/test/java/freemarker/test/templatesuite/models/MultiModel1.java b/src/test/java/freemarker/test/templatesuite/models/MultiModel1.java
index f9ac0ca..09d8a71 100644
--- a/src/test/java/freemarker/test/templatesuite/models/MultiModel1.java
+++ b/src/test/java/freemarker/test/templatesuite/models/MultiModel1.java
@@ -19,6 +19,9 @@
 
 package freemarker.test.templatesuite.models;
 
+import freemarker.template.Configuration;
+import freemarker.template.DefaultObjectWrapper;
+import freemarker.template.DefaultObjectWrapperBuilder;
 import freemarker.template.SimpleHash;
 import freemarker.template.SimpleScalar;
 import freemarker.template.SimpleSequence;
@@ -34,19 +37,21 @@ import freemarker.template.TemplateSequenceModel;
 public class MultiModel1 implements TemplateHashModel,
         TemplateSequenceModel, TemplateScalarModel {
 
+    private static final DefaultObjectWrapper DEFAULT_OBJECT_WRAPPER =
+            new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_0).build();
     private TemplateModel m_cSubModel = new MultiModel2();
     private TemplateModel m_cListHashModel1 = new MultiModel4();
     private TemplateModel m_cListHashModel2 = new MultiModel5();
-    private TemplateSequenceModel m_cListModel = new SimpleSequence();
-    private TemplateHashModel m_cHashModel = new SimpleHash();
+    private TemplateSequenceModel m_cListModel = new SimpleSequence(DEFAULT_OBJECT_WRAPPER);
+    private TemplateHashModel m_cHashModel = new SimpleHash(DEFAULT_OBJECT_WRAPPER);
 
     /** Creates new MultiModel1 */
     public MultiModel1() {
         for ( int i = 0; i < 10; i++ ) {
             ((SimpleSequence) m_cListModel).add( "Model1 value: " + Integer.toString( i ));
         }
-        ((SimpleSequence) m_cListModel).add( new MultiModel3() );
-        ((SimpleHash) m_cHashModel).put( "nested", new MultiModel3() );
+        ((SimpleSequence) m_cListModel).add(new MultiModel3());
+        ((SimpleHash) m_cHashModel).put("nested", new MultiModel3());
     }
 
     /**
diff --git a/src/test/java/freemarker/test/templatesuite/models/TransformHashWrapper.java
b/src/test/java/freemarker/test/templatesuite/models/TransformHashWrapper.java
index f3de0a9..f317b18 100644
--- a/src/test/java/freemarker/test/templatesuite/models/TransformHashWrapper.java
+++ b/src/test/java/freemarker/test/templatesuite/models/TransformHashWrapper.java
@@ -24,6 +24,7 @@ import freemarker.template.TemplateHashModel;
 import freemarker.template.TemplateModel;
 import freemarker.template.TemplateModelException;
 import freemarker.template.TemplateScalarModel;
+import freemarker.template._TemplateAPI;
 import freemarker.template.utility.HtmlEscape;
 import freemarker.template.utility.StandardCompress;
 
@@ -33,7 +34,7 @@ import freemarker.template.utility.StandardCompress;
 public class TransformHashWrapper implements TemplateHashModel,
         TemplateScalarModel {
 
-    private SimpleHash m_cHashModel = new SimpleHash();
+    private SimpleHash m_cHashModel = new SimpleHash(_TemplateAPI.SAFE_OBJECT_WRAPPER);
 
     /** Creates new TransformHashWrapper */
     public TransformHashWrapper() {


Mime
View raw message