サンプルコードを追加
詳細については以下をお読みください。これは、同じ結果を生成するコントローラーに配置できる関数の例です。データベース構造はさらに下に掲載されています。
public function test()
{
if(isset($_POST['comment_original']))
{
$this->load->library('form_validation');
$comment_original = $this->form_validation->xss_clean(html_escape($_POST['comment_original']));
var_dump($comment_original);
$this->db->insert('comments', array(
'comment_set_id' => 2993,
'comment_user_id' => 40,
'comment_original' => $comment_original,
'comment_enabled' => 1,
'comment_is_spam' => 0,
'comment_time_added' => 1358090826,
'comment_time_updated' => 1358090826
));
var_dump($this->db->last_query());
}
$this->output->set_output('<form method="post">
<textarea name="comment_original"></textarea>
<br />
<input type="submit" />
</form>');
}
元の問題
このような文字列をデータベースの TEXT 列に挿入しようとすると、こんにちは。
http://img.chronofoot.com /éric-di-meco/interview-eric-di-meco_66454_w250.jpg
データベースでは次のようになります。
$this->db->last_query() を実行して、Codeigniter が実行しているクエリを表示すると、次のように返されます。
INSERT INTO `comments` (`comment_set_id`, `comment_user_id`, `comment_original`, `comment_html`, `comment_enabled`, `comment_is_spam`, `comment_time_added`, `comment_time_updated`, `comment_ip_address`) VALUES (2993, 40, 'http://img.chronofoot.com/éric-di-meco/interview-eric-di-meco_66454_w250.jpg', 'http://img.chronofoot.com/éric-di-meco/interview-eric-di-meco_66454_w250.jpg', 1, 0, 1358090826, 1358090826, 'XXX')
そのため、挿入を試みる前に削除されていないように見えます。その正確な文字列をphpに入れると、管理者は完全な文字列でうまく挿入されます。
なぜこれが起こっているのか誰にも分かりますか?
追加情報
「é」以降はすべて削除されるため、次のような文字列でも同じことが起こります。
http://img.chronofoot.com /éric-di-meco/interview-eric-di-meco_66454_w250.jpg これは追加のダミー テキストです。
フォームに投稿される文字列は、実際には次のとおりです。
http://img.chronofoot.com/%E9ric-di-meco/interview-eric-di-meco_66454_w250.jpg
しかし、xss_clean は %E9 を é に変換しますが、これは実際には私が望んでいるものではありませんが、コアの xxs_clean 関数に対して何かを行うことを暫定的に考えています。
最後に、これは私のテーブルのように見えますが、違いはないと思います:
CREATE TABLE IF NOT EXISTS `comments` (
`comment_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`comment_set_id` int(10) unsigned NOT NULL,
`comment_user_id` mediumint(6) unsigned NOT NULL,
`comment_original` text NOT NULL,
`comment_html` text NOT NULL,
`comment_attachments` text,
`comment_time_added` int(10) unsigned NOT NULL,
`comment_time_updated` int(10) unsigned NOT NULL,
`comment_enabled` tinyint(1) NOT NULL DEFAULT '1',
`comment_is_spam` tinyint(1) NOT NULL DEFAULT '0',
`comment_has_attachments` tinyint(1) NOT NULL DEFAULT '0',
`comment_has_edits` tinyint(1) NOT NULL DEFAULT '0',
`comment_ip_address` varchar(64) DEFAULT NULL,
PRIMARY KEY (`comment_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
更新された質問: HTML のエスケープ
追加情報が欲しいと思っただけです。
だから私が言ったように、投稿されている実際の文字列はこれです:
http://img.chronofoot.com/%E9ric-di-meco/interview-eric-di-meco_66454_w250.jpg
これは html_escape を通過し、次に xss_clean を通過します。最初に xss_clean を通すと、空の文字列が返されます
var_dump($this->form_validation->xss_clean(html_escape($_POST['comment_original'])))
//Returns http://img.chronofoot.com/éric-di-meco/interview-eric-di-meco_66454_w250.jpg
そして最初に xss_clean
var_dump(html_escape($this->form_validation->xss_clean($_POST['comment_original'])))
//Returns ''
htmlentities は、文字列を次のように変換するという点で、ある方法で解決します。
http://img.chronofoot.com/éric-di-meco/interview-eric-di-meco_66454_w250.jpg
しかし、このフォームはコメントを追加するだけなので、任意の量のテキストと htmlentities を追加できるため、次のようなものが投稿された場合:
これは機能しませんhttp://img.chronofoot.com/%E9ric-di-meco/interview-eric-di-meco_66454_w250.jpg
html_escape() はそれをこれに変換します
これは機能しませんhttp://img.chronofoot.com/%E9ric-di-meco/interview-eric-di-meco_66454_w250.jpg
xss_clean() はそれをこれに変換します
これは機能しませんhttp://img.chronofoot.com /éric-di-meco/interview-eric-di-meco_66454_w250.jpg
そして htmlentities() はこれを次のように変換します:
これは機能しませんhttp://img.chronofoot.com/éric-di-meco/interview-eric-di-meco_66454_w250.jpg
アンパサンドが2回変換されるため、これはもちろん「won't」という単語を破壊します。