Escaping JSON string in Sightly - sightly

I have the following Sightly template:
<body>
<script type="application/json" id="test">
[
{
"url": "${test}"
}
]
</script>
</body>
I want to escape the value of 'test' using JSON style escaping. Unfortunately, using context='scriptString' escapes a dash as '\-', which is invalid JSON.
How can I use JSON style escaping on this value?

You need to use context='unsafe' to write JSON like this:
${test # context='unsafe'}

Sightly uses OWASP Encode#forJavascript() for the scriptString context. It seems to be a bug or a missing documentation about escaping dashes.
For URLs you can use context='uri'. For plain text you can use context='text'.

Related

Forward slashes in input object do not render in Handlebars #each partial

When trying to render a Handlebars partial, all the forward slashes in my object render as spaces instead.
My input object is like this:
let mySkills = {
"skills": [
{
"name": "HTML5",
"icon": "/img/HTML5.png"
},
{
"name": "CSS3",
"icon": "/img/CSS3.png"
},
{
"name": "JavaScript",
"icon": "/img/JS.png"
}
]
};
The Handlebars partial is like this (I simplified it for this post. I know it won't look right, but the point is that the output code is incorrect):
Handlebars.registerPartial(
'skillsBullet',
'<ul>{{#each skills}}<li style="background-image: url("{{icon}}");">{{name}}</li>{{/each}}</ul>'
);
$('#skills-container').append(Handlebars.compile($('#skills-template').html())(mySkills));
But the output snippet is like this:
Broken background image url
Here is a Codepen. You can inspect the Elements panel to see the bug in the above screenshot: https://codepen.io/car1sle/pen/NWYJeee
I already tried:
Putting backslashes before the forward slashes in the object like this "icon": "\/img\/HTML5.png"
Doing triple curly braces in the Partial like this {{{icon}}}
Doing regular brackets inside the braces in the Partial like this {{[icon]}}
Your issue is due to the fact that your resultant HTML is malformed.
Let's examine this piece of your partial:
<li style="background-image: url("{{icon}}");">
You are using double-quotes (") to wrap both the style= value and the url() value. After Handlebars processing, the resultant HTML becomes:
<li style="background-image: url("/img/CSS3.png");">
This HTML instructs the browser that the style value - between the two double-quotes - is background-image: url(. The browser then tries to determine what to do with the /img/CSS3.png");" and it, because browsers are forgiving of malformed HTML, it ignores it and carries on.
In order to get your code to work properly, you will need to use different quotes for the background-image URL than you use for the style attribute.
<li style="background-image: url(\'{{icon}}\');">
I have forked for your Codepen to provide an example.

How to display URLs from an HTML string in Angular Dart?

I'm trying to get Angular Dart to display a link in a tag from an HTML string.
At first, I tried to just set the inner HTML of the container to be the HTML string, but that didn't work, so I then I tried to use Dart's DomSanitizationService class, but that also doesn't seem to work.
What I have so far is
Dart:
class SomeComponent {
final DomSanitizationService sanitizer;
SafeUrl some_url;
SomeComponent(this.sanitizer) {
some_url = this.sanitizer.bypassSecurityTrustUrl('https://www.google.com');
}
String html_string = '''
<a [href]="some_url">Hi</a>
''';
String get Text => html_string;
}
HTML:
<div [innerHTML]="Text"></div>
The error I'm getting is Removing disallowed attribute <A [href]="some_url">. The text Hi seems to show, but there is no link anymore.
Just as you bypassed URL sanitanization, you have to bypass HTML sanitanization as well using bypassSecurityTrustHtml to return markup.
https://angular.io/api/platform-browser/DomSanitizer#bypassSecurityTrustHtml

How to pass html parameter in Google Closure Template

Guys I want to pass a parameter that contains html characters in Google Closure Template, but all I get is literal html texts. How to do this?
What I have tried so far is this :
{template .modal autoescape="strict" kind="html"}
{$html_content}
{/template}
I have been reading this but it's not very helpful. Thanks
{template .modal}
{$html_content |noAutoescape}
{/template}
Is going to print your HTML. But consider that using |noAutoescape in your templates is discouraged.
Discouraged: It's easy to accidentally introduce XSS attacks when the assertion
that content is safe is far away from where it is created. Instead,
wrap content as sanitized content where it is created and easy to
demonstrate safety.– Google Closure Templates Functions and Print Directives
Or if you are sure $html_content is "safe" HTML, you can ordain it right where you pass parameters to the template:
goog.require('soydata.VERY_UNSAFE');
goog.require('template.namespace');
var container = document.getElementById('modal');
var html = '<strong>HTML you trust!</strong>';
container.innerHTML = template.namespace.modal({
html_content: soydata.VERY_UNSAFE.ordainSanitizedHtml(html);
});
Then your initial template is going to print HTML as it is:
/**
* #param html_content HTML markup
*/
{template .modal autoescape="strict" kind="html"}
{$html_content}
{/template}

BeautifulSoup: parse only part of the page

I want to parse a part of html page, say
my_string = """
<p>Some text. Some text. Some text. Some text. Some text. Some text.
Link1
Link2
</p>
<img src="image.png" />
<p>One more paragraph</p>
"""
I pass this string to BeautifulSoup:
soup = BeautifulSoup(my_string)
# add rel="nofollow" to <a> tags
# return comment to the template
But during parsing BeautifulSoup adds <html>,<head> and <body> tags (if using lxml or html5lib parsers), and I don't need those in my code. The only way I've found up to now to avoid this is to use html.parser.
I wonder if there is a way to get rid of redundant tags using lxml - the quickest parser.
UPDATE
Originally my question was asked incorrectly. Now I removed <div> wrapper from my example, since common user does not use this tag. For this reason we cannot use .extract() method to get rid of <html>, <head> and <body> tags.
Use
soup.body.renderContents()
lxml will always add those tags, but you can use Tag.extract() to remove your <div> tag from inside them:
comment = soup.body.div.extract()
I could solve the problem using .contents property:
try:
children = soup.body.contents
string = ''
for child in children:
string += str(item)
return string
except AttributeError:
return str(soup)
I think that ''.join(soup.body.contents) would be more neat list to string converting, but this does not work and I get
TypeError: sequence item 0: expected string, Tag found

How to convert domain names with greek characters to an ascii URL?

For example:
When typing παιχνιδια.com into Firefox, it is automatically converted to xn--kxadblxczv9d.com
Please suggest a tool for making such a conversion.
One of the easiest is this. Converts and checks for availability at the same time.
If you want to do it inside your browser, save the code in this answer as puny.js and the code below to puny.html, then load the file in your browser.
<html>
<title>Punyconverter</title>
<script type="text/javascript" src="puny.js"></script>
<style type="text/css">
input {width:300px;}
label {width:100px; display:inline-block;}
</style>
<script type="text/javascript">
onload = function( ) {
var ASCII = document.getElementById("ASCII");
var Unicode = document.getElementById("Unicode");
var Input = document.getElementById("Input");
Input.onkeyup=function(){
ASCII.value = punycode.ToASCII( this.value);
Unicode.value = punycode.ToUnicode( this.value);
}
};
</script>
</html>
<body>
<h1>Convert puny coded IDN</h1>
<div><label for="Input">Input</label><input id="Input" type="text"></div>
<div><label for="ASCII">ASCII</label><input id="ASCII" type="text" readonly="readonly"></div>
<div><label for="Unicode">Unicode</label><input id="Unicode" type="text" readonly="readonly"></div>
</body>
You can use any tool that supports "Libidn". A quick search showed SimpleDNS might be of help to you.
There are heaps of converters for IDN online, if that's enough for you, you can use one of them.
Internationalized domain name (i.e. domain names with non-ASCII characters) are encoded using the Punycode system.
You encode and decode IDNA with Python:
>>> print u'παιχνιδια'.encode('idna')
xn--mxaaitabzv9d
>>> print 'xn--mxaaitabzv9d'.decode('idna')
παιχνιδια
The standard modules in Perl also in Apache can do it with the URI module.
use URI;
#insert sitename in next:
$sitename = "..";
my $uri = URI->new( $sitename,'http');
if ($uri->scheme) { print $uri; }

Resources