From d41e00ede5e2bb0434fff9a213197239bc26aef8 Mon Sep 17 00:00:00 2001 From: deemonic Date: Wed, 27 Nov 2024 03:15:00 +0000 Subject: [PATCH] regex tweaks and bug fixes --- README.md | 15 +- config/config.php | 51 +- src/BlaspExpressionService.php | 8 +- src/BlaspService.php | 4 +- tests/BlaspCheckFrenchTest.php | 123 --- tests/BlaspCheckTest.php | 60 +- tests/BlaspCheckValidationTest.php | 32 - tests/TestCase.php | 1338 +++++++++++++++++++++++++++- 8 files changed, 1393 insertions(+), 238 deletions(-) delete mode 100644 tests/BlaspCheckFrenchTest.php diff --git a/README.md b/README.md index 092db1e..41ad26b 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,7 @@ use Blaspsoft\Blasp\Facades\Blasp; $sentence = 'This is a fucking shit sentence'; $check = Blasp::check($sentence); ``` -you can also change the default language to french -```php -use Blaspsoft\Blasp\Facades\Blasp; -$sentence = 'Cette phrase est merdique'; -$check = Blasp::check($sentence, 'fr'); -``` The returned object will contain the following properties: - **sourceString**: The original string you passed. @@ -82,15 +76,8 @@ $request->merge(['sentence' => 'This is f u c k 1 n g awesome!']); $validated = $request->validate([ 'sentence' => ['blasp_check'], ]); - -// If the sentence contains profanities, validation will fail. -``` -or for french -```php -$validated = $request->validate([ - 'sentence' => ['blasp_check:fr'], -]); ``` + ### Configuration Blasp uses a configuration file (`config/blasp.php`) to manage the list of profanities, separators, and substitutions. You can publish the configuration file using the following Artisan command: diff --git a/config/config.php b/config/config.php index edad69f..ff046ba 100644 --- a/config/config.php +++ b/config/config.php @@ -22,7 +22,7 @@ | | */ - 'languages' => ['en', 'fr'], + 'languages' => ['en'], /* |-------------------------------------------------------------------------- @@ -95,7 +95,7 @@ '/p/' => ['p', 'ρ', 'Ρ', '¶', 'þ'], '/q/' => ['q'], '/r/' => ['r', '®'], - '/s/' => ['s', '5', '$', '§', 'ß', 'Ś', 'ś', 'Š', 'š'], + '/s/' => ['s', '5', '\$', '§', 'ß', 'Ś', 'ś', 'Š', 'š'], '/t/' => ['t', 'Τ', 'τ'], '/u/' => ['u', 'υ', 'µ', 'û', 'ü', 'ù', 'ú', 'ū', 'Û', 'Ü', 'Ù', 'Ú', 'Ū'], '/v/' => ['v', 'υ', 'ν'], @@ -136,15 +136,8 @@ 'flicker', 'analyst', 'cocktail', + 'musicals hit', ], - 'fr' => [ - 'passeur', - 'classe', - 'passage', - 'assumer', - 'passant', - 'bassiste', - ] ], @@ -462,7 +455,6 @@ 'cuntass', 'cunteyed', 'cuntface', - 'cuntfuck', 'cuntfucker', 'cunthole', 'cuntlick', @@ -637,7 +629,6 @@ 'fuckbutt', 'fuckbutter', 'fucked', - 'fuckedup', 'fucker', 'fuckers', 'fuckersucker', @@ -652,7 +643,6 @@ 'fuckina', 'fucking', 'fuckingbitch', - 'fuckingcunt', 'fuckinnuts', 'fuckinright', 'fuckit', @@ -742,7 +732,7 @@ 'hardon', 'headfuck', 'heeb', - 'hells', + 'hell', 'herpes', 'hijacker', 'hijacking', @@ -782,7 +772,6 @@ 'incest', 'insest', 'internet wife', - 'intheass', 'inthebuff', 'jackass', 'jackoff', @@ -1461,37 +1450,5 @@ 'zipperhea', 'zipper head', ], - 'fr' => [ - 'con', - 'connard', - 'connasse', - 'merde', - 'merdique', - 'putain', - 'enculé', - 'salope', - 'batard', - 'bordel', - 'fils de pute', - 'pute', - 'cul', - 'abruti', - 'crétin', - 'imbécile', - 'ordure', - 'débile', - 'dégénéré', - 'foutre', - 'chiant', - 'chiotte', - 'bouffon', - 'gros con', - 'pédé', - 'tapette', - 'bite', - 'couille', - 'enfoiré', - 'trou du cul', - ] ], ]; \ No newline at end of file diff --git a/src/BlaspExpressionService.php b/src/BlaspExpressionService.php index 6502232..985cdba 100644 --- a/src/BlaspExpressionService.php +++ b/src/BlaspExpressionService.php @@ -118,7 +118,7 @@ private function loadConfiguration(): void $this->validateChosenLanguage(); - $this->profanities = config('blasp.profanities')[$this->chosenLanguage]; + $this->profanities = config('blasp.profanities')[$this->chosenLanguage]; $this->separators = config('blasp.separators'); $this->substitutions = config('blasp.substitutions'); } @@ -157,6 +157,7 @@ private function generateEscapedExpression(array $characters = [], array $escape $regex = $escapedCharacters; foreach ($characters as $character) { + $regex[] = preg_quote($character, '/'); } @@ -190,8 +191,9 @@ private function generateProfanityExpression($profanity): string $expression = str_replace(self::SEPARATOR_PLACEHOLDER, $this->separatorExpression, $expression); - $expression = '/' . $expression . '(?:s?)\b/i'; - + // Allow for non-word characters or spaces around the profanity + $expression = '/' . $expression . '/i'; + return $expression; } diff --git a/src/BlaspService.php b/src/BlaspService.php index 97785d9..04e90b6 100644 --- a/src/BlaspService.php +++ b/src/BlaspService.php @@ -2,9 +2,9 @@ namespace Blaspsoft\Blasp; -use Blaspsoft\Blasp\Abstracts\StringNormalizer; -use Blaspsoft\Blasp\Normalizers\Normalize; use Exception; +use Blaspsoft\Blasp\Normalizers\Normalize; +use Blaspsoft\Blasp\Abstracts\StringNormalizer; class BlaspService extends BlaspExpressionService { diff --git a/tests/BlaspCheckFrenchTest.php b/tests/BlaspCheckFrenchTest.php deleted file mode 100644 index 4fe0abe..0000000 --- a/tests/BlaspCheckFrenchTest.php +++ /dev/null @@ -1,123 +0,0 @@ -blaspService = new BlaspService('fr'); - } - - /** - * @throws Exception - */ - public function testInvalidLanguage():void - { - $this->expectExceptionMessage('Unsupported language.'); - $blaspService = new BlaspService('es'); - $blaspService->check('This for test the language'); - } - - public function french_test_data_provider(): array - { - return [ - 'test_real_blasp_service' => [ - 'string' => 'Ceci est une putain de phrase', - 'hasProfanity' => true, - 'count' => 1, - 'expectedText' => 'Ceci est une ****** de phrase', - ], - 'test_straight_match' => [ - 'string' => 'Ceci est une connasse', - 'hasProfanity' => true, - 'count' => 1, - 'expectedText' => 'Ceci est une ********', - ], - 'test_substitution_match' => [ - 'string' => 'Ceci est une c0nn4ss3', - 'hasProfanity' => true, - 'count' => 1, - 'expectedText' => 'Ceci est une ********', - ], - 'test_obscured_match' => [ - 'string' => 'Ceci est une c-o-n-n-a-s-s-e', - 'hasProfanity' => true, - 'count' => 1, - 'expectedText' => 'Ceci est une ***************', - ], - 'test_doubled_match' => [ - 'string' => 'Ceci est une ccoonnaassee', - 'hasProfanity' => true, - 'count' => 1, - 'expectedText' => 'Ceci est une ************', - ], - 'test_combination_match' => [ - 'string' => 'Ceci est une c-ooonn4ss3', - 'hasProfanity' => true, - 'count' => 1, - 'expectedText' => 'Ceci est une ***********', - ], - 'test_multiple_profanities_no_spaces' => [ - 'string' => 'merdiqueputain foutre', - 'hasProfanity' => true, - 'count' => 3, - 'expectedText' => '************** ******', - ], - 'test_multiple_profanities' => [ - 'string' => 'Ceci est une putain de phrase de connard !', - 'hasProfanity' => true, - 'count' => 2, - 'expectedText' => 'Ceci est une ****** de phrase de ******* !', - ], 'test_scunthorpe_problem' => [ - 'string' => 'je suis un passeur', - 'hasProfanity' => false, - 'count' => 0, - 'expectedText' => 'je suis un passeur', - ], 'test_paragraph' => [ - 'string' => "Ce projet est tellement merdique. C'est un vrai bordel, et personne n'en a rien à foutre.", - 'hasProfanity' => true, - 'count' => 3, - 'expectedText' => "Ce projet est tellement ********. C'est un vrai ******, et personne n'en a rien à ******.", - ], - ]; - } - - - /** - * @throws Exception - * @dataProvider french_test_data_provider - */ - public function test_language_french(string $string, bool $hasProfanity, int $profanitiesCount, string $expectedText): void - { - $result = $this->blaspService->check($string); - - $this->assertEquals($hasProfanity, $result->hasProfanity); - $this->assertSame($profanitiesCount, $result->profanitiesCount); - $this->assertSame($expectedText, $result->cleanString); - } - - /** - * @throws Exception - */ - public function test_paragraph_french(): void - { - $paragraph = "Ce projet est tellement merdique. C'est un vrai bordel, et personne n'en a rien à foutre."; - - $result = $this->blaspService->check($paragraph, 'fr'); - - $expectedOutcome = "Ce projet est tellement ********. C'est un vrai ******, et personne n'en a rien à ******."; - $this->assertTrue($result->hasProfanity); - $this->assertSame(3, $result->profanitiesCount); - $this->assertCount(3, $result->uniqueProfanitiesFound); - $this->assertSame($expectedOutcome, $result->cleanString); - } -} diff --git a/tests/BlaspCheckTest.php b/tests/BlaspCheckTest.php index b2cfe1d..bfe5857 100644 --- a/tests/BlaspCheckTest.php +++ b/tests/BlaspCheckTest.php @@ -2,8 +2,8 @@ namespace Blaspsoft\Blasp\Tests; -use Blaspsoft\Blasp\BlaspService; use Exception; +use Blaspsoft\Blasp\BlaspService; class BlaspCheckTests extends TestCase { @@ -11,10 +11,8 @@ class BlaspCheckTests extends TestCase public function setUp(): void { - parent::setUp(); $this->blaspService = new BlaspService(); - } /** @@ -111,7 +109,6 @@ public function test_multiple_profanities_no_spaces() public function test_multiple_profanities() { $result = $this->blaspService->check('This is a fuuckking sentence you fucking cunt!'); - $this->assertTrue($result->hasProfanity); $this->assertSame(3, $result->profanitiesCount); $this->assertCount(2, $result->uniqueProfanitiesFound); @@ -174,8 +171,6 @@ public function test_false_positives() foreach ($words as $word) { - - $result = $this->blaspService->check($word); $this->assertTrue(!$result->hasProfanity); @@ -191,7 +186,6 @@ public function test_false_positives() public function test_cuntfuck_fuckcunt() { $result = $this->blaspService->check('cuntfuck fuckcunt'); - $this->assertTrue($result->hasProfanity); $this->assertSame(4, $result->profanitiesCount); $this->assertCount(2, $result->uniqueProfanitiesFound); @@ -204,10 +198,9 @@ public function test_cuntfuck_fuckcunt() public function test_fucking_shit_cunt_fuck() { $result = $this->blaspService->check('fuckingshitcuntfuck'); - $this->assertTrue($result->hasProfanity); - $this->assertSame(4, $result->profanitiesCount); - $this->assertCount(4, $result->uniqueProfanitiesFound); + $this->assertSame(3, $result->profanitiesCount); + $this->assertCount(3, $result->uniqueProfanitiesFound); $this->assertSame('*******************', $result->cleanString); } @@ -231,7 +224,7 @@ public function test_paragraph() $paragraph = "This damn project is such a pain in the ass. I can't believe I have to deal with this bullshit every single day. It's like everything is completely fucked up, and nobody gives a shit. Sometimes I just want to scream, 'What the hell is going on?' Honestly, it's a total clusterfuck, and I'm so fucking done with this crap."; $result = $this->blaspService->check($paragraph); - + $expectedOutcome = "This **** project is such a pain in the ***. I can't believe I have to deal with this ******** every single day. It's like everything is completely ****** up, and nobody gives a ****. Sometimes I just want to scream, 'What the **** is going on?' Honestly, it's a total ***********, and I'm so ******* done with this ****."; $this->assertTrue($result->hasProfanity); @@ -239,4 +232,49 @@ public function test_paragraph() $this->assertCount(9, $result->uniqueProfanitiesFound); $this->assertSame($expectedOutcome, $result->cleanString); } + + public function test_word_boudary() + { + $result = $this->blaspService->check('afuckb'); + $this->assertTrue($result->hasProfanity); + $this->assertSame(1, $result->profanitiesCount); + $this->assertCount(1, $result->uniqueProfanitiesFound); + $this->assertSame('a****b', $result->cleanString); + } + + public function test_pural_profanity() + { + $result = $this->blaspService->check('fuckings'); + $this->assertTrue($result->hasProfanity); + $this->assertSame(1, $result->profanitiesCount); + $this->assertCount(1, $result->uniqueProfanitiesFound); + $this->assertSame('*******s', $result->cleanString); + } + + public function test_this_musicals_hit() + { + $result = $this->blaspService->check('This musicals hit'); + $this->assertTrue(!$result->hasProfanity); + $this->assertSame(0, $result->profanitiesCount); + $this->assertCount(0, $result->uniqueProfanitiesFound); + $this->assertSame('This musicals hit', $result->cleanString); + } + + public function test_ass_subtitution() + { + $result = $this->blaspService->check('a$$'); + $this->assertTrue($result->hasProfanity); + $this->assertSame(1, $result->profanitiesCount); + $this->assertCount(1, $result->uniqueProfanitiesFound); + $this->assertSame('***', $result->cleanString); + } + + public function test_embedded_profanities() + { + $result = $this->blaspService->check('abcdtwatefghshitijklmfuckeropqrccuunntt'); + $this->assertTrue($result->hasProfanity); + $this->assertSame(4, $result->profanitiesCount); + $this->assertCount(4, $result->uniqueProfanitiesFound); + $this->assertSame('abcd****efgh****ijklm******opqr********', $result->cleanString); + } } \ No newline at end of file diff --git a/tests/BlaspCheckValidationTest.php b/tests/BlaspCheckValidationTest.php index 895b061..911753e 100644 --- a/tests/BlaspCheckValidationTest.php +++ b/tests/BlaspCheckValidationTest.php @@ -36,36 +36,4 @@ public function test_blasp_check_validation_fails_with_profanity() $this->assertTrue($validator->fails()); } - - /** - * Test validation passes with clean French text. - * - * @return void - */ - public function test_blasp_check_validation_passes_with_clean_french_text() - { - $data = ['message' => 'Ceci est un message propre.']; - - $rules = ['message' => 'blasp_check:fr']; - - $validator = Validator::make($data, $rules); - - $this->assertTrue($validator->passes()); - } - - /** - * Test validation fails with profane French text. - * - * @return void - */ - public function test_blasp_check_validation_fails_with_french_profanity() - { - $data = ['message' => 'Ceci est un message de merdique.']; - - $rules = ['message' => 'blasp_check:fr']; - - $validator = Validator::make($data, $rules); - - $this->assertTrue($validator->fails()); - } } diff --git a/tests/TestCase.php b/tests/TestCase.php index e5d5f39..23e7434 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -19,13 +19,1339 @@ protected function getPackageProviders($app) protected function setUp(): void { parent::setUp(); + Config::set('blasp.profanities', [ - 'en' => ['fucking', 'shit', 'cunt', 'fuck', 'penis', 'cock', 'twat', 'ass', 'dick', 'sex', 'butt', 'arse', 'lick', 'anal', 'clusterfuck', 'bullshit', 'fucked', 'damn', 'crap', 'hell'], - 'fr' => ['putain', 'connasse', 'c0nn4ss3', 'putain', 'connard', 'merdique', 'bordel', 'foutre', 'Putain', 'merde']]); - Config::set('blasp.false_positives', ['fr' => ['passeur', 'classe'], 'en' => ['Scunthorpe', 'Cockburn', 'Penistone', 'Lightwater', 'Assume', 'bass', 'class', 'Compass', 'Pass', - 'Dickinson', 'Middlesex', 'Cockerel', 'Butterscotch', 'Blackcock', 'Countryside', 'Arsenal', 'Flick', 'Flicker', 'Analyst', 'blackCocktail',]]); - Config::set('blasp.languages', ['en', 'fr']); + 'en' => [ + 'abbo', + 'abortionist', + 'abuser', + 'ahole', + 'alabama hotpocket', + 'alligatorbait', + 'anal', + 'analannie', + 'analsex', + 'areola', + 'arse', + 'arsebagger', + 'arsebandit', + 'arseblaster', + 'arsecowboy', + 'arsefuck', + 'arsefucker', + 'arsehat', + 'arsehole', + 'arseholes', + 'arsehore', + 'arsejockey', + 'arsekiss', + 'arsekisser', + 'arselick', + 'arselicker', + 'arselover', + 'arseman', + 'arsemonkey', + 'arsemunch', + 'arsemuncher', + 'arsepacker', + 'arsepirate', + 'arsepuppies', + 'arseranger', + 'arses', + 'arsewhore', + 'arsewipe', + 'ass', + 'assbag', + 'assbagger', + 'assbandit', + 'assbanger', + 'assbite', + 'assblaster', + 'assclown', + 'asscock', + 'asscowboy', + 'asscracker', + 'asses', + 'assface', + 'assfuck', + 'assfucker', + 'assgoblin', + 'ass-hat', + 'asshat', + 'asshead', + 'asshole', + 'assholes', + 'assholz', + 'asshopper', + 'asshore', + 'ass-jabber', + 'assjacker', + 'assjockey', + 'asskiss', + 'asskisser', + 'assklown', + 'asslick', + 'asslicker', + 'asslover', + 'assman', + 'assmonkey', + 'ass monkey', + 'assmunch', + 'assmuncher', + 'assnigger', + 'asspacker', + 'ass-pirate', + 'asspirate', + 'asspuppies', + 'assranger', + 'assshit', + 'assshole', + 'asssucker', + 'asswad', + 'asswhore', + 'asswipe', + 'axwound', + 'azzhole', + 'backdoorman', + 'badfuck', + 'baldy', + 'ball licker', + 'balllicker', + 'ballsack', + 'bampot', + 'banging', + 'barelylegal', + 'barface', + 'barfface', + 'bassterds', + 'bastard', + 'bastards', + 'bastardz', + 'basterds', + 'basterdz', + 'bazongas', + 'bazooms', + 'beaner', + 'beastality', + 'beastial', + 'beastiality', + 'beat-off', + 'beatoff', + 'beatyourmeat', + 'bestial', + 'bestiality', + 'biatch', + 'bicurious', + 'bigass', + 'bigbastard', + 'bigbutt', + 'bitch', + 'bitchass', + 'bitcher', + 'bitches', + 'bitchez', + 'bitchin', + 'bitching', + 'bitchslap', + 'bitchtits', + 'bitchy', + 'biteme', + 'blow job', + 'blowjob', + 'boffing', + 'bohunk', + 'bollick', + 'bollock', + 'bollocks', + 'bollox', + 'bondage', + 'boner', + 'boob', + 'boobies', + 'boobs', + 'booby', + 'bootycall', + 'bountybar', + 'breastjob', + 'breastlover', + 'breastman', + 'brothel', + 'brotherfucker', + 'bugger', + 'buggered', + 'buggery', + 'bukake', + 'bullcrap', + 'bulldike', + 'bulldyke', + 'bullshit', + 'bumblefuck', + 'bumfuck', + 'bungabunga', + 'bunghole', + 'butchbabes', + 'butchdike', + 'butchdyke', + 'butt-bang', + 'buttbang', + 'buttcheeks', + 'buttface', + 'butt-fuck', + 'buttfuck', + 'buttfucka', + 'butt-fucker', + 'buttfucker', + 'butt-fuckers', + 'buttfuckers', + 'butthead', + 'butthole', + 'buttman', + 'buttmunch', + 'buttmuncher', + 'butt-pirate', + 'buttpirate', + 'butt plug', + 'buttplug', + 'buttstain', + 'buttwipe', + 'byatch', + 'cacker', + 'cameljockey', + 'camel toe', + 'cameltoe', + 'carpet muncher', + 'carpetmuncher', + 'cawk', + 'cawks', + 'chav', + 'cherrypopper', + 'chesticle', + 'chickslick', + 'chinc', + 'chink', + 'choad', + 'chode', + 'clamdigger', + 'clamdiver', + 'clit', + 'clitface', + 'clitfuck', + 'clitoris', + 'clogwog', + 'clunge', + 'clusterfuck', + 'cnts', + 'cntz', + 'cock', + 'cockass', + 'cockbite', + 'cockblock', + 'cockblocker', + 'cockburger', + 'cockcowboy', + 'cockface', + 'cockfight', + 'cockfucker', + 'cock-head', + 'cockhead', + 'cockjockey', + 'cockknob', + 'cockknoker', + 'cocklicker', + 'cocklover', + 'cockmaster', + 'cockmongler', + 'cockmongruel', + 'cockmonkey', + 'cockmuncher', + 'cocknob', + 'cocknose', + 'cocknugget', + 'cockqueen', + 'cockrider', + 'cocks', + 'cockshit', + 'cocksman', + 'cocksmith', + 'cocksmoke', + 'cocksmoker', + 'cocksniffer', + 'cocksucer', + 'cocksuck', + 'cocksucked', + 'cock-sucker', + 'cocksucker', + 'cocksucking', + 'cocktease', + 'cockwaffle', + 'cocky', + 'coitus', + 'cok', + 'commie', + 'coochie', + 'coochy', + 'coon', + 'coondog', + 'cooter', + 'copulate', + 'cracker', + 'crackpipe', + 'crack-whore', + 'crackwhore', + 'crap', + 'crappy', + 'crotchjockey', + 'crotchmonkey', + 'crotchrot', + 'cuck', + 'cum', + 'cumbubble', + 'cumdumpster', + 'cumfest', + 'cumguzzler', + 'cumjockey', + 'cumm', + 'cumquat', + 'cumqueen', + 'cumshot', + 'cumslut', + 'cumtart', + 'cunilingus', + 'cunillingus', + 'cunnie', + 'cunnilingus', + 'cunntt', + 'cunt', + 'cuntass', + 'cunteyed', + 'cuntface', + 'cuntfucker', + 'cunthole', + 'cuntlick', + 'cuntlicker', + 'cuntlicker', + 'cuntlicking', + 'cuntrag', + 'cunts', + 'cuntslut', + 'cuntsucker', + 'cuntz', + 'cybersex', + 'cyberslimer', + 'dago', + 'dammit', + 'damn', + 'damnation', + 'damnit', + 'darkie', + 'darky', + 'datnigga', + 'deapthroat', + 'deepthroat', + 'deggo', + 'dego', + 'devilworshipper', + 'dick', + 'dickbag', + 'dickbeaters', + 'dickbrain', + 'dickface', + 'dickforbrains', + 'dickfuck', + 'dickfucker', + 'dickhead', + 'dickhole', + 'dickjuice', + 'dickless', + 'dicklick', + 'dicklicker', + 'dickmilk', + 'dickmonger', + 'dicks', + 'dickslap', + 'dick-sneeze', + 'dicksucker', + 'dicksucking', + 'dicktickler', + 'dickwad', + 'dickweasel', + 'dickweed', + 'dickwod', + 'dike', + 'dildo', + 'dildos', + 'dilldo', + 'dilldos', + 'dipshit', + 'dipstick', + 'dixiedike', + 'dixiedyke', + 'doggiestyle', + 'doggystyle', + 'dominatricks', + 'dominatrics', + 'dominatrix', + 'doochbag', + 'dookie', + 'douch', + 'douchbag', + 'douche', + 'douchebag', + 'douche-fag', + 'douchewaffle', + 'drag queen', + 'dragqueen', + 'dragqween', + 'dripdick', + 'dumass', + 'dumb ass', + 'dumbass', + 'dumbbitch', + 'dumbfuck', + 'dumbshit', + 'dumshit', + 'dyke', + 'easyslut', + 'eatballs', + 'eatme', + 'eatpussy', + 'ejaculate', + 'ejaculated', + 'ejaculating', + 'ejaculation', + 'enema', + 'excrement', + 'facefucker', + 'facist', + 'faeces', + 'fag', + 'fagbag', + 'faget', + 'fagfucker', + 'fagging', + 'faggit', + 'faggot', + 'faggotcock', + 'faggots', + 'fagit', + 'fagot', + 'fags', + 'fagtard', + 'fagz', + 'faig', + 'faigs', + 'fannyfucker', + 'fark', + 'farted', + 'farting', + 'farty', + 'fastfuck', + 'fatass', + 'fatfuck', + 'fatfucker', + 'fatso', + 'feces', + 'felatio', + 'felch', + 'felcher', + 'felching', + 'fellatio', + 'feltch', + 'feltcher', + 'feltching', + 'fingerfuck', + 'fingerfucked', + 'fingerfucker', + 'fingerfuckers', + 'fingerfucking', + 'fister', + 'fistfuck', + 'fistfucked', + 'fistfucker', + 'fistfucking', + 'fisting', + 'flamer', + 'flasher', + 'flid', + 'flipping the bird', + 'flyd', + 'flydie', + 'flydye', + 'fondle', + 'footaction', + 'footfuck', + 'footfucker', + 'footlicker', + 'fornicate', + 'freakfuck', + 'freakyfucker', + 'freefuck', + 'fubar', + 'fucck', + 'fuck', + 'fucka', + 'fuckable', + 'fuckass', + 'fuckbag', + 'fuckboy', + 'fuckbrain', + 'fuckbuddy', + 'fuckbutt', + 'fuckbutter', + 'fucked', + 'fucker', + 'fuckers', + 'fuckersucker', + 'fuckface', + 'fuckfest', + 'fuckfreak', + 'fuckfriend', + 'fuckhead', + 'fuckher', + 'fuckhole', + 'fuckin', + 'fuckina', + 'fucking', + 'fuckingbitch', + 'fuckinnuts', + 'fuckinright', + 'fuckit', + 'fuckknob', + 'fuckme', + 'fuckmehard', + 'fuckmonkey', + 'fucknut', + 'fucknutt', + 'fuckoff', + 'fuckpig', + + 'fuckstick', + 'fucktard', + 'fucktart', + 'fuckup', + 'fuckwad', + 'fuckwhore', + 'fuckwit', + 'fuckwitt', + 'fuckyou', + 'fudge packer', + 'fudgepacker', + 'Fudge Packer', + 'fugly', + 'fuk', + 'Fukah', + 'Fuken', + 'fuker', + 'Fukin', + 'Fukk', + 'Fukkah', + 'Fukken', + 'Fukker', + 'Fukkin', + 'fuks', + 'funfuck', + 'fuuck', + 'gang bang', + 'gangbang', + 'gangbanged', + 'gangbanger', + 'gatorbait', + 'gayass', + 'gaybob', + 'gayboy', + 'gaydo', + 'gayfuck', + 'gayfuckist', + 'gaygirl', + 'gaylord', + 'gaymuthafuckinwhore', + 'gays', + 'gaysex', + 'gaytard', + 'gaywad', + 'gayz', + 'getiton', + 'givehead', + 'glazeddonut', + 'godammit', + 'goddamit', + 'goddammit', + 'goddamn', + 'goddamned', + 'god-damned', + 'goddamnes', + 'goddamnit', + 'goddamnmuthafucker', + 'goldenshower', + 'gonorrehea', + 'gonzagas', + 'gooch', + 'gook', + 'gotohell', + 'greaseball', + 'gringo', + 'grostulation', + 'guido', + 'gypo', + 'gypp', + 'gyppie', + 'gyppo', + 'gyppy', + 'handjob', + 'hard on', + 'hardon', + 'headfuck', + 'heeb', + 'hell', + 'herpes', + 'hijacker', + 'hijacking', + 'hillbillies', + 'hindoo', + 'hitler', + 'hitlerism', + 'hitlerist', + 'hoar', + 'hobo', + 'hoe', + 'hoes', + 'holestuffer', + 'homo', + 'homobangers', + 'homodumbshit', + 'honger', + 'honkers', + 'honkey', + 'honky', + 'hookers', + 'hoor', + 'hoore', + 'hore', + 'horney', + 'horniest', + 'horny', + 'horseshit', + 'hosejob', + 'hotdamn', + 'hotpussy', + 'hottotrot', + 'humping', + 'hymen', + 'iblowu', + 'idiot', + 'incest', + 'insest', + 'internet wife', + 'inthebuff', + 'jackass', + 'jackoff', + 'jackshit', + 'jagoff', + 'jap', + 'japcrap', + 'japs', + 'jerkass', + 'jerk off', + 'jerk-off', + 'jerkoff', + 'jesuschrist', + 'jigaboo', + 'jiggabo', + 'jihad', + 'jijjiboo', + 'jisim', + 'jism', + 'jiss', + 'jizim', + 'jizjuice', + 'jizm', + 'jizm', + 'jizz', + 'jizzim', + 'jizzum', + 'jubblies', + 'juggalo', + 'jungle bunny', + 'junglebunny', + 'kiddy fiddler', + 'kike', + 'kinky', + 'kissass', + 'knobz', + 'kondum', + 'kooch', + 'kootch', + 'krap', + 'krappy', + 'kraut', + 'kumbubble', + 'kumbullbe', + 'kummer', + 'kumming', + 'kums', + 'kunilingus', + 'kunnilingus', + 'kunt', + 'kunts', + 'kuntz', + 'kyke', + 'labia', + 'lactate', + 'lady boy', + 'ladyboy', + 'lameass', + 'lapdance', + 'lardass', + 'lesbain', + 'lesbayn', + 'lesbian', + 'lesbin', + 'lesbo', + 'lezbe', + 'lezbefriends', + 'lezbo', + 'lezz', + 'lezzer', + 'lezzie', + 'lezzo', + 'libido', + 'lickme', + 'limpdick', + 'lipshits', + 'lipshitz', + 'livesex', + 'lmfao', + 'loadedgun', + 'lovebone', + 'lovegoo', + 'lovegun', + 'lovejuice', + 'lovemuscle', + 'lovepistol', + 'loverocket', + 'low life', + 'lowlife', + 'lubejob', + 'luckycameltoe', + 'manhater', + 'manpaste', + 'masochist', + 'masokist', + 'massterbait', + 'masstrbait', + 'masstrbate', + 'mastabate', + 'mastabater', + 'masterbaiter', + 'masterbate', + 'master bates', + 'masterbates', + 'mastrabator', + 'masturbate', + 'masturbating', + 'mattressprincess', + 'mcfagget', + 'meatbeater', + 'meatrack', + 'mgger', + 'mggor', + 'milf', + 'minge', + 'mofo', + 'molest', + 'molestation', + 'molester', + 'molestor', + 'moneyshot', + 'mooncricket', + 'moron', + 'mothafuck', + 'mothafucka', + 'mothafuckaz', + 'mothafucked', + 'mothafucker', + 'motha fucker', + 'mothafuckin', + 'mothafucking', + 'mothafuckings', + 'motha fuker', + 'motha fukkah', + 'motha fukker', + 'motherfuck', + 'motherfucked', + 'mother-fucker', + 'motherfucker', + 'mother fucker', + 'motherfuckin', + 'motherfucking', + 'motherfuckings', + 'mother fukah', + 'mother fuker', + 'mother fukkah', + 'mother fukker', + 'motherlovebone', + 'muff', + 'muffdive', + 'muffdiver', + 'muffindiver', + 'mufflikcer', + 'muncher', + 'munging', + 'muthafucker', + 'mutha fucker', + 'mutha fukah', + 'mutha fuker', + 'mutha fukkah', + 'mutha fukker', + 'nastt', + 'nastybitch', + 'nastyho', + 'nastyslut', + 'nastywhore', + 'nazi', + 'necro', + 'negro', + 'negroes', + 'negroid', + 'nigaboo', + 'nigga', + 'niggah', + 'niggaracci', + 'niggard', + 'niggarded', + 'niggarding', + 'niggardliness', + "niggardliness's", + 'niggardly', + "niggard's", + 'niggards', + 'niggaz', + 'nigger', + 'niggerhead', + 'niggerhole', + "nigger's", + 'niggers', + 'niggle', + 'niggled', + 'niggles', + 'niggling', + 'nigglings', + 'niggor', + 'niggur', + 'niglet', + 'nignog', + 'nigr', + 'nigra', + 'nigre', + 'nigur', + 'niiger', + 'niigr', + 'nipple', + 'nipplering', + 'nittit', + 'nlgger', + 'nlggor', + 'nofuckingway', + 'nonce', + 'nookey', + 'nookie', + 'nudger', + 'nut case', + 'nutcase', + 'nutfucker', + 'nut sack', + 'nutsack', + 'ontherag', + 'orafis', + 'orgasim', + 'orgasim', + 'orgasm', + 'orgasum', + 'orgies', + 'orgy', + 'oriface', + 'orifice', + 'orifiss', + 'osama bin laden', + 'packi', + 'packie', + 'packy', + 'paedo', + 'paedofile', + 'paedophile', + 'paki', + 'pakie', + 'paky', + 'palesimian', + 'panooch', + 'panti', + 'pearlnecklace', + 'pecker', + 'peckerhead', + 'peckerwood', + 'peedo', + 'peeenus', + 'peeenusss', + 'peehole', + 'peenus', + 'peinus', + 'penas', + 'penile', + 'penisbanger', + 'penis-breath', + 'penises', + 'penisfucker', + 'penispuffer', + 'penus', + 'penuus', + 'perv', + 'perversion', + 'pervert', + 'phonesex', + 'phuc', + 'phuck', + 'phuk', + 'phuked', + 'phuker', + 'phuking', + 'phukked', + 'phukker', + 'phukking', + 'phungky', + 'phuq', + 'pi55', + 'picaninny', + 'piccaninny', + 'pickaninny', + 'pikey', + 'piky', + 'pimper', + 'pimpjuic', + 'pimpjuice', + 'pimpsimp', + 'pindick', + 'piss', + 'pissed', + 'pissed off', + 'pisser', + 'pisses', + 'pissflaps', + 'pisshead', + 'pissin', + 'pissing', + 'pissoff', + 'play boy', + 'playboy', + 'play bunny', + 'playbunny', + 'play girl', + 'playgirl', + 'plumper', + 'pocketpool', + 'polac', + 'polack', + 'polak', + 'polesmoker', + 'pollock', + 'poon', + 'poonani', + 'poonany', + 'poontang', + 'pooperscooper', + 'pooping', + 'poorwhitetrash', + 'poostabber', + 'popimp', + 'porch monkey', + 'porchmonkey', + 'porn', + 'pornflick', + 'pornking', + 'porno', + 'pornprincess', + 'pric', + 'prick', + 'prik', + 'prickhead', + 'prostitute', + 'pu55i', + 'pu55y', + 'pube', + 'pubiclice', + 'puke', + 'punanny', + 'punta', + 'puntang', + 'purinaprincess', + 'pusse', + 'pussee', + 'pussie', + 'pussies', + 'pussy', + 'pussyeater', + 'pussyfucker', + 'pussylicker', + 'pussylicking', + 'pussylips', + 'pussylover', + 'pussypounder', + 'pusy', + 'puto', + 'puuke', + 'puuker', + 'queef', + 'queer', + 'queerbait', + 'queerhole', + 'queers', + 'queerz', + 'quim', + 'qweers', + 'qweerz', + 'qweir', + 'rag head', + 'raghead', + 'raped', + 'rapist', + 'rearend', + 'rearentry', + 'recktum', + 'rectum', + 'redneck', + 'renob', + 'rentafuck', + 'rimjob', + 'rimming', + 'ruski', + 'russki', + 'russkie', + 'sadist', + 'sadom', + 'saeema butt', + 'sandm', + 'sand nigger', + 'sandnigger', + 'scag', + 'scank', + 'scat', + 'schlong', + 'screwing', + 'screwyou', + 'scrote', + 'scrotum', + 'scum', + 'scumbag', + 'seaman staines', + 'semen', + 'sexed', + 'sexfarm', + 'sexhound', + 'sexhouse', + 'sexing', + 'sexkitten', + 'sexpot', + 'sexslave', + 'sextogo', + 'sextoy', + 'sextoys', + 'sexwhore', + 'sexymoma', + 'sexy-slim', + 'seymour butts', + 'shag', + 'shagger', + 'shaggin', + 'shagging', + 'shat', + 'shhit', + 'shit', + 'shitass', + 'shitbag', + 'shitbagger', + 'shitbrains', + 'shitbreath', + 'shitcan', + 'shitcanned', + 'shitcunt', + 'shitdick', + 'shite', + 'shiteater', + 'shited', + 'shiter', + 'shitface', + 'shitfaced', + 'shitfit', + 'shitforbrains', + 'shitfuck', + 'shitfucker', + 'shitfull', + 'shithapens', + 'shithappens', + 'shithead', + 'shithole', + 'shithouse', + 'shiting', + 'shitlist', + 'shitola', + 'shitoutofluck', + 'shits', + 'shitspitter', + 'shitstain', + 'shitted', + 'shitter', + 'shittiest', + 'shitting', + 'shitty', + 'shity', + 'shitz', + 'shiz', + 'shiznit', + 'shortfuck', + 'shyt', + 'shyte', + 'shytty', + 'shyty', + 'sissy', + 'sixsixsix', + 'sixtynine', + 'sixtyniner', + 'skanck', + 'skank', + 'skankbitch', + 'skankee', + 'skankey', + 'skankfuck', + 'skanks', + 'skankwhore', + 'skanky', + 'skankybitch', + 'skankywhore', + 'skeet', + 'skinflute', + 'skullfuck', + 'skum', + 'skumbag', + 'slanteye', + 'slantyeye', + 'slapper', + 'slavedriver', + 'sleezebag', + 'sleezeball', + 'slideitin', + 'slimeball', + 'slimebucket', + 'slopehead', + 'slopey', + 'slopy', + 'slut', + 'slutbag', + 'sluts', + 'slutt', + 'slutting', + 'slutty', + 'slutwear', + 'slutwhore', + 'slutz', + 'smackthemonkey', + 'smeg', + 'smelly', + 'smut', + 'snatch', + 'snatchpatch', + 'snot', + 'snowback', + 'snownigger', + 'sodom', + 'sodomise', + 'sodomite', + 'sodomize', + 'sodomy', + 'son-of-a-bitch', + 'sonofabitch', + 'sonofbitch', + 'spac', + 'spacca', + 'spaghettibender', + 'spaghettinigger', + 'spankthemonkey', + 'spazza', + 'sperm', + 'spermacide', + 'spermbag', + 'spermhearder', + 'spermherder', + 'spic', + 'spick', + 'spig', + 'spigotty', + 'spik', + 'spitter', + 'splittail', + 'splooge', + 'spooge', + 'spook', + 'spreadeagle', + 'squaw', + 'stabber', + 'stiffy', + 'strapon', + 'stripclub', + 'stroking', + 'stupidfuck', + 'stupidfucker', + 'suckass', + 'suckdick', + 'sucker', + 'suckme', + 'suckmyass', + 'suckmydick', + 'suckmytit', + 'suckoff', + 'swastika', + 'tampon', + 'tarbaby', + 'tard', + 'teat', + 'teste', + 'testicle', + 'testicles', + 'thicklips', + 'thicko', + 'thirdeye', + 'thirdleg', + 'threesome', + 'thundercunt', + 'timbernigger', + 'tit', + 'titbitnipply', + 'titfuck', + 'titfucker', + 'titfuckin', + 'titjob', + 'titlicker', + 'titlover', + 'tits', + 'tittie', + 'titties', + 'titty', + 'tittyfuck', + 'tonguethrust', + 'tonguethruster', + 'tonguetramp', + 'torture', + 'tosser', + 'tosspot', + 'towel head', + 'towelhead', + 'trailertrash', + 'tramp', + 'trannie', + 'tranny', + 'trots', + 'trouser snake', + 'tuckahoe', + 'tunneloflove', + 'turd', + 'twat', + 'twatlips', + 'twats', + 'twatwaffle', + 'twink', + 'twinkie', + 'twobitwhore', + 'unclefucker', + 'unfuckable', + 'upskirt', + 'uptheass', + 'upthebutt', + 'urinate', + 'urine', + 'usama bin laden', + 'uterus', + 'vag', + 'vagina', + 'vaginal', + 'vajayjay', + 'vajina', + 'va-j-j', + 'valjina', + 'vibrater', + 'vibrator', + 'vietcong', + 'violate', + 'violation', + 'virginbreaker', + 'vjayjay', + 'vomit', + 'vullva', + 'vulva', + 'wank', + 'wanker', + 'wanking', + 'wankjob', + 'waysted', + 'welcher', + 'wetback', + 'wetspot', + 'whacker', + 'whigger', + 'whiskeydick', + 'whiskydick', + 'whitenigger', + 'whitetrash', + 'whitey', + 'whoor', + 'whop', + 'whore', + 'whorebag', + 'whoreface', + 'whorefucker', + 'whorehouse', + 'wife beater', + 'williewanker', + 'wog', + 'wop', + 'wuss', + 'wuzzie', + 'x-rated', + 'xrated', + 'yellowman', + 'zigabo', + 'zipperhea', + 'zipper head', + ], + ]); + + Config::set('blasp.false_positives', [ + 'en' => [ + 'musicals hit', + 'Scunthorpe', + 'Cockburn', + 'Penistone', + 'Lightwater', + 'Assume', + 'bass', + 'class', + 'Compass', + 'Pass', + 'Dickinson', + 'Middlesex', + 'Cockerel', + 'Butterscotch', + 'Blackcock', + 'Countryside', + 'Arsenal', + 'Flick', + 'Flicker', + 'Analyst', + 'blackCocktail', + ] + ]); + + Config::set('blasp.languages', ['en']); + Config::set('blasp.separators', [' ', '-', '_']); + Config::set('blasp.substitutions', [ '/a/' => ['a', '4', '@', 'Á', 'á', 'À', 'Â', 'à', 'Â', 'â', 'Ä', 'ä', 'Ã', 'ã', 'Å', 'å', 'æ', 'Æ', 'α', 'Δ', 'Λ', 'λ'], '/b/' => ['b', '8', '\\', '3', 'ß', 'Β', 'β'], @@ -45,7 +1371,7 @@ protected function setUp(): void '/p/' => ['p', 'ρ', 'Ρ', '¶', 'þ'], '/q/' => ['q'], '/r/' => ['r', '®'], - '/s/' => ['s', '5', '$', '§', 'ß', 'Ś', 'ś', 'Š', 'š'], + '/s/' => ['s', '5', '\$', '§', 'ß', 'Ś', 'ś', 'Š', 'š'], '/t/' => ['t', 'Τ', 'τ'], '/u/' => ['u', 'υ', 'µ', 'û', 'ü', 'ù', 'ú', 'ū', 'Û', 'Ü', 'Ù', 'Ú', 'Ū'], '/v/' => ['v', 'υ', 'ν'],