Skip to content

Commit ffca6e7

Browse files
committed
fix: reject email with invisible chars - issue #2036
1 parent 86a07ba commit ffca6e7

File tree

4 files changed

+23
-0
lines changed

4 files changed

+23
-0
lines changed

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ import isLicensePlate from './lib/isLicensePlate';
122122
import isStrongPassword from './lib/isStrongPassword';
123123

124124
import isVAT from './lib/isVAT';
125+
import hasInvisibleChars from './lib/hasInvisibleChars';
125126

126127
const version = '13.7.0';
127128

@@ -229,6 +230,7 @@ const validator = {
229230
isLicensePlate,
230231
isVAT,
231232
ibanLocales,
233+
hasInvisibleChars,
232234
};
233235

234236
export default validator;

src/lib/hasInvisibleChars.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import assertString from './util/assertString';
2+
3+
const invisibleChars = /^[^\u00ad\u034f\u061c\u115f\u1160\u17b4\u17b5\u180e\u200b\u200c\u200d\u200e\u200f\u2060\u2061\u2062\u2063\u2064\u206a\u206b\u206c\u206d\u206e\u206f\ufeff]+$/i;
4+
5+
// check this site https://invisible-characters.com/ for list of invisible chars. I have excluded the space characters that are part of \s regex check
6+
// eslint-disable-next-line max-len
7+
// \s matches any whitespace character (equivalent to [\r\n\t\f\v \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff])
8+
export default function hasInvisibleChars(str) {
9+
assertString(str);
10+
return !invisibleChars.test(str);
11+
}

src/lib/isEmail.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import merge from './util/merge';
44
import isByteLength from './isByteLength';
55
import isFQDN from './isFQDN';
66
import isIP from './isIP';
7+
import hasInvisibleChars from './hasInvisibleChars';
78

89
const default_email_options = {
910
allow_display_name: false,
@@ -91,6 +92,9 @@ export default function isEmail(str, options) {
9192
return false;
9293
}
9394

95+
if (hasInvisibleChars(str)) {
96+
return false;
97+
}
9498
const parts = str.split('@');
9599
const domain = parts.pop();
96100
const lower_domain = domain.toLowerCase();

test/validators.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ describe('Validators', () => {
116116
'"wrong()[]",:;<>@@gmail.com',
117117
'username@domain.com�',
118118
'username@domain.com©',
119+
'invisibleChars@example­.com',
120+
'invisible​Space@test.com',
121+
// has invisible space character \u200B at the start
122+
'​user@domain.com',
123+
'invisibleZeroWidth‍Joiner@test.com',
124+
'invisible⁡WordJoiner@example.com',
119125
],
120126
});
121127
});

0 commit comments

Comments
 (0)