mirror of https://github.com/golang/go.git
internal/lsp: check that a file handle is unmodified before read
Address a lingering TODO. A FileHandle read should return errors if the file has been modified on disk while in use. Change-Id: I540de9bef575a9ca838f49500665a24b05b4f54c Reviewed-on: https://go-review.googlesource.com/c/tools/+/215981 Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rohan Challa <rohan@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
parent
219d3418f5
commit
e873952e15
|
|
@ -13,6 +13,7 @@ import (
|
|||
"golang.org/x/tools/internal/lsp/telemetry"
|
||||
"golang.org/x/tools/internal/span"
|
||||
"golang.org/x/tools/internal/telemetry/trace"
|
||||
errors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// ioLimit limits the number of parallel file reads per process.
|
||||
|
|
@ -28,17 +29,12 @@ type nativeFileHandle struct {
|
|||
}
|
||||
|
||||
func (fs *nativeFileSystem) GetFile(uri span.URI) source.FileHandle {
|
||||
identifier := "DOES NOT EXIST"
|
||||
if fi, err := os.Stat(uri.Filename()); err == nil {
|
||||
identifier = fi.ModTime().String()
|
||||
}
|
||||
kind := source.DetectLanguage("", uri.Filename())
|
||||
return &nativeFileHandle{
|
||||
fs: fs,
|
||||
identity: source.FileIdentity{
|
||||
URI: uri,
|
||||
Identifier: identifier,
|
||||
Kind: kind,
|
||||
Identifier: identifier(uri.Filename()),
|
||||
Kind: source.DetectLanguage("", uri.Filename()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -58,10 +54,20 @@ func (h *nativeFileHandle) Read(ctx context.Context) ([]byte, string, error) {
|
|||
|
||||
ioLimit <- struct{}{}
|
||||
defer func() { <-ioLimit }()
|
||||
// TODO: this should fail if the version is not the same as the handle
|
||||
|
||||
if id := identifier(h.identity.URI.Filename()); id != h.identity.Identifier {
|
||||
return nil, "", errors.Errorf("%s: file has been modified", h.identity.URI.Filename())
|
||||
}
|
||||
data, err := ioutil.ReadFile(h.identity.URI.Filename())
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return data, hashContents(data), nil
|
||||
}
|
||||
|
||||
func identifier(filename string) string {
|
||||
if fi, err := os.Stat(filename); err == nil {
|
||||
return fi.ModTime().String()
|
||||
}
|
||||
return "DOES NOT EXIST"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue