dust.js turn off HTML encoding globally - dust.js

Is there a way to turn off HTML encoding globally within dust.js? I trust my data enough to want to turn it off during rendering. Instead of having to add "|s" to every tag in every template file, being able to set it globally would be ideal.
If not, is there a way to use filtering with custom helpers? I created a #val helper, but have no way to apply the "|s" filter. According to the docs, the following should work:
{#val filters="|s" /}
But it doesn't work on its own, so I'm thinking some logic needs to be placed within the helper itself.

You can use the little-documented esc pragma to apply a global context to a template block.
{
"hello": "Hello & World"
}
{%esc:s}
This applies |s to everything inside the pragma
{hello} <-- will not escape the ampersand
{/esc}
For your second question, it depends on what your helper is doing. If your helper returns any sort of Chunk, via Chunk.render for example, you must apply filters manually. If your helper returns a value, that value will be passed through any filters that are present. Here are a couple examples: say you have a helper {#val} that simply returns anything passed to it as a value.
Returning a value from your helper means filters is respected:
dust.helpers.val = function(chunk, context, bodies, params) {
return params.value;
};
{#val value="Hello & World" /} <-- Hello & World
{#val value="Hello & World" filters="s" /} <-- Hello & World
Returning a chunk from your helper ignores filters:
dust.helpers.val = function(chunk, context, bodies, params) {
return chunk.write(params.value);
};
{#val value="Hello & World" /} <-- Hello & World

Related

Why does intl.Message need to be wrapped in an enclosing function?

Here the a suggested pattern for using Intl.message I have seen everywhere:
final String learnMoreLabel = _learnMoreLabel; String get
_learnMoreLabel => Intl.message('Learn more',
name: 'HelpContentBase__learnMoreLabel',
desc: 'The label for a link or button which takes the user to the '
'Google Help Center to read more information on a topic.');
Why can't I just write:
final String learnMoreLabel = Intl.message('Learn more',
name: 'HelpContentBase__learnMoreLabel',
desc: 'The label for a link or button which takes the user to the '
'Google Help Center to read more information on a topic.');
Why does it need to be wrapped in the getter? I found this in the docs:
Use this for a message that will be translated for different locales.
The expected usage is that this is inside an enclosing function that
only returns the value of this call and provides a scope for the
variables that will be substituted in the message.
but it doesn't say why.
The short answer is that for that example it probably could be written that way, but it breaks down when there are parameters to the message.
What happens with Intl messages is that the a preprocessor runs over the program and finds all the occurrences of Intl.message and writes them to a file. That file gets sent for translation, and then the translations are run through another program and generate Dart code for each language, which is reachable via the messages_all.dart import.
When you call Intl.message at runtime it looks up the current locale (using the name as a key) and delegates to the appropriate translation, passing along any parameters (via the "args" argument).
When the comment says "provides a scope" it really means that the only things that are allowed to be used in the message are the variables that are provided as arguments to the enclosing function. When there aren't any arguments we could allow the enclosing function to be omitted. It would mean making the parser smart enough to recognize that pattern as well.
As an aside: I don't love the pattern of calling the method once and assigning to a final variable. It sets up a potential race condition between locale initialization and variable initialization and it means the locale can't change at runtime. However, I understand when we have frameworks like Angular that are calling it and comparing the result on every frame that it gets expensive to actually call the function every time.
Another aside: When there are no parameters you can omit the name. It will use the text as a name. When there are parameters the text is an interpolation so it can't use that as the name.

Why does ActionView's "select_tag" escape the HTML in its "options" argument when called directly?

So I've been going through the very poor documentation that exists for ActionView, particularly a method called select_tag that just exists when called from view files. Supposedly, it's called like this:
select_tag name, option_tags, options
The documentation says nothing at all about the name, very little about the options, and describes the option_tags only through examples that treat it as an opaque value that must be obtained from other functions.
As always, the only way to learn anything about Rails is to reverse-engineer it.
So I tried running it directly from a Rails console, which is tricky because Ruby doesn't let you call methods that are defined in modules unless you create a class and an object first:
class H
include ActionView::Helpers::FormOptionsHelper
include ActionView::Helpers::FormTagHelper
end
H.new.options_for_select ["foo","bar"]
The above usage of options_for_select comes from actual code that somebody else wrote. The return value is a string:
"<option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option>"
So apparently, you're supposed to pass the return value from option_for_select (or one of the many other related functions that introduce complications I don't want to talk about such as generating HTML tags from ActiveRecord objects) as the option_tag parameter of select_tag. Except if you copy that string to your clipboard and paste it directly into a function call, it doesn't do what you'd expect:
H.new.select_tag :my_name, "<option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option>"
Return value:
"<select name=\"my_name\" id=\"my_name\"><option value="foo">foo</option>\n<option value="bar">bar</option></select>"
At least this reveals what the name parameter is for.
Even weirder, the text is not escaped if you pass the return value directly to select_tag without letting it print on the console:
H.new.select_tag :name, H.new.options_for_select(["foo","bar"])
Return value:
"<select name=\"name\" id=\"name\"><option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option></select>"
WTF is going on here?
In the course of writing this question, I stumbled on its answer: Ruby has been lying to me (like it always does).
When you evaluate:
H.new.options_for_select ["foo","bar"]
Ruby tells you that the result was a String. But that's only because Pry and Irb both silently call .to_s on everything, and the thing that gets returned from options_for_select has a to_s. The truth:
(H.new.options_for_select ["foo","bar"]).class
=> ActiveSupport::SafeBuffer
ActiveSupport::SafeBuffer.new("<foo>")
=> "<foo>"
So whoever wrote these methods assumed that you want to incorporate raw, user-provided strings into your <select> tags, and those strings could contain attempts at HTML/JavaScript injection, so they must be escaped.
ActiveView treats all strings as suspect, but it is possible to mark certain strings as "safe" by wrapping them in an ActiveSupport::SafeBuffer.

Line break in string returned by a helper method

I have a helper method that returns a string after formatting it, which includes adding line breaks.
I am calling this helper method in a view and am trying to display this formatted string.
I am using "\n" or "\r\n" to introduce line breaks, but this shows up as mere spaces in the browser.
You should use <br> or create it like tag('br'):
your_string = "test string" + tag('br')
your_string.html_safe #return your string
As #max rightly pointed, from a security vulnerability (XSS) aspect you can use h() on user-provided text, which converts your string to a safe string and allows you to securely call html_safe on the full string.
One mistake i made was using raw(string) in the helper method instead of using it in view and it still was shown as 'smth smth' so be aware of that.
My code looked something like this
td= helper_method()
And when I changed it to the following it worked:
td= raw(helper_method())

Razor Syntax clarification

http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvc3razor.aspx
In the above link…..
Code block Foreach
#{
<h3>Team Members</h3> string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
foreach (var person in teamMembers)
{
<p>#person</p>
}
}
why the h3 tag "Team Members" is not throwing the C# error saying not declared? This is inside the code block which says it is a C# code.
All the HTML tags are ignored inside the code block?
Similarly, why # sign in #person? Is it not this code is also inside the code block?
Thank you,
Smith
The # symbol is the heart of the Razor syntax, the character that Razor uses to differentiate code from markup. The # symbol marks a point at which the developer intends to switch from markup to code. In simple cases, no additional characters are needed to indicate when the code stops and the markup resumes. Razor’s intelligent parser determines which parts of the template are code and which are markup. What makes a valid code statement? Razor uses the following algorithm to find the end of a code statement once it reads the # symbol trigger:
Read to the end of a valid identifier (i.e., a C# or VB keyword) or variable name.
If the next character is an opening bracket ( ( or [ )…
a. Keep parsing until the corresponding closing bracket is located. Nested brackets
are also tracked to avoid premature closing of a block.
b. Loop back to #2.
If the next character is a . (period) and precedes a valid identifier, jump to #1.
Complete the code statement and continue processing the rest of the markup.
The reason the #person is there is to tell the Razor view engine that their is a transition between markup and code

Help interpreting this bit of Rails code

What is this?
"#{h params[:chat_input]}"
I am referring to the hash # and the h.
Most likely this is inside a double-quoted string, such as "Ponies all love #{h params[:chat_input]}!" The #{stuff} expression causes the stuff expression to be interpreted and inserted into the string. For example "1 + 2 = #{1 + 2}" will result in the string "1 + 2 = 3".
The h is an alias to the html_escape method, which is pretty self-explanatory.
The code you paste, by itself, is just a comment. I assume the code is inside a string, though.
"hello, #{5 + 5}"
# => hello, 10
The statement inside the brackets will be evaluated as Ruby. This is called string interpolation.
The statement inside the interpolation in your code is a method that gets an argument.
h params[:chat_input]
h(params[:chat_input])
The h method is a shortcut for html_escape, which escapes HTML. For example, <span> is converted into <span>, so that the browser displays the actual contents of the string, instead of interpreting it as HTML.
html_escape(params[:chat_input])
You probably know what params is.
To sum up, you get a HTML escaped version of whatever params[:chat_input] contains.
"#{h params[:chat_input]}"
In ruby, double-quoted strings allow for expressions to be evaluated and automatically converted to strings.
I can do this:
years = 25
"John is " + years + " years old"
but I'll get an error because I can't add the number to a string.
I can do
"John is #{years} years old"
to get around that.
The h() method is a Rails helper function that removes HTML tags. It's a safety thing.
Finally, params() is a method in Rails that gives you access to GET and POST parameters. It's actually wrapping a hash GET and POST parameters are symbolized to reduce memory (symbols are only defined once, whereas a string like "foo" is a new object every time.)
So, params[:chat_input] retrieves the value from the previous request's GET or POST parameters, and in your case it looks like it's just displaying and sanitizing them.
Hope that helps!
It's just interpolating a value inside a string. The :chat_input is a symbol, it's used in place of a string because symbols are only created once.
h(something)
or
h something
since ruby does not force the use of (), is a function available in rails that converts the parameter to a "safe HTML" string avoiding interpreting the possible HTML code inside of the 'something' variable.
"#{x}"
in ruby means converting the x variable to a string and placing it in the new string for example:
"#{host}:#{port}"
will place the value of host and the value of port into the new string formed by the "", in a way that if host is "localhost" and port is 30 the result string will be "localhost:30"
params is a special rails hash that contains the post/get parameters passed to the controller method being executed
another detail is that in ruby a method always returns the last evaluated expression
so the method
def test
"#{h params[:chat_input]}"
end
will return a string that has the HTML-safe value of the post/get parameter chat_input
holy crap, is that from chat_sandbox by any chance?
if so, let me know if you need any help $)
I'm hoping to update that code here soon.

Resources