提问人:ændrük 提问时间:9/25/2022 最后编辑:Bergiændrük 更新时间:12/15/2022 访问量:678
为什么 / 🌈 是无效的路径,而 /a🌈 是有效的?
Why is /🌈 an invalid path when /a🌈 is valid?
问:
我试图理解为什么某些 HTML 属性无法通过 W3C 验证。我在真实的代码库中遇到了这种情况,但这里有一个最小的复制:
<!DOCTYPE html><html lang="en"><head><title>a</title></head><body>
<img alt="1" src="⭐">
<img alt="2" src="/⭐">
<img alt="3" src="/a⭐">
<img alt="4" src="/a/⭐">
<img alt="5" src="🌈">
<img alt="6" src="/🌈"> <!-- Only this is invalid. -->
<img alt="7" src="/a🌈">
<img alt="8" src="/a/🌈">
</body></html>
W3C 验证器仅报告一个错误,影响第六个图像:
错误:元素上的属性值错误:不允许路径段中的非法字符。
/🌈
src
img
?
<img alt="6" src="/🌈">
为什么只有一个问题,而其他问题却没有?它有什么不同?
答:
问题中描述的行为是由现已修复的检查器(验证器)代码中的错误引起的;请参阅 https://github.com/validator/galimatias/pull/2。由于测试套件没有涵盖以斜杠开头的相对 URL 后跟大于 U+FFFF 的代码点的情况,因此该错误被忽视了——就像问题中的 U+1F30 🌈(彩虹)字符一样。因此,测试套件也进行了更新,以增加对该情况的覆盖范围;请参见 https://github.com/web-platform-tests/wpt/pull/36213。
顺便说一句,U+2b50 (⭐) 案例没有受到 bug 的影响,而 U+1F308 () 案例的原因是:Java 使用 UTF-16,而 U+1F308 在所谓的补充字符范围内(🌈即 U+FFFF 上方的代码点集),因此——如上面的评论中所述——在 UTF-16 中,代码点 U+1F308 由两个 char
值的代理对表示,而 U+2b50 表示单个值。char
值数的差异影响 URL 解析方式的原因是 HTML 检查器的 URL 解析代码中的状态机维护字符索引并在状态更改期间递减它。因此,如果它正在处理一个可以包含高于 U+FFFF 的代码点的 URL 段,它必须明智地决定它减少了多少个字符 - 对于高于 U+FFFF 的代码点,它需要将其减少 2,否则减少 1。char
为此,代码有一个调用 Character.charCount
() 的 decrIdx()
方法:
Determines the number of values needed to represent the specified character (Unicode code point). If the specified character is equal to or greater than 0x10000, then the method returns 2. Otherwise, the method returns 1.
char
So the code change that got made to the checker replaced a simple decrementing of the index value with a smarter -enabled decrIdx()
call.idx--
Character.charCount()
评论