0 (zero) is breaking while
Permalink
eCMS_Helper_Validation_BannedWords::hasBannedWords method has a while loop in it as
while ($c = $string[$i])
if string has a "0" in it, while breaks in this char. So I changed it to
while ($string[$i] || $string[$i]=="0") {
$c = $string[$i];
.
.
.
}
and it works now.
while ($c = $string[$i])
if string has a "0" in it, while breaks in this char. So I changed it to
while ($string[$i] || $string[$i]=="0") {
$c = $string[$i];
.
.
.
}
and it works now.

Could you show us some code better, like the whole loop? I'm not sure where you've got $i from. Is it a while loop inside a for loop? I'm confused.
Original code was as:
I modified it as:
function hasBannedWords(&$string){ $alpha = "abcdefghijklmnopqrstuvwxyz"; $alpha .= strtoupper($alpha); $start = $end = 0; $ra = 0; $i = 0; $out = 0; while ($c = $string[$i]) { if ($ra) { if (strpos($alpha, $c)!==FALSE) { } else { $ra = 0; $end = $i; $word = substr($string, $start, $end-$start); if ($this->isBannedWord($word)) {
Viewing 15 lines of 44 lines. View entire code block.
I modified it as:
$start = $end = 0; $ra = 0; $i = 0; $out = 0; //MODIFICATION BEGINS while ($string[$i] || $string[$i]=="0") { $c = $string[$i]; //MODIFICATION END if ($ra) {
Found another problem with word replacement. Because string is looped via chars (using integer $i), if replacement is longer than the given word then it returns back to same point with $i. Also if replacement word is shorter than banned word it bypasses following letters. Let me tell you with some examples:
1)
Banned word : "ABC", replacement is "DONT-ABC", Test String: "Is there ABC here?"
In this case when ABC is replaced with DONT-ABC beacuse cursor is waiting on 'T' now, ABC will hit again. This will create an infinite loop.
2) Banned words: "ABCDEF" and "KLM", replacement for "ABCDEF" is "AB", Test String is "is this ABCDEF KLM or what?"
In this case when "ABCDEF" is hit, it will be replaced with "AB" and cursor will be 4 chars away from AB. so "KLM" will be already passed and won't be checked.
To solve both of those problems I modified codeblock as:
Original:
Modified:
1)
Banned word : "ABC", replacement is "DONT-ABC", Test String: "Is there ABC here?"
In this case when ABC is replaced with DONT-ABC beacuse cursor is waiting on 'T' now, ABC will hit again. This will create an infinite loop.
2) Banned words: "ABCDEF" and "KLM", replacement for "ABCDEF" is "AB", Test String is "is this ABCDEF KLM or what?"
In this case when "ABCDEF" is hit, it will be replaced with "AB" and cursor will be 4 chars away from AB. so "KLM" will be already passed and won't be checked.
To solve both of those problems I modified codeblock as:
Original:
function hasBannedWords(&$string){ $alpha = "abcdefghijklmnopqrstuvwxyz"; $alpha .= strtoupper($alpha); $start = $end = 0; $ra = 0; $i = 0; $out = 0; while ($c = $string[$i]) { if ($ra) { if (strpos($alpha, $c)!==FALSE) { } else { $ra = 0; $end = $i; $word = substr($string, $start, $end-$start); if ($this->isBannedWord($word)) {
Viewing 15 lines of 34 lines. View entire code block.
Modified:
function hasBannedWords(&$string){ $alpha = "abcdefghijklmnopqrstuvwxyz"; $alpha .= strtoupper($alpha); $start = $end = 0; $ra = 0; $i = 0; $out = 0; while ($string[$i] || $string[$i]=="0") { $c = $string[$i]; if ($ra) { if (strpos($alpha, $c)!==FALSE) { } else { $ra = 0; $end = $i; $word = substr($string, $start, $end-$start);
Viewing 15 lines of 28 lines. View entire code block.
Hello, Sorry for such a late reply. My fault for being forgetful.
Have you solved the problem yet? If you have then that's brilliant and this will help others with the same problem.
I think the problem is with your while loop. I will admit that I'm not as familiar with PHP as I am with Java, but from lots of examples (especially with databases), they do this.
This works on an array where it starts at the first element and keeps going until is reaches the end.
It's shorthand for this:
The example inhttp://www.php.net/manual/en/control-structures.while.php... is
Please forgive me if I'm wrong as I haven't tested this today, but hopefully this should work.
Also, I've checked "Monitor this Post", so I'll receive an email too which will make me login again if there's another reply here.
Have you solved the problem yet? If you have then that's brilliant and this will help others with the same problem.
I think the problem is with your while loop. I will admit that I'm not as familiar with PHP as I am with Java, but from lots of examples (especially with databases), they do this.
while ($c = $string) { ... }
This works on an array where it starts at the first element and keeps going until is reaches the end.
It's shorthand for this:
$i = 0; while ($i < count($string)) { $c = $string[$i]; ... $i++ }
The example inhttp://www.php.net/manual/en/control-structures.while.php... is
while ($data = mysql_fetch_assoc($requeteID)) { $menu .= '<option value="'.$data['id'].'"'; $menu .= ($data['id'] == $_GET['id'] ? ' selected>' :'>'); $menu .= $data['name'].'</option>'; } echo $menu;
Please forgive me if I'm wrong as I haven't tested this today, but hopefully this should work.
Also, I've checked "Monitor this Post", so I'll receive an email too which will make me login again if there's another reply here.
function hasBannedWords(&$stringRaw) { $allBannedWords = array('blood', 'shi', 'bullo'); $stringLower = strtolower($stringRaw); // For preventing users from avoiding the filter with spaces (optional) $string = str_replace(' ', '', $stringLower); foreach ($allBannedWords as $bannedWord) { if (strpos($string, $bannedWord) !== FALSE) { return TRUE; } } return FALSE; }
This is a cleaner way of doing it.
This won't work as expected. Because:
Assume that "gun" is a banned word but "shotgun" is not. So in your solution above, "shotgun" will also hit TRUE
Assume that "gun" is a banned word but "shotgun" is not. So in your solution above, "shotgun" will also hit TRUE
You are right because I've not taken whole words into consideration. I was really trying to answer about the loops and wanted to be a bit more helpful but have been busy with other things.
To get around the whole word problem, you need to do a pattern match so that you modify your string from:
"AB..;sdRRR323WEAFWEA WEGWEGWEKWE KWEF WER 2r2rr2"
to
" AB sdRRR WEAFWEA WEGWEGWEKWE KWEF WER r rr "
where each sequence of non-letters is replaced by a single space.
Then if the first and/or last letters are not spaces, then you need to add a space at the front and/or at the end respectively so that your string always has spaces at both ends.
Then when looping through your banned words, each banned word needs to have spaces at the ends. This way, you can be sure that a banned word only matches if a banned word in your string is a whole word.
Hope this helps.
To get around the whole word problem, you need to do a pattern match so that you modify your string from:
"AB..;sdRRR323WEAFWEA WEGWEGWEKWE KWEF WER 2r2rr2"
to
" AB sdRRR WEAFWEA WEGWEGWEKWE KWEF WER r rr "
where each sequence of non-letters is replaced by a single space.
Then if the first and/or last letters are not spaces, then you need to add a space at the front and/or at the end respectively so that your string always has spaces at both ends.
Then when looping through your banned words, each banned word needs to have spaces at the ends. This way, you can be sure that a banned word only matches if a banned word in your string is a whole word.
Hope this helps.
Yes, you are right. This seems the exact solution.
That's brilliant. I'm glad I can help. This function will be useful to you:http://www.php.net/preg_replace... for ironing out the non-letters.