Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit a6ab319

Browse files
committed
verify: Exclude symlinks from hash digests
As we're moving in the direction of excluding symlinks entirely from dependencies (hallelujah!), it's preferable to have the initial release of vendor verification exclude symlinks from hash digests entirely. For the most part, people shouldn't notice it, and we won't be forced to bump the hash version when we stop writing out symlinks (though we may bump it anyway).
1 parent aefa7cc commit a6ab319

File tree

6 files changed

+41
-167
lines changed

6 files changed

+41
-167
lines changed

cmd/dep/testdata/harness_tests/ensure/add/desync/final/Gopkg.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/dep/testdata/harness_tests/ensure/add/exists-imports/final/Gopkg.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/dep/testdata/harness_tests/ensure/add/exists-manifest-constraint/final/Gopkg.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gps/verify/digest.go

+37-25
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"io"
1515
"os"
1616
"path/filepath"
17+
"sort"
1718
"strconv"
1819
"strings"
1920

@@ -152,14 +153,10 @@ type dirWalkClosure struct {
152153
//
153154
// Other than the `vendor` and VCS directories mentioned above, the calculated
154155
// hash includes the pathname to every discovered file system node, whether it
155-
// is an empty directory, a non-empty directory, empty file, non-empty file, or
156-
// symbolic link. If a symbolic link, the referent name is included. If a
157-
// non-empty file, the file's contents are included. If a non-empty directory,
158-
// the contents of the directory are included.
156+
// is an empty directory, a non-empty directory, an empty file, or a non-empty file.
159157
//
160-
// While filepath.Walk could have been used, that standard library function
161-
// skips symbolic links, and for now, we want the hash to include the symbolic
162-
// link referents.
158+
// Symbolic links are excluded, as they are not considered valid elements in the
159+
// definition of a Go module.
163160
func DigestFromDirectory(osDirname string) (VersionedDigest, error) {
164161
osDirname = filepath.Clean(osDirname)
165162

@@ -173,9 +170,14 @@ func DigestFromDirectory(osDirname string) (VersionedDigest, error) {
173170
someHash: sha256.New(),
174171
}
175172

176-
err := DirWalk(osDirname, func(osPathname string, info os.FileInfo, err error) error {
173+
err := filepath.Walk(osDirname, func(osPathname string, info os.FileInfo, err error) error {
177174
if err != nil {
178-
return err // DirWalk received an error during initial Lstat
175+
return err
176+
}
177+
178+
// Completely ignore symlinks.
179+
if info.Mode()&os.ModeSymlink != 0 {
180+
return nil
179181
}
180182

181183
var osRelative string
@@ -207,11 +209,9 @@ func DigestFromDirectory(osDirname string) (VersionedDigest, error) {
207209
switch {
208210
case modeType&os.ModeDir > 0:
209211
mt = os.ModeDir
210-
// DirWalkFunc itself does not need to enumerate children, because
211-
// DirWalk will do that for us.
212+
// This func does not need to enumerate children, because
213+
// filepath.Walk will do that for us.
212214
shouldSkip = true
213-
case modeType&os.ModeSymlink > 0:
214-
mt = os.ModeSymlink
215215
case modeType&os.ModeNamedPipe > 0:
216216
mt = os.ModeNamedPipe
217217
shouldSkip = true
@@ -225,9 +225,8 @@ func DigestFromDirectory(osDirname string) (VersionedDigest, error) {
225225

226226
// Write the relative pathname to hash because the hash is a function of
227227
// the node names, node types, and node contents. Added benefit is that
228-
// empty directories, named pipes, sockets, devices, and symbolic links
229-
// will also affect final hash value. Use `filepath.ToSlash` to ensure
230-
// relative pathname is os-agnostic.
228+
// empty directories, named pipes, sockets, and devices. Use
229+
// `filepath.ToSlash` to ensure relative pathname is os-agnostic.
231230
writeBytesWithNull(closure.someHash, []byte(filepath.ToSlash(osRelative)))
232231

233232
binary.LittleEndian.PutUint32(closure.someModeBytes, uint32(mt)) // encode the type of mode
@@ -237,15 +236,6 @@ func DigestFromDirectory(osDirname string) (VersionedDigest, error) {
237236
return nil // nothing more to do for some of the node types
238237
}
239238

240-
if mt == os.ModeSymlink { // okay to check for equivalence because we set to this value
241-
osRelative, err = os.Readlink(osPathname) // read the symlink referent
242-
if err != nil {
243-
return errors.Wrap(err, "cannot Readlink")
244-
}
245-
writeBytesWithNull(closure.someHash, []byte(filepath.ToSlash(osRelative))) // write referent to hash
246-
return nil // proceed to next node in queue
247-
}
248-
249239
// If we get here, node is a regular file.
250240
fh, err := os.Open(osPathname)
251241
if err != nil {
@@ -541,3 +531,25 @@ func CheckDepTree(osDirname string, wantDigests map[string]VersionedDigest) (map
541531

542532
return slashStatus, nil
543533
}
534+
535+
// sortedChildrenFromDirname returns a lexicographically sorted list of child
536+
// nodes for the specified directory.
537+
func sortedChildrenFromDirname(osDirname string) ([]string, error) {
538+
fh, err := os.Open(osDirname)
539+
if err != nil {
540+
return nil, errors.Wrap(err, "cannot Open")
541+
}
542+
543+
osChildrenNames, err := fh.Readdirnames(0) // 0: read names of all children
544+
if err != nil {
545+
return nil, errors.Wrap(err, "cannot Readdirnames")
546+
}
547+
sort.Strings(osChildrenNames)
548+
549+
// Close the file handle to the open directory without masking possible
550+
// previous error value.
551+
if er := fh.Close(); err == nil {
552+
err = errors.Wrap(er, "cannot Close")
553+
}
554+
return osChildrenNames, err
555+
}

gps/verify/digest_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ func TestVerifyDepTree(t *testing.T) {
153153
}
154154

155155
checkStatus := func(t *testing.T, status map[string]VendorStatus, key string, want VendorStatus) {
156+
t.Helper()
156157
got, ok := status[key]
157158
if !ok {
158159
t.Errorf("Want key: %q", key)

gps/verify/dirwalk.go

-139
This file was deleted.

0 commit comments

Comments
 (0)