diff --git a/README.md b/README.md
index e8b7aedd9..0f57d8a99 100644
--- a/README.md
+++ b/README.md
@@ -183,16 +183,16 @@ Sanitizer | Description
-------------------------------------- | -------------------------------
**blacklist(input, chars)** | remove characters that appear in the blacklist. The characters are used in a RegExp and so you will need to escape some chars, e.g. `blacklist(input, '\\[\\]')`.
**escape(input)** | replace `<`, `>`, `&`, `'`, `"`, `` ` ``, `\` and `/` with HTML entities.
-**ltrim(input [, chars])** | trim characters from the left-side of the input.
+**ltrim(input [, chars])** | trim characters from the left-side of the input. `chars` specifies literal characters, not regular expression ranges.
**normalizeEmail(email [, options])** | canonicalize an email address. (This doesn't validate that the input is an email, if you want to validate the email use isEmail beforehand).
`options` is an object with the following keys and default values:
- *all_lowercase: true* - Transforms the local part (before the @ symbol) of all email addresses to lowercase. Please note that this may violate RFC 5321, which gives providers the possibility to treat the local part of email addresses in a case sensitive way (although in practice most - yet not all - providers don't). The domain part of the email address is always lowercased, as it is case insensitive per RFC 1035.
- *gmail_lowercase: true* - Gmail addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Gmail addresses are lowercased regardless of the value of this setting.
- *gmail_remove_dots: true*: Removes dots from the local part of the email address, as Gmail ignores them (e.g. "john.doe" and "johndoe" are considered equal).
- *gmail_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@gmail.com" becomes "foo@gmail.com").
- *gmail_convert_googlemaildotcom: true*: Converts addresses with domain @googlemail.com to @gmail.com, as they're equivalent.
- *outlookdotcom_lowercase: true* - Outlook.com addresses (including Windows Live and Hotmail) are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Outlook.com addresses are lowercased regardless of the value of this setting.
- *outlookdotcom_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@outlook.com" becomes "foo@outlook.com").
- *yahoo_lowercase: true* - Yahoo Mail addresses are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, Yahoo Mail addresses are lowercased regardless of the value of this setting.
- *yahoo_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "-" sign (e.g. "foo-bar@yahoo.com" becomes "foo@yahoo.com").
- *icloud_lowercase: true* - iCloud addresses (including MobileMe) are known to be case-insensitive, so this switch allows lowercasing them even when *all_lowercase* is set to false. Please note that when *all_lowercase* is true, iCloud addresses are lowercased regardless of the value of this setting.
- *icloud_remove_subaddress: true*: Normalizes addresses by removing "sub-addresses", which is the part following a "+" sign (e.g. "foo+bar@icloud.com" becomes "foo@icloud.com").
-**rtrim(input [, chars])** | trim characters from the right-side of the input.
+**rtrim(input [, chars])** | trim characters from the right-side of the input. `chars` specifies literal characters, not regular expression ranges.
**stripLow(input [, keep_new_lines])** | remove characters with a numerical value < 32 and 127, mostly control characters. If `keep_new_lines` is `true`, newline characters are preserved (`\n` and `\r`, hex `0xA` and `0xD`). Unicode-safe in JavaScript.
**toBoolean(input [, strict])** | convert the input string to a boolean. Everything except for `'0'`, `'false'` and `''` returns `true`. In strict mode only `'1'` and `'true'` return `true`.
**toDate(input)** | convert the input string to a date, or `null` if the input is not a date.
**toFloat(input)** | convert the input string to a float, or `NaN` if the input is not a float.
**toInt(input [, radix])** | convert the input string to an integer, or `NaN` if the input is not an integer.
**toString(input)** | convert the input to a string. `null`, `undefined` and `NaN` are converted to an empty string, and objects are converted using their own `toString` method.
-**trim(input [, chars])** | trim characters (whitespace by default) from both sides of the input.
+**trim(input [, chars])** | trim characters (whitespace by default) from both sides of the input. `chars` specifies literal characters, not regular expression ranges.
**unescape(input)** | replace HTML encoded entities with `<`, `>`, `&`, `'`, `"`, `` ` ``, `\` and `/`.
**whitelist(input, chars)** | remove characters that do not appear in the whitelist. The characters are used in a RegExp and so you will need to escape some chars, e.g. `whitelist(input, '\\[\\]')`.
diff --git a/src/lib/ltrim.js b/src/lib/ltrim.js
index 372d2df8e..3d995426b 100644
--- a/src/lib/ltrim.js
+++ b/src/lib/ltrim.js
@@ -3,6 +3,6 @@ import assertString from './util/assertString';
export default function ltrim(str, chars) {
assertString(str);
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
- const pattern = chars ? new RegExp(`^[${chars.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}]+`, 'g') : /^\s+/g;
+ const pattern = chars ? new RegExp(`^[${chars.replace(/[-.*+?^${}()|[\]\\]/g, '\\$&')}]+`, 'g') : /^\s+/g;
return str.replace(pattern, '');
}
diff --git a/src/lib/rtrim.js b/src/lib/rtrim.js
index 2d311574b..6b4219660 100644
--- a/src/lib/rtrim.js
+++ b/src/lib/rtrim.js
@@ -4,7 +4,7 @@ export default function rtrim(str, chars) {
assertString(str);
if (chars) {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
- const pattern = new RegExp(`[${chars.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}]+$`, 'g');
+ const pattern = new RegExp(`[${chars.replace(/[-.*+?^${}()|[\]\\]/g, '\\$&')}]+$`, 'g');
return str.replace(pattern, '');
}
// Use a faster and more safe than regex trim method https://blog.stevenlevithan.com/archives/faster-trim-javascript
diff --git a/test/sanitizers.test.js b/test/sanitizers.test.js
index 5f6454afb..361686e0d 100644
--- a/test/sanitizers.test.js
+++ b/test/sanitizers.test.js
@@ -121,6 +121,18 @@ describe('Sanitizers', () => {
});
});
+ [
+ { sanitizer: 'ltrim', expect: { '--azhello': 'hello', hello: 'hello' } },
+ { sanitizer: 'rtrim', expect: { 'helloza--': 'hello', hello: 'hello' } },
+ { sanitizer: 'trim', expect: { '--azhelloza--': 'hello', hello: 'hello' } },
+ ].forEach(({ sanitizer, expect }) => {
+ it(`should trim literal hyphens with ${sanitizer}`, () => {
+ ['a-z', 'z-a'].forEach((chars) => {
+ test({ sanitizer, args: [chars], expect });
+ });
+ });
+ });
+
it('should convert strings to integers', () => {
test({
sanitizer: 'toInt',