From eaa684f66833cf5cf0fd778df1ea0eee626c6758 Mon Sep 17 00:00:00 2001 From: Hyleus Date: Fri, 29 Dec 2017 15:58:13 +0100 Subject: [PATCH 1/3] Make LanguageCensor a helper --- .../Middleware => Helpers}/LanguageCensor.php | 37 +++---------------- app/Http/Controllers/ShoutboxController.php | 3 +- resources/views/blocks/chat.blade.php | 7 +++- routes/web.php | 2 +- 4 files changed, 14 insertions(+), 35 deletions(-) rename app/{Http/Middleware => Helpers}/LanguageCensor.php (57%) diff --git a/app/Http/Middleware/LanguageCensor.php b/app/Helpers/LanguageCensor.php similarity index 57% rename from app/Http/Middleware/LanguageCensor.php rename to app/Helpers/LanguageCensor.php index 110c939d45..6842ccfa7b 100644 --- a/app/Http/Middleware/LanguageCensor.php +++ b/app/Helpers/LanguageCensor.php @@ -10,46 +10,19 @@ * @author HDVinnie */ -namespace App\Http\Middleware; +namespace App\Helpers; -use Closure; use Config; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\HttpException; /** * Class LanguageCensor * - * A middleware that can replace or redact(blur) words on a page. + * A class that can redact/replace words. * */ class LanguageCensor { - /** - * Handle an incoming request. - * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @param string|null $ability - * @param string|null $boundModelName - * - * @return mixed - * - * @throws \Symfony\Component\HttpKernel\Exception\HttpException - */ - public function handle($request, Closure $next, $ability = null, $boundModelName = null) - { - $response = $next($request); - - $content = $response->getContent(); - $content = $this->censorResponse($content); - - $response->setContent($content); - - return $response; - } - - protected function matchWords($string, $word) + static protected function matchWords($string, $word) { $result = []; $length = strlen($word); @@ -64,13 +37,13 @@ protected function matchWords($string, $word) } /** - * Censor the request response. + * Censor a text. * * @param $source * * @return mixed */ - protected function censorResponse($source) + static public function censor($source) { $redactArray = Config::get('censor.redact', []); foreach ($redactArray as $word) { diff --git a/app/Http/Controllers/ShoutboxController.php b/app/Http/Controllers/ShoutboxController.php index 88d29974c3..12346c3988 100755 --- a/app/Http/Controllers/ShoutboxController.php +++ b/app/Http/Controllers/ShoutboxController.php @@ -14,6 +14,7 @@ use App\Shoutbox; use App\User; +use App\Helpers\LanguageCensor; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Request; @@ -153,7 +154,7 @@ public function fetch($after = null)  ' . ($message->created_at->diffForHumans()) . '

- ' . \LaravelEmojiOne::toImage(Shoutbox::getMessageHtml($message->message)) . ' + ' . \LaravelEmojiOne::toImage(LanguageCensor::censor(Shoutbox::getMessageHtml($message->message))) . ' ' . ($flag ? $delete : "") . '

'; } diff --git a/resources/views/blocks/chat.blade.php b/resources/views/blocks/chat.blade.php index fd6e52999d..a39a954d93 100644 --- a/resources/views/blocks/chat.blade.php +++ b/resources/views/blocks/chat.blade.php @@ -16,6 +16,11 @@ if (in_array(\Auth::user()->id, explode(',', $message->mentions))) { $class = 'mentioned'; } + + $messageHtml = App\Shoutbox::getMessageHtml($message->message); + $messageHtml = \LaravelEmojiOne::toImage($messageHtml); + $messageHtml = App\Helpers\LanguageCensor::censor($messageHtml); + @endphp
  • @if($message->poster->image != null) @@ -36,7 +41,7 @@ @endif - @emojione(App\Shoutbox::getMessageHtml($message->message))

    + {!! $messageHtml !!}
  • @endforeach diff --git a/routes/web.php b/routes/web.php index 3fd232fc9e..cdfbd82de1 100755 --- a/routes/web.php +++ b/routes/web.php @@ -256,7 +256,7 @@ | ShoutBox Routes Group (when authorized) |------------------------------------------ */ -Route::group(['prefix' => 'shoutbox', 'middleware' => ['auth','censor']], function () { +Route::group(['prefix' => 'shoutbox', 'middleware' => ['auth']], function () { Route::get('/', 'HomeController@home')->name('shoutbox-home'); Route::get('/messages/{after?}', 'ShoutboxController@fetch')->name('shoutbox-fetch'); Route::post('/send', 'ShoutboxController@send')->name('shoutbox-send'); From a12ba2869128c1433f8edf8d968bac5a753bbc7f Mon Sep 17 00:00:00 2001 From: Hyleus Date: Fri, 29 Dec 2017 16:06:00 +0100 Subject: [PATCH 2/3] Fix shoutbox routes --- routes/web.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/web.php b/routes/web.php index cdfbd82de1..7166c3f1ea 100755 --- a/routes/web.php +++ b/routes/web.php @@ -256,7 +256,7 @@ | ShoutBox Routes Group (when authorized) |------------------------------------------ */ -Route::group(['prefix' => 'shoutbox', 'middleware' => ['auth']], function () { +Route::group(['prefix' => 'shoutbox', 'middleware' => 'auth'], function () { Route::get('/', 'HomeController@home')->name('shoutbox-home'); Route::get('/messages/{after?}', 'ShoutboxController@fetch')->name('shoutbox-fetch'); Route::post('/send', 'ShoutboxController@send')->name('shoutbox-send'); From 6bda63e7f196d2688ab867df28b6403b969decec Mon Sep 17 00:00:00 2001 From: Hyleus Date: Fri, 29 Dec 2017 19:25:17 +0100 Subject: [PATCH 3/3] Don't censor words when it is surrounded by special chars --- app/Helpers/LanguageCensor.php | 36 ++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/app/Helpers/LanguageCensor.php b/app/Helpers/LanguageCensor.php index 6842ccfa7b..f545583b5a 100644 --- a/app/Helpers/LanguageCensor.php +++ b/app/Helpers/LanguageCensor.php @@ -22,14 +22,24 @@ */ class LanguageCensor { - static protected function matchWords($string, $word) + static protected function isSpecial($c) + { + $specialChars = " [].;,"; + return strpos($specialChars, $c) !== false; + } + + static protected function matchWordIndexes($string, $word) { $result = []; $length = strlen($word); + $string_length = strlen($string); $pos = stripos($string, $word, 0); while ($pos !== false) { - $match = substr($string, $pos, $length); - array_push($result, $match); + $prev = ($pos === 0) ? ' ' : $string[$pos - 1]; + $last = ($pos + $length) < $string_length ? $string[$pos + $length] : ' '; + if (self::isSpecial($prev) && self::isSpecial($last)) { + array_push($result, $pos); + } $pos = stripos($string, $word, $pos + $length); } @@ -47,10 +57,24 @@ static public function censor($source) { $redactArray = Config::get('censor.redact', []); foreach ($redactArray as $word) { - foreach (self::matchWords($source, $word) as $match) { - $replacement = "{$match}"; - $source = str_replace($match, $replacement, $source); + $result = ""; + $length = strlen($source); + $word_length = strlen($word); + assert($word_length > 0); + $indexes = self::matchWordIndexes($source, $word); + $ignore = 0; + for ($i = 0; $i < $length; ++$i) { + if (count($indexes) > 0 && $indexes[0] == $i) { + $match = substr($source, $indexes[0], $word_length); + $result .= "{$match}"; + $ignore = $word_length - 1; + } elseif ($ignore > 0) { + --$ignore; + } else { + $result .= $source[$i]; + } } + $source = $result; } $replaceDict = Config::get('censor.replace', []);