go net/url:保留字符的PathEscape处理不一致

41ik7eoe  于 2个月前  发布在  Go
关注(0)|答案(5)|浏览(23)

;, 在 RFC 3986 的路径段中是允许的,但 PathEscape 对它们进行了百分比编码,因为“URI生成应用程序通常使用段中允许的保留字符来分隔特定于方案或解引用处理器的子组件”。然而,它并没有对其他可能受到相同特殊处理的保留字符进行转义:

  • = 通常用于分隔参数和参数值,尤其是与 ;(例如,"name;v=1.1")一起使用。
  • . 用于 ... 中的 "点段",以“指示名称层次结构中的相对位置...在 URI 路径层次结构中解释...作为解析过程的一部分被移除”。
  • : 在相对路径引用的第一个路径段中是不允许的,因为“它会被误认为是方案名”(例如,URI 引用 "foo:bar/baz/quux" 与 "foo-bar/baz/quux" 非常不同)。

你使用的 Go 版本是什么( go version )?

1.11

这个问题在最新版本中是否重现?

是的

你正在使用的操作系统和处理器架构是什么( go env )?

linux amd64

你做了什么?

https://play.golang.org/p/f-byVa3k2gi

pathSegments := []string{"non-scheme:non-authority", "foo=bar;bar=baz", ".."}
for i, segment := range pathSegments {
	pathSegments[i] = url.PathEscape(segment)
}
fmt.Println(strings.Join(pathSegments, "/"))

你期望看到什么?

non-scheme%3Anon-authority/foo%3Dbar%3Bbar%3Dbaz/%2E%2E (所有潜在的特殊字符进行百分比编码),或者可能是 non-scheme:non-authority/foo=bar;bar=baz/.. (除非需要,否则不进行字符百分比编码)。

你看到了什么?

non-scheme:non-authority/foo=bar%3Bbar=baz/..

3wabscal

3wabscal2#

@bradfitz @andybons
我尝试调试最新版本的go1.11 shouldEscape函数,从src/net/url/url.go:101开始:
如果你能确认这个bug确实存在,我们需要修复它,我认为我可以尝试一下:

138:			case encodePathSegment: // §3.3
   139:				// The RFC allows : @ & = + $ but saves / ; , for assigning
   140:				// meaning to individual path segments.
=> 141:				return c == '/' || c == ';' || c == ',' || c == '?'
acruukt9

acruukt93#

实际实现总是RFC和实际使用之间的混合。过去,我们试图严格遵循RFC(#27302),但这给我们带来了麻烦。我相信我们在这里要做的是仅转义那些用作路径段分隔符的字符。
我想知道你是否真的因为这个遇到了问题,还是只是偶然发现了这个问题。
另外,阅读RFC和代码后,我有了一个不同的问题——
@bradfitz - 关于这个评论——
// RFC允许:@&=+$,但为了给单个路径段分配意义而保留了/;,
// 对于参数和参数值。
RFC提到——
例如,分号(";")和等号("=")是保留字符,通常用于分隔适用于该段的参数和参数值。逗号(",")保留字符通常用于类似的目的。
所以,按照这个逻辑,=不应该也被转义吗?因为我们已经在转义,;了吗?或者我可能漏掉了什么?

j0pj023g

j0pj023g4#

我三个月前打开了这个,不记得它引起的问题细节(一个解决方法很简单,没有大惊小怪地实施)。如果你看到有令人信服的理由离开PathEscape的不一致行为(例如,因为net/url的更改在兼容性方面总是有问题),那么就这样吧...但即使在这种情况下,文档也应该更新以提高准确性,例如:
PathEscape对字符串进行转义,以便可以安全地将其放置在URL路径段中。大多数用于URI内分隔数据的保留字符都进行了百分比编码,但出于兼容性原因,以下字符没有进行编码:$ & + = : @
尽管我认为对=进行百分比编码是有意义的,与;,相匹配。

njthzxwz

njthzxwz5#

这是否在之后被检查过?我注意到:没有在pathEscape中转义,如果net/url包中至少有一个函数可以转义所有特殊字符,那就太好了。

相关问题