I use the combination of the 2 following filters to first strip all the HTML from the user input from obvious reasons(preventing attacks), and than replace all the \n in
tags.
<span data-ng-bind-html-unsafe="model.userInput | noHTML | newlines"></span>
filters.filter('newlines', function () {
return function(text) {
console.log(text)
return text.replace(/\n/g, '<br/>');
}
})
filters.filter('noHTML', function () {
return function(text) {
return Boolean(text) ? text
.replace(/&/g, '&')
.replace(/>/g, '>')
.replace(/</g, '<') : '';
}
});
the problem is that in angular 1.2.2 bind-html-unsafe is deprecated, and you must use $sce (strict contextual escaping) to 'trust the html', which returns a function, on which I obviously cannot apply those filters.
new code:
ctrls.controllers('someCtrl', function($scope, $sce){
$scope.trusterInput = $sce.trustAsHtml($scope.userInput);
});
Error:
TypeError: Object [object Object] has no method 'replace'
at Scope.<anonymous> (http://localhost:8000/js/filters.js:20:20)
at fnInvoke (http://code.angularjs.org/1.2.2/angular.js:9756:21)
at OPERATORS.| (http://code.angularjs.org/1.2.2/angular.js:9271:59)
at extend.constant (http://code.angularjs.org/1.2.2/angular.js:9701:14)
at OPERATORS.| (http://code.angularjs.org/1.2.2/angular.js:9271:74)
at extend.constant (http://code.angularjs.org/1.2.2/angular.js:9701:14)
at Object.getStringValue (http://code.angularjs.org/1.2.2/angular.js:16990:41)
at Scope.$digest (http://code.angularjs.org/1.2.2/angular.js:11494:47)
at Scope.$apply (http://code.angularjs.org/1.2.2/angular.js:11740:24)
at http://code.angularjs.org/1.2.2/angular.js:13265:36
Obviously becasue $sce returns a function and not a primitive(value of 'text'):
TrustedValueHolderType {$$unwrapTrustedValue: function, $$unwrapTrustedValue: function, valueOf: function, toString: function, valueOf: function…}
$$unwrapTrustedValue: function () {
arguments: (...)
get arguments: function ThrowTypeError() { [native code] }
set arguments: function ThrowTypeError() { [native code] }
caller: (...)
get caller: function ThrowTypeError() { [native code] }
set caller: function ThrowTypeError() { [native code] }
length: 0
name: ""
prototype: Object
__proto__: function Empty() {}
<function scope>
__proto__: TrustedValueHolderType
Any ide on how to solve this, beside calling my filters programmatically before the $sce, which is hardly the Angular way of doing things
Instead of writing your own HTML escaper, just let the auto-escaper do it for you, and instead of replacing newlines with <br>
just use the CSS property white-space: pre
.
TypeError: Object [object Object] has no method 'replace'
at Scope.<anonymous> (http://localhost:8000/js/filters.js:20:20)
occurs because text
is not a string -- the contextual auto-escaper has already done the first step for you, and converted the string to a privileged SCE safe HTML value.
$sce.trustAsHtml($scope.userInput)
is risky. Echoing a naïve user's input back to them as HTML can be dangerous if they are being socially engineered to copy/paste text that really comes from an attacker.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With