From 4d732a1f1dc5129f88442cff798eff5b96713545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Sroka?= <0xf1d0@protonmail.com> Date: Mon, 16 Nov 2020 09:30:34 +0000 Subject: [PATCH] Added fn to count unicode characters (#1903) ## Issue Addressed Password length check too short (https://github.com/sigp/lighthouse/issues/1880) ## Proposed Changes I've added function that counts number of unicode characters, instead of calling String::len() Co-authored-by: Paul Hauner --- common/account_utils/src/lib.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/common/account_utils/src/lib.rs b/common/account_utils/src/lib.rs index d74ed71ed..f969db702 100644 --- a/common/account_utils/src/lib.rs +++ b/common/account_utils/src/lib.rs @@ -140,11 +140,17 @@ fn trim_newline(s: &mut String) { } } +/// According to unicode, every byte that starts with 0b10xxxxxx continues encoding of character +/// Therefore the number of characters equals number of bytes minus number of 0b10xxxxxx bytes +fn count_unicode_characters(bits: &[u8]) -> usize { + bits.iter().filter(|bit| *bit >> 6 != 2).count() +} + /// Takes a string password and checks that it meets minimum requirements. /// /// The current minimum password requirement is a 12 character length character length. pub fn is_password_sufficiently_complex(password: &[u8]) -> Result<(), String> { - if password.len() >= MINIMUM_PASSWORD_LEN { + if count_unicode_characters(password) >= MINIMUM_PASSWORD_LEN { Ok(()) } else { Err(format!( @@ -192,8 +198,7 @@ impl AsRef<[u8]> for ZeroizeString { #[cfg(test)] mod test { - use super::is_password_sufficiently_complex; - use super::strip_off_newlines; + use super::*; #[test] fn test_strip_off() { @@ -244,4 +249,18 @@ mod test { fn test_password_too_short() { is_password_sufficiently_complex(b"TestPass").unwrap(); } + + #[test] + fn unicode_characters() { + assert_eq!(count_unicode_characters(b""), 0); + assert_eq!(count_unicode_characters("🐱".to_string().as_bytes()), 1); + assert_eq!(count_unicode_characters("🐱🐱".to_string().as_bytes()), 2); + + assert_eq!(count_unicode_characters(b"cats"), 4); + assert_eq!(count_unicode_characters("cats🐱".to_string().as_bytes()), 5); + assert_eq!( + count_unicode_characters("cats🐱🐱".to_string().as_bytes()), + 6 + ); + } }