function soap(string $input, bool $debug = false, bool $skiphook = false) : string
{
    global $session;
    require_once "lib/sanitize.php";
    require_once 'lib/sanitize.php';
    $final_output = $input;
    $output = full_sanitize($input);
    $mix_mask = str_pad('', strlen($output), 'X');
    if (getsetting('soap', 1)) {
        $search = nasty_word_list();
        $exceptions = array_flip(good_word_list());
        $changed_content = false;
        while (list($key, $word) = each($search)) {
            do {
                if ($word > '') {
                    $times = @preg_match_all($word, $output, $matches);
                } else {
                    $times = 0;
                }
                for ($x = 0; $x < $times; $x++) {
                    if (strlen($matches[0][$x]) < strlen($matches[1][$x])) {
                        $shortword = $matches[0][$x];
                        $longword = $matches[1][$x];
                    } else {
                        $shortword = $matches[1][$x];
                        $longword = $matches[0][$x];
                    }
                    if (isset($exceptions[strtolower($longword)])) {
                        $x--;
                        $times--;
                        if ($debug) {
                            output("This word is ok because it was caught by an exception: `b`^%s`7`b`n", $longword);
                        }
                    } else {
                        if ($debug) {
                            output("`7This word is not ok: \"`%%s`7\"; it blocks on the pattern `i%s`i at \"`\$%s`7\".`n", $longword, $word, $shortword);
                        }
                        $len = strlen($shortword);
                        $pad = str_pad('', $len, '_');
                        $p = strpos($output, $shortword);
                        $output = substr($output, 0, $p) . $pad . substr($output, $p + $len);
                        $mix_mask = substr($mix_mask, 0, $p) . $pad . substr($mix_mask, $p + $len);
                        $changed_content = true;
                    }
                }
            } while ($times > 0);
        }
        $y = 0;
        $pad = '#@%$!';
        for ($x = 0; $x < strlen($mix_mask); $x++) {
            while (substr($final_output, $y, 1) == '`') {
                $y += 2;
            }
            if (substr($mix_mask, $x, 1) == '_') {
                $final_output = substr($final_output, 0, $y) . substr($pad, $x % strlen($pad), 1) . substr($final_output, $y + 1);
            }
            $y++;
        }
        if ($session['user']['superuser'] & SU_EDIT_COMMENTS && $changed_content) {
            output("`0The filter would have tripped on \"`#%s`0\" but since you're a moderator, I'm going to be lenient on you.  The text would have read, \"`#%s`0\"`n`n", $input, $final_output);
            return $input;
        } else {
            if ($changed_content && !$skiphook) {
                modulehook('censor', ['input' => $input]);
            }
            return $final_output;
        }
    } else {
        return $final_output;
    }
}
function soap($input, $debug = false, $skiphook = false)
{
    global $session;
    require_once "lib/sanitize.php";
    $final_output = $input;
    // $output is the color code-less (fully sanitized) input against which
    // we search.
    $output = full_sanitize($input);
    // the mask of displayable chars that should be masked out;
    // X displays, _ masks.
    $mix_mask = str_pad("", strlen($output), "X");
    if (getsetting("soap", 1)) {
        $search = nasty_word_list();
        $exceptions = array_flip(good_word_list());
        $changed_content = false;
        while (list($key, $word) = each($search)) {
            do {
                if ($word > "") {
                    $times = preg_match_all($word, $output, $matches);
                } else {
                    $times = 0;
                }
                for ($x = 0; $x < $times; $x++) {
                    if (strlen($matches[0][$x]) < strlen($matches[1][$x])) {
                        $shortword = $matches[0][$x];
                        $longword = $matches[1][$x];
                    } else {
                        $shortword = $matches[1][$x];
                        $longword = $matches[0][$x];
                    }
                    if (isset($exceptions[strtolower($longword)])) {
                        $x--;
                        $times--;
                        if ($debug) {
                            output("This word is ok because it was caught by an exception: `b`^%s`7`b`n", $longword);
                        }
                    } else {
                        if ($debug) {
                            output("`7This word is not ok: \"`%%s`7\"; it blocks on the pattern `i%s`i at \"`\$%s`7\".`n", $longword, $word, $shortword);
                        }
                        // if the word should be filtered, drop it from the
                        // search terms ($output), and mask its bytes out of
                        // the output mask.
                        $len = strlen($shortword);
                        $pad = str_pad("", $len, "_");
                        //while (($p = strpos($output,$shortword))!==false){
                        $p = strpos($output, $shortword);
                        $output = substr($output, 0, $p) . $pad . substr($output, $p + $len);
                        $mix_mask = substr($mix_mask, 0, $p) . $pad . substr($mix_mask, $p + $len);
                        //}
                        $changed_content = true;
                    }
                    //end if
                }
                //end for
            } while ($times > 0);
        }
        $y = 0;
        //position within final output
        $pad = '#@%$!';
        for ($x = 0; $x < strlen($mix_mask); $x++) {
            while (substr($final_output, $y, 1) == "`") {
                $y += 2;
                //when encountering appo encoding, skip over it.
            }
            //this character should be masked out.
            if (substr($mix_mask, $x, 1) == "_") {
                $final_output = substr($final_output, 0, $y) . substr($pad, $x % strlen($pad), 1) . substr($final_output, $y + 1);
            }
            $y++;
        }
        if ($session['user']['superuser'] & SU_EDIT_COMMENTS && $changed_content) {
            output("`0The filter would have tripped on \"`#%s`0\" but since you're a moderator, I'm going to be lenient on you.  The text would have read, \"`#%s`0\"`n`n", $input, $final_output);
            return $input;
        } else {
            if ($changed_content && !$skiphook) {
                modulehook("censor", array("input" => $input));
            }
            return $final_output;
        }
    } else {
        return $final_output;
    }
}