1. David Black
  2. atlassian-soy-templates

Commits

David Black  committed 3f14414

html escape the value arguments to getText calls and inform soy that the getText content does not need to be escaped through the use of the SanitizedContent class.

Signed-off-by: David Black <dblack@atlassian.com>

  • Participants
  • Parent commits 4f455db
  • Branches gettext_escaping_demo_hack

Comments (0)

Files changed (2)

File soy-template-plugin/src/main/java/com/atlassian/soy/impl/functions/GetTextFunction.java

View file
  • Ignore whitespace
 package com.atlassian.soy.impl.functions;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.regex.Matcher;
 import com.google.common.collect.Iterables;
 import com.google.inject.Singleton;
 import com.google.template.soy.base.SoySyntaxException;
+import com.google.template.soy.data.SanitizedContent;
 import com.google.template.soy.data.SoyData;
 import com.google.template.soy.data.restricted.NullData;
 import com.google.template.soy.data.restricted.StringData;
 import com.google.template.soy.jssrc.restricted.SoyJsSrcFunction;
 import com.google.template.soy.tofu.restricted.SoyTofuFunction;
 
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
         {
             throw new SoySyntaxException("Argument to getText() is not a literal string");
         }
-
-        List<SoyData> params = args.subList(1, args.size());
+        CharEscaper htmlEscaper = CharEscapers.htmlEscaper();
+        ArrayList<SoyData> params = new ArrayList<SoyData>();
+        for (SoyData arg : args.subList(1, args.size()))
+        {
+            params.add(StringData.forValue(htmlEscaper.escape(arg.toString())));
+        }
         StringData stringData = (StringData) data;
         String text = i18nResolver.getText(stringData.getValue(), transformSoyDataListToSerializableArray(params));
-        return StringData.forValue(text);
+        return new SanitizedContent(text, SanitizedContent.ContentKind.HTML);
     }
 
     private Serializable[] transformSoyDataListToSerializableArray(List<SoyData> params)

File soy-template-plugin/src/test/java/com/atlassian/soy/impl/functions/GetTextFunctionTest.java

View file
  • Ignore whitespace
 import org.junit.runner.RunWith;
 import org.mockito.Matchers;
 import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
 
 import java.io.Serializable;
+import java.text.MessageFormat;
 import java.util.Arrays;
 
 import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.*;
 
 @RunWith(MockitoJUnitRunner.class)
 public class GetTextFunctionTest {
         function.computeForTofu(Arrays.<SoyData>asList(StringData.forValue("ma.key"), StringData.forValue("blah")));
         verify(i18nResolver).getText("ma.key", "blah");
     }
+
+    @Test
+    public void testComputeForTofuGetTextValueArgumentsAreEscaped() throws Exception
+    {
+        final String formatString = "<a href=\"{0}\"> {1} </a>";
+        when(i18nResolver.getText(anyString(), Matchers.<Serializable>anyVararg())).thenAnswer(new Answer<Object>()
+        {
+            @Override
+            public Object answer(InvocationOnMock invocation)
+            {
+                Object[] arguments = java.util.Arrays.copyOfRange(invocation.getArguments(), 1, invocation.getArguments().length);
+                return MessageFormat.format(formatString, arguments);
+            }
+        });
+        SoyData tofu = function.computeForTofu(Arrays.<SoyData>asList(StringData.forValue("ma.key"), StringData.forValue("bl<>ah")));
+        verify(i18nResolver).getText("ma.key", "bl&lt;&gt;ah");
+    }
+
 }