Skip to content
Permalink
Browse files Browse the repository at this point in the history
Added Text Attribute
To help combat XSS attackes the text attribute will add text only to elements rather than html
  • Loading branch information
moappi committed Feb 9, 2018
1 parent 1b66aa2 commit 2d3d24d
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 44 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -28,7 +28,7 @@ Transform (template)
```javascript
var transform =
{"<>": "li", "id":"${id}", "html":[
{"<>": "span", "html": "${name} (${year})"}
{"<>": "span", "text": "${name} (${year})"}
]};
```
Plus JSON Data
Expand Down
16 changes: 0 additions & 16 deletions examples/default.html

This file was deleted.

114 changes: 88 additions & 26 deletions json2html.js
@@ -1,4 +1,4 @@
//Copyright (c) 2016 Crystalline Technologies
//Copyright (c) 2018 Crystalline Technologies
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
Expand Down Expand Up @@ -135,14 +135,61 @@ var json2html = {

switch(key) {

//LEGACY support for tag
//DEPRECATED (use <> instead)
case 'tag':

//HTML element to render
case '<>':
//Do nothing as we have already created the element
break;

//Encode as text
case 'text':
//Get the transform value associated with this key
var _transform = transform[key];

//Determine what kind of object this is
// array => NOT SUPPORTED
// other => text
if(json2html._isArray(_transform)) {
//NOT Supported
} else if(typeof _transform === 'function') {

//Get the result from the function
var temp = _transform.call(obj, obj, index);

//Don't allow arrays as return objects from functions
if(!json2html._isArray(temp)) {

//Determine what type of object was returned
switch(typeof temp){

//Not supported for text
case 'function':
case 'undefined':
case 'object':
break;

//Append as text
// string, number, boolean
default:
//Insure we encode as text first
children.html += json2html.toText(temp);
break;
}
}
} else {

//Get the encoded text associated with this element
html = json2html.toText( json2html._getValue(obj,transform,key,index) );
}
break;

//LEGACY support for children
//DEPRECATED (use HTML instead)
case 'children':

//Encode as HTML
// accepts Array of children, functions, string, number, boolean
case 'html':

//Get the transform value associated with this key
Expand All @@ -160,31 +207,35 @@ var json2html = {

//Get the result from the function
var temp = _transform.call(obj, obj, index);

//Determine what type of object was returned
switch(typeof temp){

//Only returned by json2html.transform or $.json2html calls
case 'object':
//make sure this object is a valid json2html response object
// we ignore all other objects (since we don't know how to represent them in html)
if(temp.html !== undefined && temp.events !== undefined) children = json2html._append(children,temp);
break;

//Not supported
case 'function':
case 'undefined':
break;

//Append to html
// string, number, boolean
default:
children.html += temp;
break;
}

//Don't allow arrays as return objects from functions
if(!json2html._isArray(temp)) {

//Determine what type of object was returned
switch(typeof temp){

//Only returned by json2html.transform or $.json2html calls
case 'object':
//make sure this object is a valid json2html response object
// we ignore all other objects (since we don't know how to represent them in html)
if(temp.html !== undefined && temp.events !== undefined) children = json2html._append(children,temp);
break;

//Not supported
case 'function':
case 'undefined':
break;

//Append to html
// string, number, boolean
default:
children.html += temp;
break;
}
}
} else {

//Create the html attribute for this element
//Get the HTML associated with this element
html = json2html._getValue(obj,transform,key,index);
}
break;
Expand Down Expand Up @@ -319,6 +370,17 @@ var json2html = {

return(out);
},

//Encode the html to text
'toText':function(html) {
return html
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\"/g, '&quot;')
.replace(/\'/g, '&#39;')
.replace(/\//g, '&#x2F;');
},

//Tokenizer
'_tokenizer':function( tokenizers, doBuild ){
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -6,7 +6,7 @@
},
"name": "json2html",
"description": "json2html - HTML Templating",
"version": "1.0.1",
"version": "1.1.0",
"homepage": "http://json2html.com",
"repository": {
"url": "https://github.com/moappi/json2html.git"
Expand Down
17 changes: 17 additions & 0 deletions test/index.html
@@ -0,0 +1,17 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title> json2html tests </title>

<!-- Add JSON2HTML -->
<script type="text/javascript" src="../json2html.js"></script>

</head>
<body>
<!-- Run the tests -->
<script type="text/javascript" src="test.nested.js"></script>
<script type="text/javascript" src="test.shorthand.js"></script>
<script type="text/javascript" src="test.escape.js"></script>
<script type="text/javascript" src="test.text.js"></script>
</body>
</html>
File renamed without changes.
File renamed without changes.
File renamed without changes.
27 changes: 27 additions & 0 deletions test/test.text.js
@@ -0,0 +1,27 @@

(function() {

//Test the handling of quoted strings
var test_data = [
{"text":"<script>alert(0);</script> no alert"},
{"text":"<strong>non highlighted</strong>"},
{"text":"& (ampersand) : ' (single quote) : \" (double quote) "}
];

var transform = [
{"<>":"div", "text":"${text}"},
{"<>":"div","text":[
{"<>":"span","text":"this shouldn't be rendered"}
]},
{"<>":"div", "text":function(){
return(this.text);
}},
{"<>":"div", "text":function(){
return(["not rendered"]);
}}
];

var html = json2html.transform(test_data, transform);

document.write('<h1>Text Encoding Test</h1>'+ html);
})();

0 comments on commit 2d3d24d

Please sign in to comment.