Skip to content

Commit 4d1e994

Browse files
authored
Merge pull request #20375 from emberjs/docs-SafeString
[DOCS BETA] Document the `SafeString` type
2 parents 3dd057d + 5378cfe commit 4d1e994

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

packages/@ember/-internals/glimmer/lib/utils/string.ts

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,64 @@
44

55
import type { SafeString as GlimmerSafeString } from '@glimmer/runtime';
66

7+
/**
8+
A wrapper around a string that has been marked as safe ("trusted"). **When
9+
rendered in HTML, Ember will not perform any escaping.**
10+
11+
Note:
12+
13+
1. This does not *make* the string safe; it means that some code in your
14+
application has *marked* it as safe using the `htmlSafe()` function.
15+
16+
2. The only public API for getting a `SafeString` is calling `htmlSafe()`. It
17+
is *not* user-constructible.
18+
19+
If a string contains user inputs or other untrusted data, you must sanitize
20+
the string before using the `htmlSafe` method. Otherwise your code is
21+
vulnerable to [Cross-Site Scripting][xss]. There are many open source
22+
sanitization libraries to choose from, both for front end and server-side
23+
sanitization.
24+
25+
[xss]: https://owasp.org/www-community/attacks/DOM_Based_XSS
26+
27+
```javascript
28+
import { htmlSafe } from '@ember/template';
29+
30+
let someTrustedOrSanitizedString = "<div>Hello!</div>"
31+
32+
htmlSafe(someTrustedorSanitizedString);
33+
```
34+
35+
@for @ember/template
36+
@class SafeString
37+
@since 4.12.0
38+
@public
39+
*/
740
export class SafeString implements GlimmerSafeString {
841
private __string: string;
942

1043
constructor(string: string) {
1144
this.__string = string;
1245
}
1346

47+
/**
48+
Get the string back to use as a string.
49+
50+
@public
51+
@method toString
52+
@returns {String} The string marked as trusted
53+
*/
1454
toString(): string {
1555
return `${this.__string}`;
1656
}
1757

58+
/**
59+
Get the wrapped string as HTML to use without escaping.
60+
61+
@public
62+
@method toHTML
63+
@returns {String} the trusted string, without any escaping applied
64+
*/
1865
toHTML(): string {
1966
return this.toString();
2067
}
@@ -115,8 +162,8 @@ export function htmlSafe(str: string): SafeString {
115162
```javascript
116163
import { htmlSafe, isHTMLSafe } from '@ember/template';
117164
118-
var plainString = 'plain string',
119-
safeString = htmlSafe('<div>someValue</div>');
165+
let plainString = 'plain string';
166+
let safeString = htmlSafe('<div>someValue</div>');
120167
121168
isHTMLSafe(plainString); // false
122169
isHTMLSafe(safeString); // true

packages/@ember/string/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ export function htmlSafe(str: string): SafeString {
290290
return internalHtmlSafe(str);
291291
}
292292

293-
export function isHTMLSafe(str: any | null | undefined): str is SafeString {
293+
export function isHTMLSafe(str: unknown): str is SafeString {
294294
deprecateImportFromString('isHTMLSafe');
295295

296296
return internalIsHtmlSafe(str);

tests/docs/expected.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ module.exports = {
509509
'toArray',
510510
'toggleProperty',
511511
'toString',
512+
'toHTML',
512513
'tracked',
513514
'transitionTo',
514515
'transitionToRoute',

0 commit comments

Comments
 (0)