mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/go/internal/mmap: reslice to file size on Windows
The Mmap function returns a Data struct containing a slice with the mapped contents of the file. Before this change, on Windows, the slice contained the contents of all the pages of the mapping, including past the end of the file. Re-slice the slice to the length of the file (if if the slice is longer) so that the slice contains only the data in the file. For #71059 Change-Id: I389b752505b6fa1252b5c6d836a37bc7e662a45d Reviewed-on: https://go-review.googlesource.com/c/go/+/640155 Reviewed-by: Russ Cox <rsc@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
f5a89dff67
commit
c6ab13fc43
3 changed files with 40 additions and 1 deletions
32
src/cmd/go/internal/mmap/mmap_test.go
Normal file
32
src/cmd/go/internal/mmap/mmap_test.go
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package mmap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestMmap does a round trip to make sure the slice returned by
|
||||||
|
// mmap contains the same data as was written to the file. It's
|
||||||
|
// a test on one of the issues in #71059: on Windows we were
|
||||||
|
// returning a slice containing all the data in the mmapped pages,
|
||||||
|
// which could be longer than the file.
|
||||||
|
func TestMmap(t *testing.T) {
|
||||||
|
// Use an already existing file as our test data. Avoid creating
|
||||||
|
// a temporary file so that we don't have to close the mapping on
|
||||||
|
// Windows before deleting the file during test cleanup.
|
||||||
|
f := "testdata/small_file.txt"
|
||||||
|
|
||||||
|
want := []byte("This file is shorter than 4096 bytes.\n")
|
||||||
|
|
||||||
|
data, _, err := Mmap(f)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("calling Mmap: %v", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(data.Data, want) {
|
||||||
|
t.Fatalf("mmapped data slice: got %q; want %q", data.Data, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,5 +37,11 @@ func mmapFile(f *os.File) (Data, error) {
|
||||||
return Data{}, fmt.Errorf("VirtualQuery %s: %w", f.Name(), err)
|
return Data{}, fmt.Errorf("VirtualQuery %s: %w", f.Name(), err)
|
||||||
}
|
}
|
||||||
data := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.RegionSize))
|
data := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.RegionSize))
|
||||||
return Data{f, data}, nil
|
if len(data) < int(size) {
|
||||||
|
// In some cases, especially on 386, we may not receive a in incomplete mapping:
|
||||||
|
// one that is shorter than the file itself. Return an error in those cases because
|
||||||
|
// incomplete mappings are not useful.
|
||||||
|
return Data{}, fmt.Errorf("mmapFile: received incomplete mapping of file")
|
||||||
|
}
|
||||||
|
return Data{f, data[:int(size)]}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
src/cmd/go/internal/mmap/testdata/small_file.txt
vendored
Normal file
1
src/cmd/go/internal/mmap/testdata/small_file.txt
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
This file is shorter than 4096 bytes.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue