The real problem here (which comes up again and again) is that
spring.message is not a function on the first place. Or, maybe
function and macro for convenience, but I belive that the base case
should be that it's a function.

But certainly you don't want to patch that. But you could do the same,
i.e., call the function from the macro, and not the other way around.


Tuesday, April 10, 2018, 12:34:19 PM, Riehemann, Michael wrote:

> Hi Daniel,
>
> thank you for your answer. 
>
> The real usage is a little bit different but with the same result.
> We're using Spring in our software and added a macro to simplify and
> unify the usage of the spring.messageText and spring.messageArgs
> macros. And since our messageKeys could include HTML we set the
> outputformat to plaintext (default is HTML).
>
> <#outputformat "plainText">
>   <#macro message key args=[]>
>     <#compress>
>       <#if key?has_content>
>         <#if args?has_content>
>           <#local messageText><@spring.messageArgs key args/></#local>
>         <#else>
>           <#local messageText><@spring.message key/></#local>
>         </#if>
>         ${messageText}
>       </#if>
>     </#compress>
>   </#macro>
> </#outputformat>
>
> But we also need this as a return value for other usecases, so we
> added a small wrapper as function:
>
> <#outputformat "plainText">
> <#function getMessage key args=[]>
>   <#local result><@message key=key args=args /></#local>
>   <#return result />
> </#function>
> </#outputformat>
>
> And this causes the problem with the escaping, since it wasn't
> clear to us that the output format is fixed.
>
> --Michael
>
> -----Ursprüngliche Nachricht-----
> Von: Daniel Dekany [mailto:ddek...@apache.org] 
> Gesendet: Montag, 9. April 2018 16:14
> An: Riehemann, Michael <dev@freemarker.apache.org>
> Betreff: Re: Autoescaping
>
> Output formats works the same with both #function and #macro. What
> causes the difference in your case is that you *call* another macro
> from that function. You could call it from a macro as well with
> similar conclusion, but you have printed the output directly there.
> The output format of the body of the called macro is fixed on parse
> time. Imagine it as if the parser (where parsing happens when the
> template is first loaded, earlier than template execution), it
> modifies ${foo} to ${foo?esc('HTML')} for you (it doesn't, but it's
> something similar). It's not dynamic. It saves you typing and
> prevents human errors exploitable for XSS attack. See also this from the page 
> your have linked:
>
>   Basically, each position in a template has an associated output
>   format, and as you saw above, it might not be the same everywhere in
>   the template. This association sticks to the positions and won't
>   change as the template executes. So if, for example, you call a
>   macro from inside an outputformat block and the called macro is
>   defined outside that block, it won't get the output format of it.
>   Or, if you have a macro that's defined in a template with HTML
>   output format, no mater from where you call it, that macro will
>   always execute with HTML output format. This is like if you were
>   coloring each characters of the template files by output format in
>   the text editor, and then later when the templates are executed, it
>   only considers the color of the statement being executed. This gives
>   you firm control over the output format and hence escaping; you
>   don't have to consider the possible execution paths that can lead to
>   a point.
>
> Also, I'm curious what use case do you have for dynamic escaping. I
> mean, I see your example, why, in the real world do you need something like 
> that?
>
>
> Monday, April 9, 2018, 2:44:36 PM, Riehemann, Michael wrote:
>
>> Hi Freemarker Devs,
>>
>> I have a question about the Autoescaping and the outputformat, 
>> https://freemarker.apache.org/docs/dgui_misc_autoescaping.html
>>
>> Examplecode:
>>
>> <#ftl output_format="HTML">
>>
>> <#outputformat "plainText">
>> <#function testFunction>
>> <#local result><@testMacro /></#local> <#return result /> </#function> 
>> </#outputformat>
>>
>> <#outputformat "plainText">
>> <#macro testMacro>
>> &
>> </#macro>
>> </#outputformat>
>>
>> Test Function: ${testFunction()}
>> Test Macro: <@testMacro/>
>>
>> Output:
>>
>> Test Function: &amp;
>> Test Macro: &
>>
>> It looks like outputformat is not working surrounding a function.
>> The simplest fix is to add ?no_esc to the call:
>> ${testFunction()?no_esc}
>>
>> But we have a lot of calls of this function and don't want to change all 
>> templates.
>>
>> So I tried this code (without outputformat):
>>
>> <#ftl output_format="HTML">
>>
>> <#function testFunction>
>> <#local result><@testMacro /></#local> <#return result /> </#function>
>>
>> <#outputformat "plainText">
>> <#macro testMacro>
>> &
>> </#macro>
>> </#outputformat>
>>
>> Test Function: ${testFunction()}
>> Test Macro: <@testMacro/>
>>
>> Output:
>>
>> Test Function: &
>> Test Macro: &
>>
>> Why does it work without the ouputformat surrounding the function?
>> Or maybe, why does the outputformat do the opposite to the function?
>>
>> Thank you,
>> Michael Riehemann
>
> --
> Thanks,
>  Daniel Dekany
>
>

-- 
Thanks,
 Daniel Dekany

Reply via email to