// note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs $val = preg_replace('/(?:[\x00-\x08][\x0b-\x0c][\x0e-\x20])/', '', $val); // straight replacements, the user should never need these since they're normal characters // this prevents like $search = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()~`";:?+/={}[]-_|\'\\'; $length = strlen($search); for ($i = 0; $i < $length; $i++) { // ;? matches the ;, which is optional // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars // @ @ search for the hex values $val = preg_replace('/(?:&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ; // @ @ 0{0,7} matches '0' zero to seven times $val = preg_replace('/(?:�{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; } // now the only remaining whitespace attacks are \t, \n, and \r $found = true; // keep replacing as long as the previous round replaced something while ($found == true) { $val_before = $val; $ra_length = count($ra); for ($i = 0; $i < $ra_length; $i++) { $pattern = '/'; $ra_str_length = strlen($ra[$i]); for ($j = 0; $j < $ra_str_length; $j++) { $pattern .= '(' . '(?:&#[x|X]0{0,8}([9][a][b]);?)?' . '|(?:�{0,8}([9][10][13]);?)?' . ')?' . $ra[$i][$j]; } $pattern .= '/i'; $replacement = substr($ra[$i], 0, 2).''.substr($ra[$i], 2); // add in <> to nerf the tag $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags if ($val_before == $val) { // no replacements were made, so exit the loop $found = false; } } } return $val; } ?>