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 <[email protected]>
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() {