Comparing version 4.0.0-alpha.0 to 4.0.0-alpha.1
@@ -49,3 +49,3 @@ 'use strict'; | ||
if (isSpace(character)) { | ||
if (this.options.allowedTags.has(this.nameBuffer.toLowerCase())) { | ||
if (this.isNameBufferAnAllowedTag()) { | ||
transition(new InTagState(0 /* Allowed */, this.options)); | ||
@@ -64,3 +64,3 @@ return TAG_START + (this.isClosingTag ? "/" : "") + this.nameBuffer + character; | ||
transition(new InPlaintextState(this.options)); | ||
if (this.options.allowedTags.has(this.nameBuffer.toLowerCase())) { | ||
if (this.isNameBufferAnAllowedTag()) { | ||
return TAG_START + (this.isClosingTag ? "/" : "") + this.nameBuffer + character; | ||
@@ -79,2 +79,14 @@ } | ||
} | ||
isNameBufferAnAllowedTag() { | ||
const tagName = this.nameBuffer.toLowerCase(); | ||
if (this.options.allowedTags) { | ||
return this.options.allowedTags.has(tagName); | ||
} | ||
else if (this.options.disallowedTags) { | ||
return !this.options.disallowedTags.has(tagName); | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
} | ||
@@ -148,3 +160,2 @@ class InTagState { | ||
const DefaultStateMachineOptions = { | ||
allowedTags: new Set(), | ||
tagReplacementText: "", | ||
@@ -151,0 +162,0 @@ encodePlaintextTagDelimiters: true, |
declare type QuoteCharacter = '"' | "'"; | ||
export interface StateMachineOptions { | ||
readonly allowedTags: Set<string>; | ||
readonly allowedTags?: Set<string>; | ||
readonly disallowedTags?: Set<string>; | ||
readonly tagReplacementText: string; | ||
@@ -28,2 +29,3 @@ readonly encodePlaintextTagDelimiters: boolean; | ||
consume(character: string, transition: InTagNameStateTransitionFunction): string; | ||
private isNameBufferAnAllowedTag; | ||
} | ||
@@ -30,0 +32,0 @@ declare type InTagStateTransitionFunction<T extends TagMode> = (next: InPlaintextState | InQuotedStringInTagState<T>) => void; |
import { StateMachineOptions } from "./states"; | ||
export { StateMachineOptions } from "./states"; | ||
export declare const DefaultStateMachineOptions: StateMachineOptions; | ||
@@ -3,0 +4,0 @@ export declare class StateMachine { |
@@ -45,3 +45,3 @@ function isSpace(character) { | ||
if (isSpace(character)) { | ||
if (this.options.allowedTags.has(this.nameBuffer.toLowerCase())) { | ||
if (this.isNameBufferAnAllowedTag()) { | ||
transition(new InTagState(0 /* Allowed */, this.options)); | ||
@@ -60,3 +60,3 @@ return TAG_START + (this.isClosingTag ? "/" : "") + this.nameBuffer + character; | ||
transition(new InPlaintextState(this.options)); | ||
if (this.options.allowedTags.has(this.nameBuffer.toLowerCase())) { | ||
if (this.isNameBufferAnAllowedTag()) { | ||
return TAG_START + (this.isClosingTag ? "/" : "") + this.nameBuffer + character; | ||
@@ -75,2 +75,14 @@ } | ||
} | ||
isNameBufferAnAllowedTag() { | ||
const tagName = this.nameBuffer.toLowerCase(); | ||
if (this.options.allowedTags) { | ||
return this.options.allowedTags.has(tagName); | ||
} | ||
else if (this.options.disallowedTags) { | ||
return !this.options.disallowedTags.has(tagName); | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
} | ||
@@ -144,3 +156,2 @@ class InTagState { | ||
const DefaultStateMachineOptions = { | ||
allowedTags: new Set(), | ||
tagReplacementText: "", | ||
@@ -147,0 +158,0 @@ encodePlaintextTagDelimiters: true, |
@@ -12,3 +12,3 @@ { | ||
"bugs": "https://github.com/ericnorris/striptags/issues", | ||
"version": "4.0.0-alpha.0", | ||
"version": "4.0.0-alpha.1", | ||
"keywords": [ | ||
@@ -15,0 +15,0 @@ "striptags", |
@@ -1,5 +0,7 @@ | ||
# striptags (WIP) | ||
# striptags | ||
An implementation of PHP's [strip_tags](https://www.php.net/manual/en/function.strip-tags.php) in Typescript. | ||
**Note:** this is a total rewrite from [v3](https://github.com/ericnorris/striptags/tree/v3.x.x), and as such, is currently in an alpha state. Feel free to use this during the alpha period and provide feedback before it is released as v4. | ||
## Highlights | ||
@@ -13,3 +15,3 @@ | ||
``` | ||
npm install striptags | ||
npm install striptags@alpha | ||
``` | ||
@@ -20,3 +22,2 @@ | ||
```typescript | ||
// commonjs format | ||
striptags(text: string, options?: Partial<StateMachineOptions>): string; | ||
@@ -28,6 +29,6 @@ ``` | ||
```javascript | ||
// commonjs format | ||
// commonjs | ||
const striptags = require("striptags").striptags; | ||
// alternatively: | ||
// alternatively, as an es6 import | ||
// import { striptags } from "striptags"; | ||
@@ -40,4 +41,4 @@ | ||
console.log(striptags(html)); | ||
console.log(striptags(html, {allowedTags: new Set(["strong"])})); | ||
console.log(striptags(html, {tagReplacementText: "🍩"})); | ||
console.log(striptags(html, { allowedTags: new Set(["strong"]) })); | ||
console.log(striptags(html, { tagReplacementText: "🍩" })); | ||
``` | ||
@@ -65,5 +66,6 @@ | ||
```javascript | ||
// commonjs | ||
const StateMachine = require("striptags").StateMachine; | ||
// alternatively: | ||
// alternatively, as an es6 import | ||
// import { StateMachine } from "striptags"; | ||
@@ -73,5 +75,3 @@ | ||
console.log( | ||
instance.consume("some text with <a") + instance.consume("tag>and more text") | ||
); | ||
console.log(instance.consume("some text with <a") + instance.consume("tag>and more text")); | ||
``` | ||
@@ -85,6 +85,32 @@ | ||
## Options | ||
## Safety | ||
* `allowedTags: Set<string>` a set containing a list of tag names to allow (e.g. `new Set(["tagname"])`), default: `new Set([])`. | ||
* `tagReplacementText: string` a string to use as replacement text when a tag is found and not allowed, default: `""`. | ||
* `encodePlaintextTagDelimiters: boolean` true if `<` and `>` characters immediately followed by whitespace should be HTML encoded, default: `true`. This is safe to set to `false` if the output is expected to be used only as plaintext. | ||
`striptags` is safe to use by default; the output is guaranteed to be free of potential XSS vectors if used as text within a tag. **Specifying either `allowedTags` or `disallowedTags` in the options argument removes this guarantee**, however. For example, a malicious user may achieve XSS via an attribute in an allowed tag: `<img onload="alert(1);">`. | ||
In addition, `striptags` will automatically HTML encode `<` and `>` characters followed by whitespace. While most browsers tested treat `<` or `>` followed by whitespace as a non-tag string, it is safer to escape the characters. You may change this behavior via the `encodePlaintextTagDelimiters` option described below. | ||
## `Partial<StateMachineOptions>` | ||
**`allowedTags?: Set<string>`** | ||
A set containing a list of tag names to allow (e.g. `new Set(["tagname"])`). Tags not in this list will be removed. This option takes precedence over the `disallowedTags` option. | ||
Default: `undefined` | ||
**`disallowedTags?: Set<string>`** | ||
A set containing a list of tag names to disallow ((e.g. `new Set(["tagname"])`). Tags not in this list will be allowed. Ignored if `allowedTags` is set. | ||
Default: `undefined` | ||
**`tagReplacementText?: string`** | ||
A string to use as replacement text when a tag is found and not allowed. | ||
Default: `""` | ||
**`encodePlaintextTagDelimiters?: boolean`** | ||
Setting this option to true will cause `<` and `>` characters immediately followed by whitespace to be HTML encoded. This is safe to set to `false` if the output is expected to be used only as plaintext (i.e. it will not be displayed alongside other HTML). | ||
Default: `true` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
19694
413
110
0