Skip to content
Permalink
Browse files Browse the repository at this point in the history
[New] [Fix] ensure that all content in tag is properly escaped.
  • Loading branch information
ljharb committed Nov 16, 2016
1 parent de2e69a commit bc01e53
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Expand Up @@ -13,7 +13,7 @@
"indent": [2, 4],
"max-lines": 0,
"max-nested-callbacks": [2, 5],
"max-params": [2, 3],
"max-params": [2, 4],
"max-statements": [2, 20],
"max-statements-per-line": [2, { "max": 2 }],
"new-cap": [2, { "capIsNewExceptions": ["Template"] }],
Expand Down
10 changes: 5 additions & 5 deletions lib/render.js
Expand Up @@ -21,7 +21,7 @@ var wrapWith = function (tagName) {
opt.errorAfterField ? '' : errorHTML,
field.widget.toHTML(name, field),
opt.errorAfterField ? errorHTML : ''
].join(''));
].join(''), true);
wrappedContent.push(fieldset);
} else {
var fieldHTMLs = [field.labelHTML(name, field.id), field.widget.toHTML(name, field)];
Expand All @@ -35,7 +35,7 @@ var wrapWith = function (tagName) {
}
wrappedContent = wrappedContent.concat(fieldHTMLs);
}
return tag(tagName, { classes: field.classes() }, wrappedContent.join(''));
return tag(tagName, { classes: field.classes() }, wrappedContent.join(''), true);
};
};
exports.div = wrapWith('div');
Expand All @@ -45,7 +45,7 @@ exports.li = wrapWith('li');
exports.table = function (name, field, options) {
var opt = options || {};

var th = tag('th', {}, field.labelHTML(name, field.id));
var th = tag('th', {}, field.labelHTML(name, field.id), true);

var tdContent = field.widget.toHTML(name, field);

Expand All @@ -58,7 +58,7 @@ exports.table = function (name, field, options) {
}
}

var td = tag('td', {}, tdContent);
var td = tag('td', {}, tdContent, true);

return tag('tr', { classes: field.classes() }, th + td);
return tag('tr', { classes: field.classes() }, th + td, true);
};
5 changes: 3 additions & 2 deletions lib/tag.js
Expand Up @@ -50,12 +50,13 @@ var isSelfClosing = function (tagName) {
return Object.prototype.hasOwnProperty.call(selfClosingTags, tagName);
};

var tag = function tag(tagName, attrsMap, content) {
var tag = function tag(tagName, attrsMap, content, contentIsEscaped) {
var safeTagName = htmlEscape(tagName);
var attrsHTML = !is.array(attrsMap) ? attrs(attrsMap) : attrsMap.reduce(function (html, map) {
return html + attrs(map);
}, '');
return '<' + safeTagName + attrsHTML + (isSelfClosing(safeTagName) ? ' />' : '>' + content + '</' + safeTagName + '>');
var safeContent = contentIsEscaped ? content : htmlEscape(content);
return '<' + safeTagName + attrsHTML + (isSelfClosing(safeTagName) ? ' />' : '>' + safeContent + '</' + safeTagName + '>');
};

tag.attrs = attrs;
Expand Down
4 changes: 2 additions & 2 deletions lib/widgets.js
Expand Up @@ -117,7 +117,7 @@ var select = function (isMultiple) {
var choices = unifyChoices(f.choices, 1);
var optionsHTML = renderChoices(choices, function render(choice) {
if (choice.isNested) {
return tag('optgroup', { label: choice.label }, renderChoices(choice.choices, render));
return tag('optgroup', { label: choice.label }, renderChoices(choice.choices, render), true);
} else {
return tag('option', { value: choice.value, selected: !!isSelected(f.value, choice.value) }, choice.label);
}
Expand All @@ -130,7 +130,7 @@ var select = function (isMultiple) {
if (isMultiple) {
attrs.multiple = true;
}
return tag('select', [attrs, userAttrs, w.attrs || {}], optionsHTML);
return tag('select', [attrs, userAttrs, w.attrs || {}], optionsHTML, true);
};
return w;
};
Expand Down
10 changes: 10 additions & 0 deletions test/test-widgets.js
Expand Up @@ -256,6 +256,16 @@ test('textarea', function (t) {
'<textarea name="name" id="someid" rows="20" cols="80" class="one two" placeholder="hi!">value</textarea>'
);
t.equal(forms.widgets.textarea().type, 'textarea');

t.test('properly escapes contents', function (st) {
st.equal(
forms.widgets.textarea().toHTML('name', { value: 'Inside</textarea>Escaped the textarea!' }),
'<textarea name="name" id="id_name">Inside&lt;/textarea&gt;Escaped the textarea!</textarea>'
);

st.end();
});

t.end();
});

Expand Down

0 comments on commit bc01e53

Please sign in to comment.