Skip to content

Commit

Permalink
[BUGFIX beta] Change style deprecation to warning.
Browse files Browse the repository at this point in the history
  • Loading branch information
rwjblue committed Mar 25, 2015
1 parent 60f53a3 commit 31e61f1
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 46 deletions.
68 changes: 48 additions & 20 deletions packages/ember-htmlbars/tests/attr_nodes/style_test.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,78 @@
/* globals EmberDev */

import Ember from "ember-metal/core";
import EmberView from "ember-views/views/view";
import compile from "ember-template-compiler/system/compile";
import { SafeString } from "ember-htmlbars/utils/string";
import { runAppend, runDestroy } from "ember-runtime/tests/utils";
import { styleWarning } from "ember-views/attr_nodes/attr_node";

var view;
var view, originalWarn, warnings;

QUnit.module("ember-htmlbars: style attribute", {
setup() {
warnings = [];
originalWarn = Ember.warn;
Ember.warn = function(message, test) {
if (!test) {
warnings.push(message);
}
};
},

teardown() {
runDestroy(view);
Ember.warn = originalWarn;
}
});

if (Ember.FEATURES.isEnabled('ember-htmlbars-attribute-syntax')) {
// jscs:disable validateIndentation

QUnit.test('specifying `<div style="width: {{userValue}}></div>` is [DEPRECATED]', function() {
view = EmberView.create({
userValue: '42',
template: compile('<div style="width: {{view.userValue}}"></div>')
});
if (!EmberDev.runningProdBuild) {
QUnit.test('specifying `<div style={{userValue}}></div>` generates a warning', function() {
view = EmberView.create({
userValue: 'width: 42px',
template: compile('<div style={{view.userValue}}></div>')
});

expectDeprecation(function() {
runAppend(view);
}, /Dynamic content in the `style` attribute is not escaped and may pose a security risk. Please perform a security audit and once verified change from `<div style="foo: {{property}}">` to `<div style="foo: {{{property}}}">/);
});

QUnit.test('specifying `<div style="width: {{{userValue}}}></div>` works properly', function() {
view = EmberView.create({
userValue: '42',
template: compile('<div style="width: {{view.userValue}}"></div>')
deepEqual(warnings, [styleWarning]);
});

expectNoDeprecation(function() {
QUnit.test('specifying `attributeBindings: ["style"]` generates a warning', function() {
view = EmberView.create({
userValue: 'width: 42px',
template: compile('<div style={{view.userValue}}></div>')
});

runAppend(view);

deepEqual(warnings, [styleWarning]);
});
});
}

QUnit.test('specifying `<div style="width: {{userValue}}></div>` works properly with a SafeString', function() {
QUnit.test('specifying `<div style={{{userValue}}}></div>` works properly without a warning', function() {
view = EmberView.create({
userValue: new SafeString('42'),
template: compile('<div style="width: {{view.userValue}}"></div>')
userValue: 'width: 42px',
template: compile('<div style={{{view.userValue}}}></div>')
});

expectNoDeprecation(function() {
runAppend(view);
runAppend(view);

deepEqual(warnings, [ ]);
});

QUnit.test('specifying `<div style={{userValue}}></div>` works properly with a SafeString', function() {
view = EmberView.create({
userValue: new SafeString('width: 42px'),
template: compile('<div style={{view.userValue}}></div>')
});

runAppend(view);

deepEqual(warnings, [ ]);
});

// jscs:enable validateIndentation
Expand Down
46 changes: 31 additions & 15 deletions packages/ember-htmlbars/tests/helpers/bind_attr_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/*globals EmberDev */
/*jshint newcap:false*/

import Ember from "ember-metal/core"; // Ember.lookup
import run from "ember-metal/run_loop";
import Namespace from "ember-runtime/system/namespace";
Expand All @@ -11,13 +13,15 @@ import { observersFor } from "ember-metal/observer";
import { Registry } from "ember-runtime/system/container";
import { set } from "ember-metal/property_set";
import { runAppend, runDestroy } from "ember-runtime/tests/utils";
import { styleWarning } from "ember-views/attr_nodes/attr_node";
import { SafeString } from "ember-htmlbars/utils/string";

import helpers from "ember-htmlbars/helpers";
import compile from "ember-template-compiler/system/compile";
var view;

var originalLookup = Ember.lookup;
var TemplateTests, registry, container, lookup;
var TemplateTests, registry, container, lookup, warnings, originalWarn;

/**
This module specifically tests integration with Handlebars and Ember-specific
Expand All @@ -35,6 +39,14 @@ QUnit.module("ember-htmlbars: {{bind-attr}}", {
registry.optionsForType('template', { instantiate: false });
registry.register('view:default', _MetamorphView);
registry.register('view:toplevel', EmberView.extend());

warnings = [];
originalWarn = Ember.warn;
Ember.warn = function(message, test) {
if (!test) {
warnings.push(message);
}
};
},

teardown() {
Expand All @@ -43,6 +55,7 @@ QUnit.module("ember-htmlbars: {{bind-attr}}", {
registry = container = view = null;

Ember.lookup = lookup = originalLookup;
Ember.warn = originalWarn;
TemplateTests = null;
}
});
Expand Down Expand Up @@ -600,24 +613,27 @@ QUnit.test("src attribute bound to null is not present", function() {
ok(!view.element.firstChild.hasAttribute('src'), "src attribute not present");
});

QUnit.test('specifying `<div {{bind-attr style=userValue}}></div>` is [DEPRECATED]', function() {
view = EmberView.create({
userValue: '42',
template: compile('<div {{bind-attr style=view.userValue}}></div>')
});
if (!EmberDev.runningProdBuild) {

QUnit.test('specifying `<div {{bind-attr style=userValue}}></div>` triggers a warning', function() {
view = EmberView.create({
userValue: '42',
template: compile('<div {{bind-attr style=view.userValue}}></div>')
});

expectDeprecation(function() {
runAppend(view);
}, /Dynamic content in the `style` attribute is not escaped and may pose a security risk. Please perform a security audit and once verified change from `<div {{bind-attr style=someProperty}}>` to `<div style={{{someProperty}}}>/);
});

QUnit.test('specifying `<div {{{bind-attr style=userValue}}}></div>` works properly', function() {
view = EmberView.create({
userValue: '42',
template: compile('<div {{{bind-attr style=view.userValue}}}></div>')
deepEqual(warnings, [styleWarning]);
});
}

expectNoDeprecation(function() {
runAppend(view);
QUnit.test('specifying `<div {{bind-attr style=userValue}}></div>` works properly with a SafeString', function() {
view = EmberView.create({
userValue: new SafeString('42'),
template: compile('<div {{bind-attr style=view.userValue}}></div>')
});

runAppend(view);

deepEqual(warnings, [ ]);
});
20 changes: 13 additions & 7 deletions packages/ember-views/lib/attr_nodes/attr_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export default function AttrNode(attrName, attrValue) {
this.init(attrName, attrValue);
}

export var styleWarning = 'Binding style attributes may introduce cross-site scripting vulnerabilities; ' +
'please ensure that values being bound are properly escaped. For more information, ' +
'including how to disable this warning, see ' +
'http://emberjs.com/deprecations/v1.x/#toc_warning-when-binding-style-attributes.';

AttrNode.prototype.init = function init(attrName, simpleAttrValue) {
this.isView = true;

Expand All @@ -27,8 +32,6 @@ AttrNode.prototype.init = function init(attrName, simpleAttrValue) {
this.isDestroying = false;
this.lastValue = null;
this.hasRenderedInitially = false;
this._dynamicStyleDeprecationMessage = '`<div style="foo: {{property}}">` to ' +
'`<div style="foo: {{{property}}}">`.';

subscribe(this.attrValue, this.rerender, this);
};
Expand Down Expand Up @@ -76,16 +79,19 @@ AttrNode.prototype.render = function render(buffer) {
};

AttrNode.prototype._deprecateEscapedStyle = function AttrNode_deprecateEscapedStyle(value) {
Ember.deprecate(
'Dynamic content in the `style` attribute is not escaped and may pose a security risk. ' +
'Please perform a security audit and once verified change from ' +
this._dynamicStyleDeprecationMessage,
Ember.warn(
styleWarning,
(function(name, value, escaped) {
// SafeString
if (value && value.toHTML) {
return true;
}
return name !== 'style' || !escaped;

if (name !== 'style') {
return true;
}

return !escaped;
}(this.attrName, value, this._morph.escaped))
);
};
Expand Down
5 changes: 1 addition & 4 deletions packages/ember-views/lib/attr_nodes/legacy_bind.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import o_create from "ember-metal/platform/create";

function LegacyBindAttrNode(attrName, attrValue) {
this.init(attrName, attrValue);

this._dynamicStyleDeprecationMessage = '`<div {{bind-attr style=someProperty}}>` to ' +
'`<div style={{{someProperty}}}>`.';
}

LegacyBindAttrNode.prototype = o_create(AttrNode.prototype);
Expand All @@ -34,7 +31,7 @@ LegacyBindAttrNode.prototype.render = function render(buffer) {
}

Ember.assert(fmt("Attributes must be numbers, strings or booleans, not %@", [value]),
value === null || value === undefined || typeOf(value) === 'number' || typeOf(value) === 'string' || typeOf(value) === 'boolean');
value === null || value === undefined || typeOf(value) === 'number' || typeOf(value) === 'string' || typeOf(value) === 'boolean' || !!(value && value.toHTML));

if (this.lastValue !== null || value !== null) {
this._deprecateEscapedStyle(value);
Expand Down

0 comments on commit 31e61f1

Please sign in to comment.