@@ -228,7 +228,16 @@ public static function enhanceWordCensor(string $text): bool
228228 */
229229 public static function checkReservedName (string $ name , bool $ fatal = false ): bool
230230 {
231- $ skeleton = self ::getSkeletonString (html_entity_decode ($ name , ENT_QUOTES ));
231+ // For ease of comparison, decode any entities.
232+ $ name = Utils::entityDecode ($ name , nbsp_to_space: true );
233+
234+ // Do we want caseless comparison?
235+ if (empty (Config::$ modSettings ['reserveCase ' ])) {
236+ $ name = Utils::casefold ($ name );
237+ }
238+
239+ // Get the "skeleton" for this name.
240+ $ skeleton = self ::getSkeletonString ($ name );
232241
233242 // This will hold all the names that are similar to $name.
234243 $ homograph_names = [];
@@ -241,19 +250,19 @@ public static function checkReservedName(string $name, bool $fatal = false): boo
241250 continue ;
242251 }
243252
244- // The admin might've used entities too, level the playing field.
245- $ reserved_check = html_entity_decode ($ reserved , ENT_QUOTES );
253+ // The admin might've used entities too, so level the playing field.
254+ $ reserved_check = Utils:: entityDecode ($ reserved , nbsp_to_space: true );
246255
247256 // Case sensitive name?
248257 if (empty (Config::$ modSettings ['reserveCase ' ])) {
249- $ reserved_check = Utils::strtolower ($ reserved_check );
258+ $ reserved_check = Utils::casefold ($ reserved_check );
250259 }
251260
252261 $ reserved_skeleton = self ::getSkeletonString ($ reserved_check );
253262
254263 // Skeletons match.
255264 if ($ skeleton == $ reserved_skeleton ) {
256- $ homograph_names [] = $ reserved_check ;
265+ $ homograph_names [$ reserved ] = $ reserved_check ;
257266 }
258267 // Skeleton of the name includes skeleton of a reserved name.
259268 elseif (
@@ -324,6 +333,14 @@ public static function checkReservedName(string $name, bool $fatal = false): boo
324333 */
325334 public static function checkSimilarMemberName (string $ name , int $ id_member = 0 , bool $ fatal = false ): bool
326335 {
336+ $ name = Utils::entityDecode ($ name , nbsp_to_space: true );
337+
338+ if (empty (Config::$ modSettings ['reserveCase ' ])) {
339+ $ name = Utils::casefold ($ name );
340+ }
341+
342+ $ skeleton = self ::getSkeletonString ($ name );
343+
327344 // This will hold all the names that are similar to $name.
328345 $ homograph_names = [];
329346
@@ -335,12 +352,18 @@ public static function checkSimilarMemberName(string $name, int $id_member = 0,
335352 AND id_member != {int:current_member} ' ) . '' ,
336353 [
337354 'current_member ' => $ id_member ,
338- 'skeleton ' => Utils:: htmlspecialchars ( self :: getSkeletonString ( html_entity_decode ( $ name , ENT_QUOTES ))) ,
355+ 'skeleton ' => $ skeleton ,
339356 ],
340357 );
341358
342359 while ($ row = Db::$ db ->fetch_assoc ($ request )) {
343- $ homograph_names [] = html_entity_decode ($ row ['real_name ' ], ENT_QUOTES );
360+ $ real_name = Utils::entityDecode ($ row ['real_name ' ], nbsp_to_space: true );
361+
362+ if (empty (Config::$ modSettings ['reserveCase ' ])) {
363+ $ real_name = Utils::casefold ($ real_name );
364+ }
365+
366+ $ homograph_names [$ row ['real_name ' ]] = $ real_name ;
344367 }
345368
346369 Db::$ db ->free_result ($ request );
@@ -363,21 +386,32 @@ public static function checkSimilarMemberName(string $name, int $id_member = 0,
363386 */
364387 public static function checkSimilarGroupName (string $ name , bool $ fatal = false ): bool
365388 {
366- $ skeleton = self ::getSkeletonString (html_entity_decode ($ name , ENT_QUOTES ));
389+ $ name = Utils::entityDecode ($ name , nbsp_to_space: true );
390+
391+ if (empty (Config::$ modSettings ['reserveCase ' ])) {
392+ $ name = Utils::casefold ($ name );
393+ }
394+
395+ $ skeleton = self ::getSkeletonString ($ name );
367396
368397 // This will hold all the names that are similar to $name.
369398 $ homograph_names = [];
370399
371400 // Get all the membergroup names.
372401 $ request = Db::$ db ->query (
373- 'SELECT group_name AS name
402+ 'SELECT group_name
374403 FROM {db_prefix}membergroups ' ,
375- [],
376404 );
377405
378406 while ($ row = Db::$ db ->fetch_assoc ($ request )) {
379- if ($ skeleton === self ::getSkeletonString (html_entity_decode ($ row ['name ' ], ENT_QUOTES ))) {
380- $ homograph_names [] = $ row ['name ' ];
407+ $ group_name = Utils::entityDecode ($ row ['group_name ' ], nbsp_to_space: true );
408+
409+ if (empty (Config::$ modSettings ['reserveCase ' ])) {
410+ $ group_name = Utils::casefold ($ group_name );
411+ }
412+
413+ if ($ skeleton === self ::getSkeletonString ($ group_name )) {
414+ $ homograph_names [$ row ['group_name ' ]] = $ group_name ;
381415 }
382416 }
383417 Db::$ db ->free_result ($ request );
@@ -407,7 +441,7 @@ protected static function checkHomographNames(string $name, array $homograph_nam
407441 {
408442 $ name_script_set = self ::resolveScriptSet ($ name );
409443
410- foreach ($ homograph_names as $ homograph_name ) {
444+ foreach ($ homograph_names as $ orig => $ homograph_name ) {
411445 $ homograph_name_script_set = self ::resolveScriptSet ($ homograph_name );
412446
413447 // If they are mixed script confusables, reject.
@@ -417,7 +451,7 @@ protected static function checkHomographNames(string $name, array $homograph_nam
417451 && array_intersect ($ name_script_set , $ homograph_name_script_set ) === []
418452 ) {
419453 if ($ fatal ) {
420- ErrorHandler::fatalLang ('username_reserved ' , 'password ' , [$ homograph_name ]);
454+ ErrorHandler::fatalLang ('username_reserved ' , 'password ' , [$ orig ]);
421455 }
422456
423457 return true ;
@@ -436,7 +470,7 @@ protected static function checkHomographNames(string $name, array $homograph_nam
436470 // This takes care of "ljeto" vs. "ljeto".
437471 if ($ name_kc === $ homograph_name_kc ) {
438472 if ($ fatal ) {
439- ErrorHandler::fatalLang ('username_reserved ' , 'password ' , [$ homograph_name ]);
473+ ErrorHandler::fatalLang ('username_reserved ' , 'password ' , [$ orig ]);
440474 }
441475
442476 return true ;
@@ -449,7 +483,7 @@ protected static function checkHomographNames(string $name, array $homograph_nam
449483 // This takes care of "Bogden" vs. "Boɡden".
450484 if (!preg_match ('~^[ ' . $ regexes ['Allowed ' ] . ']*$~u ' , $ name_kc ) || !preg_match ('~^[ ' . $ regexes ['Allowed ' ] . ']*$~u ' , $ homograph_name_kc )) {
451485 if ($ fatal ) {
452- ErrorHandler::fatalLang ('username_reserved ' , 'password ' , [$ homograph_name ]);
486+ ErrorHandler::fatalLang ('username_reserved ' , 'password ' , [$ orig ]);
453487 }
454488
455489 return true ;
0 commit comments