@ttsc/darwin-x64 0.33.0-next.1 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/go/VERSION +2 -2
- package/bin/go/bin/go +0 -0
- package/bin/go/bin/gofmt +0 -0
- package/bin/go/pkg/tool/darwin_amd64/asm +0 -0
- package/bin/go/pkg/tool/darwin_amd64/cgo +0 -0
- package/bin/go/pkg/tool/darwin_amd64/compile +0 -0
- package/bin/go/pkg/tool/darwin_amd64/cover +0 -0
- package/bin/go/pkg/tool/darwin_amd64/fix +0 -0
- package/bin/go/pkg/tool/darwin_amd64/link +0 -0
- package/bin/go/pkg/tool/darwin_amd64/preprofile +0 -0
- package/bin/go/pkg/tool/darwin_amd64/vet +0 -0
- package/bin/go/src/crypto/internal/fips140/mlkem/cast.go +66 -36
- package/bin/go/src/crypto/internal/fips140/mlkem/mlkem768.go +6 -0
- package/bin/go/src/crypto/tls/ech.go +18 -4
- package/bin/go/src/go.mod +1 -1
- package/bin/go/src/go.sum +2 -2
- package/bin/go/src/html/template/js.go +8 -3
- package/bin/go/src/html/template/transition.go +8 -1
- package/bin/go/src/internal/buildcfg/zbootstrap.go +1 -1
- package/bin/go/src/internal/godebugs/table.go +1 -0
- package/bin/go/src/internal/poll/fd_windows.go +21 -1
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_arm.go +3 -3
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_arm64.go +3 -3
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_loong64.go +2 -2
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_mips64x.go +2 -2
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_mipsx.go +1 -1
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_ppc64x.go +2 -2
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_riscv64.go +2 -2
- package/bin/go/src/internal/runtime/syscall/linux/defs_linux_s390x.go +2 -2
- package/bin/go/src/internal/syscall/windows/at_windows.go +91 -15
- package/bin/go/src/internal/syscall/windows/types_windows.go +8 -1
- package/bin/go/src/mime/multipart/formdata.go +4 -5
- package/bin/go/src/net/http/fs.go +28 -0
- package/bin/go/src/net/http/h2_bundle.go +278 -133
- package/bin/go/src/net/http/httputil/reverseproxy.go +15 -0
- package/bin/go/src/net/http/server.go +23 -3
- package/bin/go/src/net/http/transport.go +6 -1
- package/bin/go/src/net/textproto/reader.go +9 -7
- package/bin/go/src/os/file_windows.go +7 -3
- package/bin/go/src/os/root_openat.go +5 -5
- package/bin/go/src/os/root_unix.go +4 -0
- package/bin/go/src/os/root_windows.go +8 -2
- package/bin/go/src/runtime/metrics/doc.go +5 -0
- package/bin/go/src/runtime/netpoll_epoll.go +20 -7
- package/bin/go/src/runtime/os_windows.go +23 -0
- package/bin/go/src/vendor/modules.txt +1 -1
- package/bin/ttsc +0 -0
- package/bin/ttsc-cache +0 -0
- package/bin/ttscserver +0 -0
- package/package.json +1 -1
package/bin/go/VERSION
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
go1.26.
|
|
2
|
-
time 2026-
|
|
1
|
+
go1.26.9
|
|
2
|
+
time 2026-10-02T20:28:03Z
|
package/bin/go/bin/go
CHANGED
|
Binary file
|
package/bin/go/bin/gofmt
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -8,45 +8,75 @@ import (
|
|
|
8
8
|
"bytes"
|
|
9
9
|
"crypto/internal/fips140"
|
|
10
10
|
_ "crypto/internal/fips140/check"
|
|
11
|
+
"crypto/internal/fips140/sha256"
|
|
11
12
|
"errors"
|
|
12
13
|
"sync"
|
|
13
14
|
)
|
|
14
15
|
|
|
15
16
|
var fipsSelfTest = sync.OnceFunc(func() {
|
|
16
|
-
fips140.CAST("ML-KEM-768",
|
|
17
|
-
var d = &[32]byte{
|
|
18
|
-
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
|
19
|
-
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
|
20
|
-
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
|
21
|
-
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
|
22
|
-
}
|
|
23
|
-
var z = &[32]byte{
|
|
24
|
-
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
|
25
|
-
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
|
26
|
-
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
|
27
|
-
0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
|
|
28
|
-
}
|
|
29
|
-
var m = &[32]byte{
|
|
30
|
-
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
|
31
|
-
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
|
32
|
-
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
|
33
|
-
0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
|
|
34
|
-
}
|
|
35
|
-
var K = []byte{
|
|
36
|
-
0x55, 0x01, 0xfc, 0x52, 0x3b, 0x74, 0x5f, 0x41,
|
|
37
|
-
0x76, 0x2a, 0x18, 0x8d, 0xe4, 0x4a, 0x59, 0xb9,
|
|
38
|
-
0x20, 0xf4, 0x30, 0x14, 0x62, 0x04, 0xee, 0x4e,
|
|
39
|
-
0x79, 0x37, 0x32, 0x39, 0x6d, 0xf7, 0xaa, 0x48,
|
|
40
|
-
}
|
|
41
|
-
dk := &DecapsulationKey768{}
|
|
42
|
-
kemKeyGen(dk, d, z)
|
|
43
|
-
ek := dk.EncapsulationKey()
|
|
44
|
-
var cc [CiphertextSize768]byte
|
|
45
|
-
Ke, _ := kemEncaps(&cc, ek, m)
|
|
46
|
-
Kd := kemDecaps(dk, &cc)
|
|
47
|
-
if !bytes.Equal(Ke, K) || !bytes.Equal(Kd, K) {
|
|
48
|
-
return errors.New("unexpected result")
|
|
49
|
-
}
|
|
50
|
-
return nil
|
|
51
|
-
})
|
|
17
|
+
fips140.CAST("ML-KEM-768", fips140CAST)
|
|
52
18
|
})
|
|
19
|
+
|
|
20
|
+
// fips140CAST covers both the successful and the implicit rejection paths, as
|
|
21
|
+
// required by IG 10.3.A, Resolution 14, and as tested by TestCASTRejectionPath.
|
|
22
|
+
// It tests only one parameter set as allowed by Note22. It compares dk and not
|
|
23
|
+
// ek, because ek is part of dk, as allowed by the same Resolution. It compares
|
|
24
|
+
// dk with an expected hash to avoid embedding several kilobytes of test vectors
|
|
25
|
+
// in every binary, as allowed by GeneralNote7.
|
|
26
|
+
func fips140CAST() error {
|
|
27
|
+
var d = &[32]byte{
|
|
28
|
+
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
|
29
|
+
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
|
30
|
+
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
|
31
|
+
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
|
32
|
+
}
|
|
33
|
+
var z = &[32]byte{
|
|
34
|
+
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
|
35
|
+
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
|
36
|
+
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
|
37
|
+
0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
|
|
38
|
+
}
|
|
39
|
+
var dkHash = []byte{
|
|
40
|
+
0xa1, 0x32, 0x4a, 0x71, 0xf5, 0x7e, 0x26, 0x85,
|
|
41
|
+
0x37, 0x7e, 0x4f, 0x7d, 0xe2, 0xd1, 0xf0, 0x58,
|
|
42
|
+
0x53, 0x8e, 0x08, 0x7e, 0xe3, 0x9b, 0x48, 0x2b,
|
|
43
|
+
0x3d, 0xbf, 0x96, 0xf9, 0xf7, 0x69, 0xc7, 0x85,
|
|
44
|
+
}
|
|
45
|
+
var m = &[32]byte{
|
|
46
|
+
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
|
47
|
+
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
|
48
|
+
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
|
49
|
+
0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
|
|
50
|
+
}
|
|
51
|
+
var K = []byte{
|
|
52
|
+
0x55, 0x01, 0xfc, 0x52, 0x3b, 0x74, 0x5f, 0x41,
|
|
53
|
+
0x76, 0x2a, 0x18, 0x8d, 0xe4, 0x4a, 0x59, 0xb9,
|
|
54
|
+
0x20, 0xf4, 0x30, 0x14, 0x62, 0x04, 0xee, 0x4e,
|
|
55
|
+
0x79, 0x37, 0x32, 0x39, 0x6d, 0xf7, 0xaa, 0x48,
|
|
56
|
+
}
|
|
57
|
+
var Kr = []byte{
|
|
58
|
+
0x01, 0xa1, 0x03, 0x3a, 0x2e, 0x68, 0x33, 0x80,
|
|
59
|
+
0x7f, 0xd3, 0x91, 0x80, 0xbe, 0x3b, 0x4f, 0x0a,
|
|
60
|
+
0x1f, 0x6f, 0x50, 0x51, 0x67, 0x56, 0x9d, 0x0e,
|
|
61
|
+
0x5e, 0x5e, 0x1f, 0xdb, 0x52, 0xa9, 0x10, 0xec,
|
|
62
|
+
}
|
|
63
|
+
dk := &DecapsulationKey768{}
|
|
64
|
+
kemKeyGen(dk, d, z)
|
|
65
|
+
ek := dk.EncapsulationKey()
|
|
66
|
+
H := sha256.New()
|
|
67
|
+
H.Write(TestingOnlyExpandedBytes768(dk))
|
|
68
|
+
if !bytes.Equal(H.Sum(nil), dkHash) {
|
|
69
|
+
return errors.New("unexpected private key hash")
|
|
70
|
+
}
|
|
71
|
+
var cc [CiphertextSize768]byte
|
|
72
|
+
Kd := kemDecaps(dk, &cc)
|
|
73
|
+
if !bytes.Equal(Kd, Kr) {
|
|
74
|
+
return errors.New("unexpected rejection result")
|
|
75
|
+
}
|
|
76
|
+
Ke, _ := kemEncaps(&cc, ek, m)
|
|
77
|
+
Kd = kemDecaps(dk, &cc)
|
|
78
|
+
if !bytes.Equal(Ke, K) || !bytes.Equal(Kd, K) {
|
|
79
|
+
return errors.New("unexpected result")
|
|
80
|
+
}
|
|
81
|
+
return nil
|
|
82
|
+
}
|
|
@@ -469,6 +469,8 @@ func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte,
|
|
|
469
469
|
return kemDecaps(dk, c), nil
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
+
var testingOnlyRejectionOutcome func(int)
|
|
473
|
+
|
|
472
474
|
// kemDecaps produces a shared key from a ciphertext.
|
|
473
475
|
//
|
|
474
476
|
// It implements ML-KEM.Decaps_internal according to FIPS 203, Algorithm 18.
|
|
@@ -488,6 +490,10 @@ func kemDecaps(dk *DecapsulationKey768, c *[CiphertextSize768]byte) (K []byte) {
|
|
|
488
490
|
var cc [CiphertextSize768]byte
|
|
489
491
|
c1 := pkeEncrypt(&cc, &dk.encryptionKey, (*[32]byte)(m), r)
|
|
490
492
|
|
|
493
|
+
if testingOnlyRejectionOutcome != nil {
|
|
494
|
+
testingOnlyRejectionOutcome(subtle.ConstantTimeCompare(c[:], c1))
|
|
495
|
+
}
|
|
496
|
+
|
|
491
497
|
subtle.ConstantTimeCopy(subtle.ConstantTimeCompare(c[:], c1), Kout, Kprime)
|
|
492
498
|
return Kout
|
|
493
499
|
}
|
|
@@ -308,6 +308,7 @@ func decodeInnerClientHello(outer *clientHelloMsg, encoded []byte) (*clientHello
|
|
|
308
308
|
recon.AddBytes(compressionMethods)
|
|
309
309
|
})
|
|
310
310
|
recon.AddUint16LengthPrefixed(func(recon *cryptobyte.Builder) {
|
|
311
|
+
var outerExtensionsSeen bool
|
|
311
312
|
for !extensions.Empty() {
|
|
312
313
|
var extension uint16
|
|
313
314
|
var extData cryptobyte.String
|
|
@@ -317,18 +318,30 @@ func decodeInnerClientHello(outer *clientHelloMsg, encoded []byte) (*clientHello
|
|
|
317
318
|
return
|
|
318
319
|
}
|
|
319
320
|
if extension == extensionECHOuterExtensions {
|
|
320
|
-
if
|
|
321
|
+
if outerExtensionsSeen {
|
|
322
|
+
recon.SetError(errors.New("tls: invalid outer extensions"))
|
|
323
|
+
return
|
|
324
|
+
}
|
|
325
|
+
outerExtensionsSeen = true
|
|
326
|
+
var outerExtensions cryptobyte.String
|
|
327
|
+
if !extData.ReadUint8LengthPrefixed(&outerExtensions) || !extData.Empty() ||
|
|
328
|
+
outerExtensions.Empty() {
|
|
321
329
|
recon.SetError(errors.New("tls: invalid inner client hello"))
|
|
322
330
|
return
|
|
323
331
|
}
|
|
332
|
+
// OuterExtensions reconstruction per RFC 9849, Appendix A.
|
|
333
|
+
// i scans the outer extensions in order and never rewinds,
|
|
334
|
+
// so a referenced type that is out of order or duplicated
|
|
335
|
+
// cannot be found again and is rejected.
|
|
324
336
|
var i int
|
|
325
|
-
for !
|
|
337
|
+
for !outerExtensions.Empty() {
|
|
326
338
|
var extType uint16
|
|
327
|
-
if !
|
|
339
|
+
if !outerExtensions.ReadUint16(&extType) {
|
|
328
340
|
recon.SetError(errors.New("tls: invalid inner client hello"))
|
|
329
341
|
return
|
|
330
342
|
}
|
|
331
|
-
if extType == extensionEncryptedClientHello
|
|
343
|
+
if extType == extensionEncryptedClientHello ||
|
|
344
|
+
extType == extensionECHOuterExtensions {
|
|
332
345
|
recon.SetError(errors.New("tls: invalid outer extensions"))
|
|
333
346
|
return
|
|
334
347
|
}
|
|
@@ -345,6 +358,7 @@ func decodeInnerClientHello(outer *clientHelloMsg, encoded []byte) (*clientHello
|
|
|
345
358
|
recon.AddUint16LengthPrefixed(func(recon *cryptobyte.Builder) {
|
|
346
359
|
recon.AddBytes(rawOuterExts[i].data)
|
|
347
360
|
})
|
|
361
|
+
i++
|
|
348
362
|
}
|
|
349
363
|
} else {
|
|
350
364
|
recon.AddUint16(extension)
|
package/bin/go/src/go.mod
CHANGED
package/bin/go/src/go.sum
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
golang.org/x/crypto v0.46.1-0.20251210140736-7dacc380ba00 h1:JgcPM1rzpSOZS8y69FQvnY0xN0ciHlpQqwTXJcuZIA4=
|
|
2
2
|
golang.org/x/crypto v0.46.1-0.20251210140736-7dacc380ba00/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
|
3
|
-
golang.org/x/net v0.47.1-0.
|
|
4
|
-
golang.org/x/net v0.47.1-0.
|
|
3
|
+
golang.org/x/net v0.47.1-0.20260925170545-1431957440b7 h1:5FtxsBBG4SLV2/Vvvf3+wW2NIHWR7CSbJfn9byVKwPk=
|
|
4
|
+
golang.org/x/net v0.47.1-0.20260925170545-1431957440b7/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
|
5
5
|
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
|
6
6
|
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
|
7
7
|
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
|
@@ -96,7 +96,10 @@ func nextJSCtx(s []byte, preceding jsCtx) jsCtx {
|
|
|
96
96
|
for j > 0 && isJSIdentPart(rune(s[j-1])) {
|
|
97
97
|
j--
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
// An IdentifierName after a property-access dot is a property name,
|
|
100
|
+
// which precedes a div op.
|
|
101
|
+
if regexpPrecederKeywords[string(s[j:])] &&
|
|
102
|
+
!bytes.HasSuffix(bytes.TrimRight(s[:j], jsWhitespace), []byte(".")) {
|
|
100
103
|
return jsCtxRegexp
|
|
101
104
|
}
|
|
102
105
|
}
|
|
@@ -106,8 +109,9 @@ func nextJSCtx(s []byte, preceding jsCtx) jsCtx {
|
|
|
106
109
|
return jsCtxDivOp
|
|
107
110
|
}
|
|
108
111
|
|
|
109
|
-
// regexpPrecederKeywords is a set of
|
|
110
|
-
//
|
|
112
|
+
// regexpPrecederKeywords is a set of JS keywords that can precede a regular
|
|
113
|
+
// expression in JS source. It deliberately treats the context-sensitive
|
|
114
|
+
// keyword yield as a keyword.
|
|
111
115
|
var regexpPrecederKeywords = map[string]bool{
|
|
112
116
|
"break": true,
|
|
113
117
|
"case": true,
|
|
@@ -123,6 +127,7 @@ var regexpPrecederKeywords = map[string]bool{
|
|
|
123
127
|
"try": true,
|
|
124
128
|
"typeof": true,
|
|
125
129
|
"void": true,
|
|
130
|
+
"yield": true,
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
var jsonMarshalType = reflect.TypeFor[json.Marshaler]()
|
|
@@ -331,7 +331,14 @@ func tJS(c context, s []byte) (context, int) {
|
|
|
331
331
|
case '#':
|
|
332
332
|
if i+1 < len(s) && s[i+1] == '!' {
|
|
333
333
|
c.state, i = stateJSLineCmt, i+1
|
|
334
|
+
break
|
|
335
|
+
}
|
|
336
|
+
// A private identifier such as #yield is never a keyword, and
|
|
337
|
+
// precedes a div op.
|
|
338
|
+
for i+1 < len(s) && isJSIdentPart(rune(s[i+1])) {
|
|
339
|
+
i++
|
|
334
340
|
}
|
|
341
|
+
c.jsCtx = jsCtxDivOp
|
|
335
342
|
case '{':
|
|
336
343
|
// We only care about tracking brace depth if we are inside of a
|
|
337
344
|
// template literal.
|
|
@@ -382,7 +389,7 @@ func tJSTmpl(c context, s []byte) (context, int) {
|
|
|
382
389
|
case '$':
|
|
383
390
|
if len(s) >= i+2 && s[i+1] == '{' {
|
|
384
391
|
c.jsBraceDepth = append(c.jsBraceDepth, 0)
|
|
385
|
-
c.state = stateJS
|
|
392
|
+
c.state, c.jsCtx = stateJS, jsCtxRegexp
|
|
386
393
|
return c, i + 2
|
|
387
394
|
}
|
|
388
395
|
case '`':
|
|
@@ -15,7 +15,7 @@ const DefaultGORISCV64 = `rva20u64`
|
|
|
15
15
|
const defaultGOEXPERIMENT = ``
|
|
16
16
|
const defaultGO_EXTLINK_ENABLED = ``
|
|
17
17
|
const defaultGO_LDSO = ``
|
|
18
|
-
const version = `go1.26.
|
|
18
|
+
const version = `go1.26.9`
|
|
19
19
|
const defaultGOOS = runtime.GOOS
|
|
20
20
|
const defaultGOARCH = runtime.GOARCH
|
|
21
21
|
const DefaultGOFIPS140 = `off`
|
|
@@ -49,6 +49,7 @@ var All = []Info{
|
|
|
49
49
|
{Name: "httplaxcontentlength", Package: "net/http", Changed: 22, Old: "1"},
|
|
50
50
|
{Name: "httpmuxgo121", Package: "net/http", Changed: 22, Old: "1"},
|
|
51
51
|
{Name: "httpservecontentkeepheaders", Package: "net/http", Changed: 23, Old: "1"},
|
|
52
|
+
{Name: "httpservecontentmaxranges", Package: "net/http", Changed: 26, Old: "1"},
|
|
52
53
|
{Name: "installgoroot", Package: "go/build"},
|
|
53
54
|
{Name: "jstmpllitinterp", Package: "html/template", Opaque: true}, // bug #66217: remove Opaque
|
|
54
55
|
//{Name: "multipartfiles", Package: "mime/multipart"},
|
|
@@ -382,6 +382,10 @@ type FD struct {
|
|
|
382
382
|
// message based socket connection.
|
|
383
383
|
ZeroReadIsEOF bool
|
|
384
384
|
|
|
385
|
+
// KeepFileCompletionModes prevents Init from changing the file object's
|
|
386
|
+
// completion notification modes.
|
|
387
|
+
KeepFileCompletionModes bool
|
|
388
|
+
|
|
385
389
|
// Whether the handle is owned by os.File.
|
|
386
390
|
isFile bool
|
|
387
391
|
|
|
@@ -469,6 +473,22 @@ func (fd *FD) Init(net string, pollable bool) error {
|
|
|
469
473
|
return nil
|
|
470
474
|
}
|
|
471
475
|
|
|
476
|
+
if fd.KeepFileCompletionModes {
|
|
477
|
+
// Query the existing skip-success mode so we don't wait for a
|
|
478
|
+
// suppressed completion or skip waiting for an expected one.
|
|
479
|
+
var info windows.FILE_IO_COMPLETION_NOTIFICATION_INFORMATION
|
|
480
|
+
if err := windows.NtQueryInformationFile(fd.Sysfd, &windows.IO_STATUS_BLOCK{},
|
|
481
|
+
unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), windows.FileIoCompletionNotificationInformation); err != nil {
|
|
482
|
+
// Without knowing the modes, neither waiting for a completion
|
|
483
|
+
// packet on success nor skipping it is safe. Leave the handle
|
|
484
|
+
// unassociated and use explicit events for pending I/O instead.
|
|
485
|
+
// Inline success needs no wait, and deadlines are unavailable.
|
|
486
|
+
fd.skipSyncNotif = true
|
|
487
|
+
return nil
|
|
488
|
+
}
|
|
489
|
+
fd.skipSyncNotif = info.Flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0
|
|
490
|
+
}
|
|
491
|
+
|
|
472
492
|
// It is safe to add overlapped handles that also perform I/O
|
|
473
493
|
// outside of the runtime poller. The runtime poller will ignore
|
|
474
494
|
// I/O completion notifications not initiated by us.
|
|
@@ -476,7 +496,7 @@ func (fd *FD) Init(net string, pollable bool) error {
|
|
|
476
496
|
if err != nil {
|
|
477
497
|
return err
|
|
478
498
|
}
|
|
479
|
-
if fd.kind != kindNet || socketCanUseSetFileCompletionNotificationModes {
|
|
499
|
+
if !fd.KeepFileCompletionModes && (fd.kind != kindNet || socketCanUseSetFileCompletionNotificationModes) {
|
|
480
500
|
// Non-socket handles can use SetFileCompletionNotificationModes without problems.
|
|
481
501
|
err := syscall.SetFileCompletionNotificationModes(fd.Sysfd,
|
|
482
502
|
syscall.FILE_SKIP_SET_EVENT_ON_HANDLE|syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,
|
|
@@ -6,6 +6,7 @@ package windows
|
|
|
6
6
|
|
|
7
7
|
import (
|
|
8
8
|
"internal/oserror"
|
|
9
|
+
"internal/stringslite"
|
|
9
10
|
"runtime"
|
|
10
11
|
"structs"
|
|
11
12
|
"syscall"
|
|
@@ -141,19 +142,27 @@ func Openat(dirfd syscall.Handle, name string, flag uint64, perm uint32) (_ sysc
|
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
var h syscall.Handle
|
|
144
|
-
err
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
145
|
+
var err error
|
|
146
|
+
if TestOpenatFallback && flag&O_NOFOLLOW_ANY != 0 {
|
|
147
|
+
err = STATUS_INVALID_PARAMETER
|
|
148
|
+
} else {
|
|
149
|
+
err = NtCreateFile(
|
|
150
|
+
&h,
|
|
151
|
+
SYNCHRONIZE|access,
|
|
152
|
+
objAttrs,
|
|
153
|
+
&IO_STATUS_BLOCK{},
|
|
154
|
+
nil,
|
|
155
|
+
fileAttrs,
|
|
156
|
+
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
|
157
|
+
disposition,
|
|
158
|
+
FILE_OPEN_FOR_BACKUP_INTENT|options,
|
|
159
|
+
nil,
|
|
160
|
+
0,
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
if err == STATUS_INVALID_PARAMETER && flag&O_NOFOLLOW_ANY != 0 {
|
|
164
|
+
h, err = openatFallback(name, SYNCHRONIZE|access, *objAttrs, fileAttrs, disposition, FILE_OPEN_FOR_BACKUP_INTENT|options)
|
|
165
|
+
}
|
|
157
166
|
if err != nil {
|
|
158
167
|
return h, ntCreateFileError(err, flag)
|
|
159
168
|
}
|
|
@@ -177,11 +186,78 @@ func Openat(dirfd syscall.Handle, name string, flag uint64, perm uint32) (_ sysc
|
|
|
177
186
|
return h, nil
|
|
178
187
|
}
|
|
179
188
|
|
|
189
|
+
// TestOpenatFallback should only be used for testing purposes.
|
|
190
|
+
// When set, Openat simulates a system that does not support OBJ_DONT_REPARSE.
|
|
191
|
+
var TestOpenatFallback bool
|
|
192
|
+
|
|
193
|
+
// openatFallback implements O_NOFOLLOW_ANY for a single path component on
|
|
194
|
+
// Windows versions that do not support OBJ_DONT_REPARSE (including Windows 10
|
|
195
|
+
// build 10240). See go.dev/issue/78131.
|
|
196
|
+
func openatFallback(name string, access uint32, attrs OBJECT_ATTRIBUTES, fileAttrs, disposition, options uint32) (syscall.Handle, error) {
|
|
197
|
+
// FILE_OPEN_REPARSE_POINT only prevents following the final component.
|
|
198
|
+
// All current production callers that request O_NOFOLLOW_ANY pass a
|
|
199
|
+
// single component: os.Root splits paths (including symlink targets)
|
|
200
|
+
// before opening each component, and RemoveAll passes a basename or a
|
|
201
|
+
// directory entry name relative to an open parent directory. Thus this
|
|
202
|
+
// fallback also supports multi-component paths passed to those APIs.
|
|
203
|
+
// Reject other paths here rather than weaken O_NOFOLLOW_ANY: this is
|
|
204
|
+
// not a general replacement for OBJ_DONT_REPARSE.
|
|
205
|
+
if attrs.RootDirectory == 0 || name == ".." ||
|
|
206
|
+
stringslite.IndexByte(name, '\\') >= 0 || stringslite.IndexByte(name, '/') >= 0 || stringslite.IndexByte(name, ':') >= 0 {
|
|
207
|
+
return syscall.InvalidHandle, STATUS_INVALID_PARAMETER
|
|
208
|
+
}
|
|
209
|
+
attrs.Attributes &^= OBJ_DONT_REPARSE
|
|
210
|
+
var h syscall.Handle
|
|
211
|
+
err := NtCreateFile(
|
|
212
|
+
&h, access, &attrs, &IO_STATUS_BLOCK{}, nil, fileAttrs,
|
|
213
|
+
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, disposition,
|
|
214
|
+
(options|FILE_OPEN_REPARSE_POINT)&^FILE_DELETE_ON_CLOSE, nil, 0,
|
|
215
|
+
)
|
|
216
|
+
if err != nil {
|
|
217
|
+
return syscall.InvalidHandle, err
|
|
218
|
+
}
|
|
219
|
+
// Inspect the handle, not the path, before truncation or delete-on-close.
|
|
220
|
+
// Skip this check if opening the reparse point itself was requested,
|
|
221
|
+
// or if O_CREAT|O_EXCL requires creating a new file without following links.
|
|
222
|
+
if options&FILE_OPEN_REPARSE_POINT == 0 {
|
|
223
|
+
var info syscall.ByHandleFileInformation
|
|
224
|
+
err = syscall.GetFileInformationByHandle(h, &info)
|
|
225
|
+
if err == nil && info.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
|
226
|
+
err = STATUS_REPARSE_POINT_ENCOUNTERED
|
|
227
|
+
}
|
|
228
|
+
if err != nil {
|
|
229
|
+
syscall.CloseHandle(h)
|
|
230
|
+
return syscall.InvalidHandle, err
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if options&FILE_DELETE_ON_CLOSE == 0 {
|
|
234
|
+
return h, nil
|
|
235
|
+
}
|
|
236
|
+
defer syscall.CloseHandle(h)
|
|
237
|
+
|
|
238
|
+
// Only enable deletion after checking for a reparse point. An empty
|
|
239
|
+
// name relative to h reopens the same file, even if it has been renamed
|
|
240
|
+
// or its directory entry has been replaced since the first open.
|
|
241
|
+
// The file already exists, including when created with O_EXCL.
|
|
242
|
+
attrs.RootDirectory = h
|
|
243
|
+
attrs.ObjectName = &NTUnicodeString{}
|
|
244
|
+
var dh syscall.Handle
|
|
245
|
+
err = NtOpenFile(
|
|
246
|
+
&dh, access, &attrs, &IO_STATUS_BLOCK{},
|
|
247
|
+
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
|
248
|
+
options|FILE_OPEN_REPARSE_POINT,
|
|
249
|
+
)
|
|
250
|
+
if err != nil {
|
|
251
|
+
return syscall.InvalidHandle, err
|
|
252
|
+
}
|
|
253
|
+
return dh, nil
|
|
254
|
+
}
|
|
255
|
+
|
|
180
256
|
// ntCreateFileError maps error returns from NTCreateFile to user-visible errors.
|
|
181
257
|
func ntCreateFileError(err error, flag uint64) error {
|
|
182
258
|
s, ok := err.(NTStatus)
|
|
183
259
|
if !ok {
|
|
184
|
-
//
|
|
260
|
+
// The Openat fallback can also return Win32 errors.
|
|
185
261
|
return err
|
|
186
262
|
}
|
|
187
263
|
switch s {
|
|
@@ -222,7 +298,7 @@ func Mkdirat(dirfd syscall.Handle, name string, mode uint32) error {
|
|
|
222
298
|
syscall.FILE_ATTRIBUTE_NORMAL,
|
|
223
299
|
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
|
|
224
300
|
FILE_CREATE,
|
|
225
|
-
FILE_DIRECTORY_FILE,
|
|
301
|
+
FILE_DIRECTORY_FILE|FILE_OPEN_REPARSE_POINT,
|
|
226
302
|
nil,
|
|
227
303
|
0,
|
|
228
304
|
)
|
|
@@ -272,7 +272,14 @@ type FILE_LINK_INFORMATION struct {
|
|
|
272
272
|
FileName [syscall.MAX_PATH]uint16
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
const
|
|
275
|
+
const (
|
|
276
|
+
FileIoCompletionNotificationInformation = 41
|
|
277
|
+
FileReplaceCompletionInformation = 61
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
type FILE_IO_COMPLETION_NOTIFICATION_INFORMATION struct {
|
|
281
|
+
Flags uint32
|
|
282
|
+
}
|
|
276
283
|
|
|
277
284
|
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_completion_information
|
|
278
285
|
type FILE_COMPLETION_INFORMATION struct {
|
|
@@ -93,17 +93,16 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
|
|
|
93
93
|
// The relationship between these parameters, as well as the overly-large and
|
|
94
94
|
// unconfigurable 10 MB added on to maxMemory, is unfortunate but difficult to change
|
|
95
95
|
// within the constraints of the API as documented.
|
|
96
|
+
if maxMemory < 0 {
|
|
97
|
+
maxMemory = 0
|
|
98
|
+
}
|
|
96
99
|
maxFileMemoryBytes := maxMemory
|
|
97
100
|
if maxFileMemoryBytes == math.MaxInt64 {
|
|
98
101
|
maxFileMemoryBytes--
|
|
99
102
|
}
|
|
100
103
|
maxMemoryBytes := maxMemory + int64(10<<20)
|
|
101
104
|
if maxMemoryBytes <= 0 {
|
|
102
|
-
|
|
103
|
-
maxMemoryBytes = 0
|
|
104
|
-
} else {
|
|
105
|
-
maxMemoryBytes = math.MaxInt64
|
|
106
|
-
}
|
|
105
|
+
maxMemoryBytes = math.MaxInt64
|
|
107
106
|
}
|
|
108
107
|
var copyBuf []byte
|
|
109
108
|
for {
|
|
@@ -12,6 +12,7 @@ import (
|
|
|
12
12
|
"internal/godebug"
|
|
13
13
|
"io"
|
|
14
14
|
"io/fs"
|
|
15
|
+
"math"
|
|
15
16
|
"mime"
|
|
16
17
|
"mime/multipart"
|
|
17
18
|
"net/textproto"
|
|
@@ -1010,6 +1011,25 @@ func (r httpRange) mimeHeader(contentType string, size int64) textproto.MIMEHead
|
|
|
1010
1011
|
}
|
|
1011
1012
|
}
|
|
1012
1013
|
|
|
1014
|
+
// GODEBUG=httpservecontentmaxranges=<limit> controls the maximum number of ranges that will
|
|
1015
|
+
// be processed in a Range header. Setting httpservecontentmaxranges=0 disables the limit.
|
|
1016
|
+
var httpservecontentmaxranges = godebug.New("httpservecontentmaxranges")
|
|
1017
|
+
|
|
1018
|
+
const defaultMaxContentRanges = 200
|
|
1019
|
+
|
|
1020
|
+
func maxContentRanges() int {
|
|
1021
|
+
maxRanges := defaultMaxContentRanges
|
|
1022
|
+
if v := httpservecontentmaxranges.Value(); v != "" {
|
|
1023
|
+
if n, err := strconv.Atoi(v); err == nil && n >= 0 {
|
|
1024
|
+
maxRanges = n
|
|
1025
|
+
if maxRanges == 0 {
|
|
1026
|
+
maxRanges = math.MaxInt
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
return maxRanges
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1013
1033
|
// parseRange parses a Range header string as per RFC 7233.
|
|
1014
1034
|
// errNoOverlap is returned if none of the ranges overlap.
|
|
1015
1035
|
func parseRange(s string, size int64) ([]httpRange, error) {
|
|
@@ -1022,6 +1042,14 @@ func parseRange(s string, size int64) ([]httpRange, error) {
|
|
|
1022
1042
|
}
|
|
1023
1043
|
var ranges []httpRange
|
|
1024
1044
|
noOverlap := false
|
|
1045
|
+
numRanges := strings.Count(s[len(b):], ",") + 1
|
|
1046
|
+
maxRanges := maxContentRanges()
|
|
1047
|
+
if (numRanges > maxRanges) != (numRanges > defaultMaxContentRanges) {
|
|
1048
|
+
httpservecontentmaxranges.IncNonDefault()
|
|
1049
|
+
}
|
|
1050
|
+
if numRanges > maxRanges {
|
|
1051
|
+
return nil, nil // ignore header with too many ranges
|
|
1052
|
+
}
|
|
1025
1053
|
for ra := range strings.SplitSeq(s[len(b):], ",") {
|
|
1026
1054
|
ra = textproto.TrimString(ra)
|
|
1027
1055
|
if ra == "" {
|