Reputation: 5273
I have a textarea
for commenting. I need to allow tags such as '
and \
as well as html
tags (e.g <b> , <i> , <br>
).
I tried htmlspecialchars($comment,ENT_QUOTES);
, but this way '
and \
are allowed but html
tags aren't. That is the input assassin's <b>creed
becomes exactly assassin's <b>creed
. But i need it to become assassin's creed.
Whereas if i don't use htmlspecialchars($comment,ENT_QUOTES);
, assassin's <b>creed
makes trouble... because of the '
. But assassins <b>creed
becomes assassin's creed as it should.
How could i solve this problem?
I hope it's clear enough
Thanks
edit:
This is how it should be:
input: assassin's <b>creed
output: assassin's creed
by using htmlspecialchars
:
input: assassin's <b>creed
output: assassin's <b>creed
without using any functions:
input: assassin's <b>creed
can't insert to database
without using any functions:
input: assassins <b>creed
output: assassins creed
Upvotes: 1
Views: 130
Reputation: 1826
Your best option is to use a library such as htmlpurifier (mentioned in optional's answer). If this isn't an option, a function like the following will allow you to preserve html tags:
function htmlspecialchars_whitelist(
array $whitelist,
$string,
$flags = ENT_COMPAT,
$encoding = 'UTF-8',
$double_encode = true) {
$regex = implode('|', $whitelist);
preg_match_all("#<(?:(?:$regex) ?/?|/(?:$regex))>#", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
$pos = 0;
$buffer = '';
foreach ($matches as $match) {
$off = $match[0][3];
$substr = substr($string, $pos, $off - $pos);
$substr = htmlspecialchars($substr, $flags, $encoding, $double_encode);
$buffer .= $substr;
$buffer .= $match[0][0];
$pos = $off + strlen($match[0][0]);
}
$buffer .= htmlspecialchars(substr($string, $pos), $flags, $encoding, $double_encode);
return $buffer;
}
Example:
$whitelist = array('b', 'strong', 'i', 'em', 'strike', 'br');
$html = "<p>The <strike>quick</strike> \"brown\" <strong>fox</strong> jumped <hr /> 'over' the <em>lazy dog</em>.</p>";
echo htmlspecialchars_whitelist($whitelist, $html, ENT_QUOTES);
// <p>The <strike>quick</strike> "brown" <strong>fox</strong> jumped <hr /> 'over' the <em>lazy dog</em>.</p>
http://phpfiddle.org/main/code/yru-fb1
Note: you must still guard against SQL injection. Phil Cross' answer tackles this.
Upvotes: 0
Reputation: 9302
Your problem is you're using htmlspecialchars()
to escape database data.
This shouldn't be used to escape data destined for a database. It would seem that you are inadvertantly SQL injecting yourself.
As I don't know how your connecting to your database, I'll post a couple of ways to escape your data properly:
mysql Although you shouldn't be using this functionality, as its deprecated and not supported, I'll post how to escape properly:
$data = "Assassin's <b>creed</b>";
$data = mysql_real_escape_string($data);
$result = mysql_query("INSERT INTO .... ");
PDO
$conn = new PDO("{$connection_string}");
$data = "Assassin's <b>Creed</b>";
$conn->prepare("INSERT INTO tbl_games (title) VALUES (?)");
$conn->execute(array($data));
CodeIgniter
$this->db->insert('tbl_games', array('title' => "Assassin's <b>Creed</b>"));
I'm not sure of mysqli functionality (or others).
In any case, you shouldn't need to use htmlspecialchars()
to escape your data.
Either use the database's built in functionality for escaping the data, or research prepared statements.
Upvotes: 1
Reputation: 92
if you want to allow html tags etc you can not sanitize data with htmlspecialchars or similar php functions. You have to use libraries for this purpose (sanitizing data while allowing tags inoffensively) I recommend htmlpurifier
Or you may use WYSIWYG web editors like http://www.tinymce.com/ or http://ckeditor.com/
Upvotes: 0