#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use Encode; | |
use utf8; | |
use JSON; | |
use Text::Xslate; | |
use Plack::Request; | |
use Data::Rmap qw//; | |
use Scalar::Util qw(blessed); | |
my $tx = Text::Xslate->new( | |
syntax => 'TTerse', | |
function => { | |
jsgateway => sub { | |
my $hashref = shift; | |
Data::Rmap::rmap_to { | |
Data::Rmap::cut($_) if blessed $_; | |
return if ref $_; | |
$_ = Text::Xslate::unmark_raw(Text::Xslate::html_escape($_)) | |
} Data::Rmap::ALL, $hashref; | |
my $json = JSON->new->ascii->encode($hashref); | |
my $bs = '\\'; | |
$json =~ s!/!${bs}/!g; | |
$json =~ s!<!${bs}u003c!g; | |
$json =~ s!>!${bs}u003e!g; | |
$json =~ s!&!${bs}u0026!g; | |
Text::Xslate::mark_raw($json); | |
}, | |
} | |
); | |
sub { | |
my $env = shift; | |
my $req = Plack::Request->new($env); | |
my $param = { | |
'query' => decode_utf8($req->param('query') // "default foo"), | |
'hoge' => q!&"bar'<b>baz</b>\ / </script>! . qq!\r\nfoo\x{2028}hoge!, | |
'hashref' => { 'a' => 'b', 'c' => 'd', 'e' => { 'f' => 'g' } }, | |
}; | |
return [ | |
200, | |
['Content-Type'=>'text/html; charset=UTF-8'], | |
[encode_utf8($tx->render_string(<<'EOF', | |
<html> | |
<script type="text/javascript"><!--//<![CDATA[ | |
String.prototype.unescapeHTMLx = function () { | |
var temp = document.createElement("div"); | |
temp.innerHTML = this; | |
var result = temp.childNodes[0].nodeValue; | |
temp.removeChild(temp.firstChild); | |
return result; | |
} | |
if (!window['JSGateway']) { | |
window.JSGateway = { | |
_params : {}, | |
getParam:function(key){ | |
var obj = JSGateway; | |
return obj._params[key]; | |
}, | |
setParam:function(value){ | |
var obj = JSGateway; | |
obj._params=value; | |
} | |
}; | |
} | |
JSGateway.setParam([% $js_param | jsgateway %]); | |
//]]>--></script> | |
<body> | |
<script> | |
</script> | |
<br /> | |
<button onclick="alert(JSGateway.getParam('hoge').unescapeHTMLx())">サンプル: unescapeHTML alert</button> | |
<button onclick="document.getElementById('output').innerHTML=JSGateway.getParam('hoge')">サンプル: そのまま innerHTML</button> | |
<button onclick="alert(JSGateway.getParam('query'))">query そのまま alert</button> | |
<button onclick="alert(JSGateway.getParam('query').unescapeHTMLx())">query unescapeHTML alert</button> | |
<button onclick="document.getElementById('output').innerHTML=JSGateway.getParam('query')">query そのまま innerHTML</button> | |
<button onclick="document.getElementById('output').innerHTML=JSGateway.getParam('query').unescapeHTMLx()">query unescapeHTML innerHTML</button> | |
<div id="output">sample</div> | |
</body> | |
</html> | |
EOF | |
{ js_param => $param }, | |
))] | |
]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment