/);
-});
-QUnit.test('specifying `
')
+ deepEqual(warnings, [styleWarning]);
});
- expectNoDeprecation(function() {
+ QUnit.test('specifying `attributeBindings: ["style"]` generates a warning', function() {
+ view = EmberView.create({
+ userValue: 'width: 42px',
+ template: compile('
')
+ });
+
runAppend(view);
+
+ deepEqual(warnings, [styleWarning]);
});
-});
+}
-QUnit.test('specifying `
')
+ userValue: 'width: 42px',
+ template: compile('
')
});
- expectNoDeprecation(function() {
- runAppend(view);
+ runAppend(view);
+
+ deepEqual(warnings, [ ]);
+});
+
+QUnit.test('specifying `
` works properly with a SafeString', function() {
+ view = EmberView.create({
+ userValue: new SafeString('width: 42px'),
+ template: compile('
')
});
+
+ runAppend(view);
+
+ deepEqual(warnings, [ ]);
});
// jscs:enable validateIndentation
diff --git a/packages/ember-htmlbars/tests/helpers/bind_attr_test.js b/packages/ember-htmlbars/tests/helpers/bind_attr_test.js
index 56e951700d3..cdb16513bc3 100644
--- a/packages/ember-htmlbars/tests/helpers/bind_attr_test.js
+++ b/packages/ember-htmlbars/tests/helpers/bind_attr_test.js
@@ -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";
@@ -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
@@ -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() {
@@ -43,6 +55,7 @@ QUnit.module("ember-htmlbars: {{bind-attr}}", {
registry = container = view = null;
Ember.lookup = lookup = originalLookup;
+ Ember.warn = originalWarn;
TemplateTests = null;
}
});
@@ -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 `
` is [DEPRECATED]', function() {
- view = EmberView.create({
- userValue: '42',
- template: compile('
')
- });
+if (!EmberDev.runningProdBuild) {
+
+ QUnit.test('specifying `
` triggers a warning', function() {
+ view = EmberView.create({
+ userValue: '42',
+ template: compile('
')
+ });
- 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 `
` to `
/);
-});
-QUnit.test('specifying `
` works properly', function() {
- view = EmberView.create({
- userValue: '42',
- template: compile('
')
+ deepEqual(warnings, [styleWarning]);
});
+}
- expectNoDeprecation(function() {
- runAppend(view);
+QUnit.test('specifying `
` works properly with a SafeString', function() {
+ view = EmberView.create({
+ userValue: new SafeString('42'),
+ template: compile('
')
});
+
+ runAppend(view);
+
+ deepEqual(warnings, [ ]);
});
diff --git a/packages/ember-views/lib/attr_nodes/attr_node.js b/packages/ember-views/lib/attr_nodes/attr_node.js
index dd1ad181107..3c7836fbe49 100644
--- a/packages/ember-views/lib/attr_nodes/attr_node.js
+++ b/packages/ember-views/lib/attr_nodes/attr_node.js
@@ -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;
@@ -27,8 +32,6 @@ AttrNode.prototype.init = function init(attrName, simpleAttrValue) {
this.isDestroying = false;
this.lastValue = null;
this.hasRenderedInitially = false;
- this._dynamicStyleDeprecationMessage = '`
` to ' +
- '`
`.';
subscribe(this.attrValue, this.rerender, this);
};
@@ -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))
);
};
diff --git a/packages/ember-views/lib/attr_nodes/legacy_bind.js b/packages/ember-views/lib/attr_nodes/legacy_bind.js
index cda3fe51176..7ad2343eb31 100644
--- a/packages/ember-views/lib/attr_nodes/legacy_bind.js
+++ b/packages/ember-views/lib/attr_nodes/legacy_bind.js
@@ -11,9 +11,6 @@ import o_create from "ember-metal/platform/create";
function LegacyBindAttrNode(attrName, attrValue) {
this.init(attrName, attrValue);
-
- this._dynamicStyleDeprecationMessage = '`
` to ' +
- '`
`.';
}
LegacyBindAttrNode.prototype = o_create(AttrNode.prototype);
@@ -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);