/** * Filter to alter form field values based on fields.xml. Usually a no-op. * * @param string The name of the parameter * @param ?string The current value of the parameter (NULL: none) * @return string The filtered value of the parameter */ function filter_form_field_default($name, $val) { $restrictions = load_field_restrictions(); foreach ($restrictions as $_r => $_restrictions) { $_r_exp = explode(',', $_r); foreach ($_r_exp as $__r) { if (trim($__r) == '' || simulated_wildcard_match($name, trim($__r), true)) { foreach ($_restrictions as $bits) { list($restriction, $attributes) = $bits; if (array_key_exists('error', $attributes) && substr($attributes['error'], 0, 1) == '!') { $attributes['error'] = do_lang(substr($attributes['error'], 1)); } switch (strtolower($restriction)) { case 'minlength': if (strlen($val) < intval($attributes['embed'])) { warn_exit(array_key_exists('error', $attributes) ? make_string_tempcode($attributes['error']) : do_lang_tempcode('FXML_FIELD_TOO_SHORT', escape_html($name), strval(intval($attributes['embed'])))); } break; case 'maxlength': if (strlen($val) > intval($attributes['embed'])) { warn_exit(array_key_exists('error', $attributes) ? make_string_tempcode($attributes['error']) : do_lang_tempcode('FXML_FIELD_TOO_LONG', escape_html($name), strval(intval($attributes['embed'])))); } break; case 'shun': if (simulated_wildcard_match(strtolower($val), strtolower($attributes['embed']), true)) { warn_exit(array_key_exists('error', $attributes) ? make_string_tempcode($attributes['error']) : do_lang_tempcode('FXML_FIELD_SHUNNED', escape_html($name))); } break; case 'pattern': if (preg_match('#' . str_replace('#', '\\#', $attributes['embed']) . '#', $val) == 0) { warn_exit(array_key_exists('error', $attributes) ? make_string_tempcode($attributes['error']) : do_lang_tempcode('FXML_FIELD_PATTERN_FAIL', escape_html($name), escape_html($attributes['embed']))); } break; case 'possibilityset': $values = explode(',', $attributes['embed']); $found = false; foreach ($values as $value) { if ($val == trim($value) || $val == $value || simulated_wildcard_match($val, $value, true)) { $found = true; } } $secretive = array_key_exists('secretive', $attributes) && $attributes['secretive'] == '1'; if (!$found) { warn_exit(array_key_exists('error', $attributes) ? make_string_tempcode($attributes['error']) : do_lang_tempcode($secretive ? 'FXML_FIELD_NOT_IN_SET_SECRETIVE' : 'FXML_FIELD_NOT_IN_SET', escape_html($name), escape_html($attributes['embed']))); } break; case 'disallowedsubstring': if (simulated_wildcard_match(strtolower($val), strtolower($attributes['embed']))) { warn_exit(array_key_exists('error', $attributes) ? make_string_tempcode($attributes['error']) : do_lang_tempcode('FXML_FIELD_SHUNNED_SUBSTRING', escape_html($name), escape_html($attributes['embed']))); } break; case 'disallowedword': if (addon_installed('wordfilter')) { global $WORDS_TO_FILTER; $temp_remember = $WORDS_TO_FILTER; $WORDS_TO_FILTER = array($attributes['embed'] => array('word' => $attributes['embed'], 'w_replacement' => '', 'w_substr' => 0)); require_code('word_filter'); check_word_filter($val, $name, false, true, false); $WORDS_TO_FILTER = $temp_remember; } else { if (strpos($val, $attributes['embed']) !== false) { warn_exit_wordfilter($name, do_lang_tempcode('WORD_FILTER_YOU', escape_html($attributes['embed']))); } // In soviet Russia, words filter you } break; case 'replace': if (!array_key_exists('from', $attributes)) { $val = $attributes['embed']; } else { $val = str_replace($attributes['from'], $attributes['embed'], $val); } break; case 'removeshout': $val = preg_replace_callback('#[^a-z]*[A-Z]{4}[^a-z]*#', 'deshout_callback', $val); break; case 'sentencecase': if (strlen($val) != 0) { $val = strtolower($val); $val[0] = strtoupper($val); // assumes no leading whitespace $val = preg_replace_callback('#[\\.\\!\\?]\\s+[a-z]#m', 'make_sentence_case_callback', $val); } break; case 'titlecase': $val = ucwords(strtolower($val)); break; case 'prepend': if (substr($val, 0, strlen($attributes['embed'])) != $attributes['embed']) { $val = $attributes['embed'] . $val; } break; case 'append': if (substr($val, -strlen($attributes['embed'])) != $attributes['embed']) { $val .= $attributes['embed']; } break; } } } } } return $val; }
/** * Check the specified text ($a) for banned words. * If any are found, and the member cannot bypass the word filter, an error message is displayed. * * @param string The sentence to check * @param ?ID_TEXT The name of the parameter this is coming from. Certain parameters are not checked, for reasons of efficiency (avoiding loading whole word check list if not needed) (NULL: don't know param, do not check to avoid) * @param boolean Whether to avoid dying on fully blocked words (useful if importing, for instance) * @param boolean Whether to try pattern matching (this takes more resources) * @param boolean Whether to allow permission-based skipping, and length-based skipping * @return string "Fixed" version */ function check_word_filter($a, $name = NULL, $no_die = false, $try_patterns = false, $perm_check = true) { global $WORD_FILTERING_ALREADY; if ($WORD_FILTERING_ALREADY) { return $a; } if ($perm_check) { if (strlen($a) < 3) { return $a; } if (function_exists('has_specific_permission') && $GLOBALS['MICRO_AJAX_BOOTUP'] == 0 && has_specific_permission(get_member(), 'bypass_word_filter')) { return $a; } } // Load filter global $WORDS_TO_FILTER; if (is_null($WORDS_TO_FILTER)) { $WORDS_TO_FILTER = array(); $rows = $GLOBALS['SITE_DB']->query_select('wordfilter', array('*'), NULL, '', NULL, NULL, true); if (!is_null($rows)) { foreach ($rows as $i => $r) { if ($i == 0 && !array_key_exists('w_replacement', $r)) { return $a; } // Safe upgrading $WORDS_TO_FILTER[strtolower($r['word'])] = $r; } } } // Find words $words = str_word_count($a, 2); if (is_null($words)) { $words = array(); } // HPHP issue #113 // Apply filter for complete blocked words $changes = array(); foreach ($words as $pos => $word) { if (array_key_exists(strtolower($word), $WORDS_TO_FILTER) && $WORDS_TO_FILTER[strtolower($word)]['w_substr'] == 0) { $w = $WORDS_TO_FILTER[strtolower($word)]; if ($w['w_replacement'] == '' && !$no_die) { warn_exit_wordfilter($name, do_lang_tempcode('WORD_FILTER_YOU', escape_html($word))); // In soviet Russia, words filter you } else { $changes[] = array($pos, $word, $w['w_replacement']); } } if ($try_patterns) { // Now try patterns foreach ($WORDS_TO_FILTER as $word2 => $w) { if ($w['w_substr'] == 0 && simulated_wildcard_match($word, $word2, true)) { if ($w['w_replacement'] == '' && !$no_die) { warn_exit_wordfilter($name, do_lang_tempcode('WORD_FILTER_YOU', escape_html($word))); // In soviet Russia, words filter you } else { $changes[] = array($pos, $word, $w['w_replacement']); } } } } } // Make changes $changes = array_reverse($changes); foreach ($changes as $change) { $before = substr($a, 0, $change[0]); $after = substr($a, $change[0] + strlen($change[1])); $a = $before . $change[2] . $after; } // Apply filter for disallowed substrings foreach ($WORDS_TO_FILTER as $word => $w) { if ($w['w_substr'] == 1 && strpos($a, $word) !== false) { if ($w['w_replacement'] == '' && !$no_die) { warn_exit_wordfilter($name, do_lang_tempcode('WORD_FILTER_YOU', escape_html($word))); } else { $a = preg_replace('#' . preg_quote($word) . '#i', $w['w_replacement'], $a); } } } return $a; }