最近我因浏览器支持的数据质量而遇到了一个错误,我正在寻找一个安全的规则来应用字符串转义而不需要双倍大小,除非需要。
UTF-8字节序列“E2-80-A8”(U + 2028,LINE SEPARATOR),Unicode数据库中完全有效的字符。但是,该序列表示行分隔符(是,其他则为“0A”)。
很糟糕的是,许多浏览器(包括Chrome,Firefox和Safari;我没有测试其他浏览器)都无法处理一个JSONP回调,其中包含一个包含该Unicode字符的字符串。 JSONP包含在非Unicode HTML中,我没有任何控制权。
浏览器只是在这样的JavaScript上报告了INVALID CODE /语法错误,这些错误从调试工具和所有文本编辑器看起来都是有效的。我猜测它可能会尝试将“E2-80-A8”转换为BIG-5并打破JS语法。
以上只是Unicode如何破坏系统意外情况的一个示例。据我所知,一些黑客可以使用RTL和其他控制字符。 Unicode规范中有许多“引号”,“空格”,“符号”和“控件”。
问题:
是否有一个Unicode字符列表供每个程序员了解我们可能不希望它们在我们的应用程序中有效的隐藏功能(和错误)。 (例如,Windows在文件名中禁用RTL)。
编辑:
我不是要求JSON也不是JavaScript。我要求在所有程序中使用Unicode的一般最佳实践。
答案 0 :(得分:9)
它打破了javascript,因为字符串中不能包含换行符:
var myString = "
";
//SyntaxError: Unexpected token ILLEGAL
现在,UTF-8序列"E2-80-A8"
解码为unicode代码点U+2028
,其被视为类似于javascript中的换行符:
var myString = "
";
//Syntax Error
但是,编写
是安全的var myString = "\u2028";
//you can now log myString in console and get real representation of this character
这是JSON正确编码的内容。我会考虑正确编码JSON,而不是保留不安全字符的黑名单。 (这是U + 2028和U + 2029 AFAIK)。
在PHP中:
echo json_encode( chr(0xe2). chr(0x80).chr(0xA8 ) );
//"\u2028"
答案 1 :(得分:4)
查看Unicode图表。有一个非打印字符列表。这些是潜在的麻烦制造者。你的朋友U + 2028有很多朋友:http://www.unicode.org/charts/PDF/U2000.pdf而且它不只是在2000年范围内。
你可以将它们全部核对,或者将它们分成不同的类别(例如U + 2028成为\ n或正确转义的SEP字符等)。
HTH
答案 2 :(得分:4)
有一个字符属性数据库和一个描述它的报告,UNICODE CHARACTER DATABASE,可以很好地了解浏览器“应该”如何处理代码点。我爱这个词,“应该”。最安全的是白名单,你可以选择L | M | N | S,Letter或Mark或Number或Symbol。
查看图书馆的ICU project
答案 3 :(得分:3)
A-Z,a-z和0-9通常是安全的。在这62个字符之外,您将遇到某些系统的问题。任何人都无法给你答案。
例如,您提到了域名。处理Unicode域名的唯一方法是遵循RFC 3454和RFC 5890-5893,并以这种方式处理数据。大多数Unix文件系统上的文件名是不包含/或\ 0的任意字节字符串。功能上将Unix上的文件名作为Unicode字符串处理而不会破坏任何内容本身就是一个问题。请注意,Windows文件名不是A-Z安全的; NUL和PRN之类的东西都是保留名称。每个领域都会遇到自己的小问题和怪癖,没有简单的总结就足以满足各地的需求。