Amb*_*pel 12 mysql perl encoding user-input
我有一个用户将文本输入表单的应用程序.
数据保存到MySQL数据库(排序规则:) utf8_general_ci,然后输出为XML(编码:UTF-8).
问题是人们倾向于从其他来源剪切和粘贴他们的信息,例如,Microsoft Word文档或PDF.
此输入文本通常包含对输出编码不正确的字符,例如"智能引号",来自Windows-1252编码的文档
显然,当转换或处理XML时,这会导致问题,因为字符是非法的.
那么,如何消毒输入?
以前,我使用了一些相当强力的方法,比如"去模糊"脚本,它由一长串搜索和替换操作组成.
这仍然是最好的方法吗?还有其他方法吗?
我可以在表单上设置accept-charset属性并让浏览器为我执行此操作吗?
如果是这样,哪些浏览器会这样做并且可能存在任何问题?
另外,为什么我的数据库接受这些字符,这些字符是UTF-8中的保留/控制字符?
正如你所看到的,我对编码知之甚少,知道我有问题,但我现在有点超出我的深度......
TIA
此输入文本通常包含对输出编码不正确的字符,例如"智能引号",来自Windows-1252编码的文档
"智能引号"(cp1252中的字节147和148)是完全有效的Unicode字符,U + 201C和U + 201D.您的应用程序应该能够无缝地处理它们; 如果没有,你做错了,很可能所有非ASCII字符都会失败.
无论字符是来自某人键入它们还是从Word中粘贴它们的人,浏览器都应该向您的应用程序提交UTF-8编码的字符,这应该将相同的UTF-8字节存储到数据库中.
如果浏览器未以UTF-8提交,则可能无法设置包含表单的HTML页面的字符集.这可以使用:
Content-Type: text/html;charset=utf-8
Run Code Online (Sandbox Code Playgroud)
HTTP标头和/或:
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
Run Code Online (Sandbox Code Playgroud)
<head>中的元素.
我可以在表单上设置accept-charset属性并让浏览器为我执行此操作吗?
不,由于IE的缘故,accept-charset基本没用,它误解了它意味着"如果页面上的那个不能编码我们想要的字符,请尝试使用这个字符集",而不是"总是使用这个字符集".这意味着如果你使用accept-charset,你最终可能会同时提交一系列编码,而无法弄清楚哪个是哪个.太好了!
为什么我的数据库接受这些字符,这些字符是UTF-8中的保留/控制字符?
在MySQL中,UTF-8只是一种排序规则,用于比较和排序.它仍然将数据存储为字节,并不关心它们是否不是有效的UTF-8序列.
最好在你的应用程序中解码和检查传入的UTF-8序列,因为在现代Unicode中无效的"短序列"可以隐藏旧的浏览器仍然可以识别的"<"字符(至少IE6预先SP2,Opera 7).
ETA:
所以,我输入了一个包含字节146的字符串
不,您输入了Unicode字符U + 201B.浏览器处理Unicode字符,而不是字节,直到它必须将序列化表单提交给服务器.然后它决定如何将字符转换为字节,如果页面被处理为UTF-8,它将始终选择UTF-8.
(如果它不是UTF-8,浏览器倾向于以不符合标准的方式作弊:对于所有不适合编码的字符,它会将它们编码为HTML字符引用,如'’'.这是错误的,因为你现在无法区分浏览器转义的'&'和真实的,用户输入的'&'之间的区别,而且这是非常错误的,因为如果你将引用作为未转义的HTML回显它看起来像你'重新做对了,事实上你刚刚做了一个很大的安全漏洞.)
它作为146进入数据库
真的,'\ x92'字节,而不是'\ xC2\x92','\ xE2\x80\x99'或''?
当我生成(UTF-8编码的)XML时,它就出现了146.没有来自浏览器的抱怨
然后它没有作为单个146字节出现.当在XML文件中给出"\ x92"时,浏览器会抱怨.(不是HTML文件,其中无效的UTF-8序列作为缺失字符字形出现.)
我怀疑它是以''出现的.字符引用,格式正确(尽管字符U + 0092是C1控件集的一部分,因此不会呈现为任何有用的内容).如果这是正在发生的事情,那么您的表单页面毕竟不会被选为UTF-8,并且您正遭受上述浏览器自动转义提交问题.