mirror of
https://github.com/discourse/discourse.git
synced 2025-01-30 22:33:59 +08:00
FIX: remove dangerous support for style/background attributes in polls
This commit is contained in:
parent
fdbcc31a9c
commit
a3fb2c002c
|
@ -1,6 +1,6 @@
|
||||||
export default Em.Component.extend({
|
export default Em.Component.extend({
|
||||||
tagName: "li",
|
tagName: "li",
|
||||||
attributeBindings: ["data-poll-option-id", "data-poll-selected", "style"],
|
attributeBindings: ["data-poll-option-id", "data-poll-selected"],
|
||||||
|
|
||||||
"data-poll-option-id": Em.computed.alias("option.id"),
|
"data-poll-option-id": Em.computed.alias("option.id"),
|
||||||
|
|
||||||
|
@ -8,14 +8,6 @@ export default Em.Component.extend({
|
||||||
return this.get("option.selected") ? "selected" : false;
|
return this.get("option.selected") ? "selected" : false;
|
||||||
}.property("option.selected"),
|
}.property("option.selected"),
|
||||||
|
|
||||||
style: function() {
|
|
||||||
var styles = [];
|
|
||||||
if (this.get("color")) { styles.push("color:" + this.get("color")); }
|
|
||||||
if (this.get("background")) { styles.push("background:" + this.get("background")); }
|
|
||||||
|
|
||||||
return (styles.length > 0 ? styles.join(";") : '').htmlSafe();
|
|
||||||
}.property("color", "background"),
|
|
||||||
|
|
||||||
render(buffer) {
|
render(buffer) {
|
||||||
buffer.push(this.get("option.html"));
|
buffer.push(this.get("option.html"));
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,19 +3,14 @@ export default Em.Component.extend({
|
||||||
classNames: ["results"],
|
classNames: ["results"],
|
||||||
|
|
||||||
options: function() {
|
options: function() {
|
||||||
const voters = this.get("poll.voters"),
|
const voters = this.get("poll.voters");
|
||||||
backgroundColor = this.get("poll.background");
|
|
||||||
|
|
||||||
this.get("poll.options").forEach(option => {
|
this.get("poll.options").forEach(option => {
|
||||||
const percentage = voters === 0 ? 0 : Math.floor(100 * option.get("votes") / voters),
|
const percentage = voters === 0 ? 0 : Math.floor(100 * option.get("votes") / voters);
|
||||||
styles = ["width: " + percentage + "%"];
|
|
||||||
|
|
||||||
if (backgroundColor) { styles.push("background: " + backgroundColor); }
|
|
||||||
|
|
||||||
option.setProperties({
|
option.setProperties({
|
||||||
percentage,
|
percentage,
|
||||||
title: I18n.t("poll.option_title", { count: option.get("votes") }),
|
title: I18n.t("poll.option_title", { count: option.get("votes") })
|
||||||
style: styles.join(";").htmlSafe()
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="bar-back">
|
<td colspan="2" class="bar-back">
|
||||||
<div class="bar" style={{option.style}}></div>
|
<div class="bar"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
{{else}}
|
{{else}}
|
||||||
<ul>
|
<ul>
|
||||||
{{#each option in poll.options}}
|
{{#each option in poll.options}}
|
||||||
{{poll-option option=option color=poll.color background=poll.background toggle="toggleOption"}}
|
{{poll-option option=option toggle="toggleOption"}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
const DATA_PREFIX = "data-poll-";
|
const DATA_PREFIX = "data-poll-";
|
||||||
const DEFAULT_POLL_NAME = "poll";
|
const DEFAULT_POLL_NAME = "poll";
|
||||||
|
|
||||||
const WHITELISTED_ATTRIBUTES = ["type", "name", "min", "max", "step", "order", "color", "background", "status"];
|
const WHITELISTED_ATTRIBUTES = ["type", "name", "min", "max", "step", "order", "status"];
|
||||||
const WHITELISTED_STYLES = ["color", "background"];
|
|
||||||
|
|
||||||
const ATTRIBUTES_REGEX = new RegExp("(" + WHITELISTED_ATTRIBUTES.join("|") + ")=['\"]?[^\\s\\]]+['\"]?", "g");
|
const ATTRIBUTES_REGEX = new RegExp("(" + WHITELISTED_ATTRIBUTES.join("|") + ")=['\"]?[^\\s\\]]+['\"]?", "g");
|
||||||
|
|
||||||
|
@ -81,21 +80,9 @@
|
||||||
|
|
||||||
// TODO: remove non whitelisted content
|
// TODO: remove non whitelisted content
|
||||||
|
|
||||||
// generate <li> styles (if any)
|
// add option id (hash)
|
||||||
var styles = [];
|
|
||||||
WHITELISTED_STYLES.forEach(function(style) {
|
|
||||||
if (attributes[DATA_PREFIX + style]) {
|
|
||||||
styles.push(style + ":" + attributes[DATA_PREFIX + style]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var style = styles.join(";");
|
|
||||||
|
|
||||||
// add option id (hash) + style
|
|
||||||
for (o = 1; o < contents[0].length; o++) {
|
for (o = 1; o < contents[0].length; o++) {
|
||||||
var attr = {};
|
var attr = {};
|
||||||
// apply styles if any
|
|
||||||
if (style.length > 0) { attr["style"] = style; }
|
|
||||||
// compute md5 hash of the content of the option
|
// compute md5 hash of the content of the option
|
||||||
attr[DATA_PREFIX + "option-id"] = md5(JSON.stringify(contents[0][o].slice(1)));
|
attr[DATA_PREFIX + "option-id"] = md5(JSON.stringify(contents[0][o].slice(1)));
|
||||||
// store options attributes
|
// store options attributes
|
||||||
|
@ -178,6 +165,4 @@
|
||||||
Discourse.Markdown.whiteListTag("a", "class", /^button (cast-votes|toggle-results)/);
|
Discourse.Markdown.whiteListTag("a", "class", /^button (cast-votes|toggle-results)/);
|
||||||
|
|
||||||
Discourse.Markdown.whiteListTag("li", "data-*");
|
Discourse.Markdown.whiteListTag("li", "data-*");
|
||||||
Discourse.Markdown.whiteListTag("li", "style", /^(color=#?\w+;)?(background=#?\w+;)?$/);
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user