go 建议:系统调用,x/sys/windows:由于返回类型不合适而弃用CommandLineToArgv函数,

ffx8fchx  于 6个月前  发布在  Go
关注(0)|答案(7)|浏览(67)

你正在使用的Go版本是什么(go version)?
https://pkg.go.dev/golang.org/x/sys@v0.12.0/windows#CommandLineToArgv
你做了什么?
windows.DecomposeCommandLine进行模糊测试,它以前使用windows.CommandLineToArgv如下:

var argc int32
	argv, err := CommandLineToArgv(&utf16CommandLine[0], &argc)
	if err != nil {
		return nil, err
	}
	defer LocalFree(Handle(unsafe.Pointer(argv)))
	var args []string
	for _, v := range (*argv)[:argc] {
		args = append(args, UTF16ToString((*v)[:]))
	}
	return args, nil

你期望看到什么?
CommandLineToArgv返回一个与它的argc返回值一致的返回类型,并与在https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw中记录的签名匹配。
你看到了什么?
Go的CommandLineToArgv Package 器硬编码了返回值的边界,每个边界有8192个条目,每个条目有8192个字符:

func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error)

硬编码的边界是错误的,当调用者尝试通过argc索引到argv时,可能会导致调用者恐慌。(注意@golang/windows)

jtw3ybtb

jtw3ybtb1#

https://go.dev/cl/530275提到了这个问题:windows: convert TestCommandLineRecomposition to a fuzz test and fix discrepancies

kxxlusnw

kxxlusnw2#

我不确定我们应该如何解决这个问题。可选方案包括:

  1. 将它记录为不幸的事情,但保留导出的函数签名不变,因为 almost nobody 直接使用它。
  2. 在不替换的情况下弃用 CommandLineToArgv,并记录调用者应该使用 DecomposeCommandLine 代替。
  3. 弃用 CommandLineToArgv 并用具有更正确签名的新函数(名称待定)替换它。
  4. 对现有的 CommandLineToArgv 进行重大更改,使其返回值具有正确的类型。调用者可以使用类似 argp := (**uint64)(unsafe.Pointer(argv)) 的东西,以便他们的代码在无论使用哪个签名的情况下都能编译通过。
oogrdqng

oogrdqng3#

https://go.dev/cl/531175提到了这个问题:windows: document the return type mismatch for CommandLineToArgv

xuo3flqw

xuo3flqw4#

我不确定我们应该如何解决这个问题。选项包括:
我更喜欢选项2。当前的CommandLineToArgv调用者应该被警告API是错误的,并且废弃它是实现这一目标的好方法。在大多数情况下,DecomposeCommandLine应该是更好的选择。
我也喜欢这样的设计,即寻找CommandLineToArgv的用户会被重定向到DecomposeCommandLine,这在一般情况下更难发现,因为通常人们会尝试用鸭子类型来识别Windows API名称。另一方面,如果我们遵循选项3,即导出CommandLineToArgv2,那么用户在花了一些时间确保他们没有调用不同的Windows API后,就会坚持使用这个API。

pzfprimi

pzfprimi5#

https://go.dev/cl/531176提到了这个问题:windows: remove the 8192-codepoint arg limit in FuzzComposeCommandLine

yyhrrdl8

yyhrrdl86#

这也影响了具有相同 Package 器的 syscall 包:
https://pkg.go.dev/syscall?GOOS=windows#CommandLineToArgv

l2osamch

l2osamch7#

将内容转换为基于选项(2)的提案。该提案具体如下:

  • 废弃 syscall.CommandLineToArgvwindows.CommandLineToArgv ,并建议使用 windows.DecomposeCommandLine 作为替代方案。

相关问题