fmt#

相关issue:

Errorf函数支持多个%w。更多信息可以看Golang1.20新特性 multi errors

html/template#

相关issue

ES6开始,`可以用于js字面值表示。但html/template目前没有正确地将`按照预期进行处理。

在go1.20.3及其之后的版本,默认情况下,如果模板在js模板字面值中包含Go模板操作,则go直接抛出error,终止模板处理。html/template中增加了GODEBUG标识jstmpllitinterp=1可以恢复原先的行为。

比如模板为

<script>var x = `{{.X}}`;</script>

变量为

map[string]interface{}{"X": "`+alert(1);`"}

js字面值x中包含go的模板变量{{.X}},会抛出panic信息

panic: {{.X}} appears in a JS template literal

完整demo代码可见: jstmpllitinterp demo

math/rand#

相关issue:

在Go1.20之前,我们可以使用math/rand在启动的时候接收一个确定的seed value来生成伪随机数。通常可以是使用当前时间的unix timestamp作为seed value。

rand.Seed(time.Now().UnixNano())

Go1.20之前,没有rand.Seed(time.Now().UnixNano()),以下代码每次执行都会输出相同的随机数。

Go1.20之后,不需要rand.Seed(time.Now().UnixNano()),每次执行都会输出不同的随机数。如果要行为和原先一致,可以使用GODEBUG=randautoseed=0

这是一个 behaviour change

func main() {

    // rand.Seed(time.Now().UnixNano())
    fmt.Println(rand.Int())
}

rand.Seed在1.20之后就被废弃了,虽然按照Go1兼容性需求,应该可以一直使用,但还是建议替换为rand.New(rand.NewSource(seed))

archive/tar && archive/zip#

相关issue

相关CL

GODEBUG=tarinsecurepath=0的时候,tar.Reader.Next方法在碰到一个文件名是1)绝对路径指向 2)超过当前目录的路径 3) 包含非法字符 的时候会返回错误tar.ErrInsecurePath。 但目前默认行为还是和原先一样,未来可能会默认禁用不安全的路径。

GODEBUG=zipinsecurepath=0的时候,zip.NewReader在打开一个压缩文件(archive)的时候,如果文件名 1)绝对路径指向 2)超过当前目录的路径 3) 包含非法字符 的时候,会返回zip.ErrInsecurePath。但目前默认行为还是和原先一样,未来可能会默认禁用不安全的路径。

读取一个包含文件数据的目录文件会返回一个error。 zip规范并不允许目录文件包含文件数据,所以这个变更只会影响非法压缩包的读取。

Demo#

  1. 创建一个不安全的tar文件: tar -cvf unsafe.tar unsafe ../../../Test
  2. 编译二进制文件: cd tar && go build .
  3. 运行二进制文件
    1. ./tar
    2. GODEBUG=tarinsecurepath=0 ./tar

crypto/x509#

相关issue

新增的SetFallbackRoots函数,允许程序设置一组备用的根证书,防止操作系统验证或者标准平台的根包在运行时不可用。它常和新的包golang.org/x/crypto/x509roots/fallback一起使用,提供最新的根包(root bundle)。

time#

相关issue

Parse函数现在直接忽略了低于纳秒精度的数字,而不是将这些数值视为错误。

    const in = "2021-09-29T16:04:33.0000000000Z"
    fmt.Println(time.Parse(time.RFC3339, in))
    fmt.Println(time.Parse(time.RFC3339Nano, in))

    // Go1.19.13
    // 2021-09-29 16:04:33 +0000 UTC <nil>
    // 0001-01-01 00:00:00 +0000 UTC parsing time "2021-09-29T16:04:33.0000000000Z" as "2006-01-02T15:04:05.999999999Z07:00": cannot parse "0Z" as "Z07:00"
    // d

    // Go1.20
    // 2021-09-29 16:04:33 +0000 UTC <nil>
    // 2021-09-29 16:04:33 +0000 UTC <nil>

Parse函数对格式的校验更加严格

    ts, err := time.Parse(time.RFC3339, "2020-04-14T08:13:26--4:00")
    fmt.Printf("%v , %v\n", ts, err)

    // Go1.19
    // 2020-04-14 08:13:26 +0400 +0400 , <nil>

    // Go1.20
    // 0001-01-01 00:00:00 +0000 UTC , parsing time "2020-04-14T08:13:26--4:00" as "2006-01-02T15:04:05Z07:00": cannot parse "--4:00" as "Z07:00"

mime/multipart#

相关issue

In Go 1.19.8(1.20.3) and later, this package sets limits the size of the MIME data it processes to protect against malicious inputs. Reader.NextPart and Reader.NextRawPart limit the number of headers in a part to 10000 and Reader.ReadForm limits the total number of headers in all FileHeaders to 10000. These limits may be adjusted with the GODEBUG=multipartmaxheaders setting. Reader.ReadForm further limits the number of parts in a form to 1000. This limit may be adjusted with the GODEBUG=multipartmaxparts setting.

TODO

disallow anonymous interface cycles#

虽然这不是标准库的变更,但是也可以了解下。

相关issue

这实际是个breaking change,如下代码在go1.19之前编译不会报错。但在go1.20之后,就会报invalid recursive type: anonymous interface refers to itself (see https://go.dev/issue/56103)

受影响的代码需要使用go build -gcflags=all=-d=interfacecycles

Go1.20:Go 编译器默认会拒绝这些接口循环,但可以使用 go build -gcflags=all=-d=interfacecycles 来进行构建,以确保旧代码的正常编译。如果在候选发布期间有人向 Go 团队报告大量损坏,将会取消此更改。 Go1.22:等到 1.22 版本后 -d=interfacecycles 标志将被删除,旧代码将不再构建该特性。如果有人报告问题,将可以讨论或是推迟删除,给予更多的改造时间。

type J interface {
    m(a interface {
        J
    })
}

func main() {
    var j J
    j.m(j)
}

Reference#