Skip to content

Commit

Permalink
Check hashes of files in download cache for validity
Browse files Browse the repository at this point in the history
The gomobile init command will use files cached in a 'dl' folder
in lieu of downloading a new file from scratch. If a user of gomobile
does not upgrade for a substantial amount of time, the cached files
will be out of date and possibly cause the init command to fail because
they are missing something the init command now expects.

The init command has a list of expectad sha256 message digests of files
it downloads, which can be utilized to check a file that exists in the 'dl'
folder before proceeeding to utilize it to continue with the init process.

This fixes the problem cited in issue #14503, which is not platform-specific:
golang/go#14503

Some files detailing debugging of the original problem and asserting a solution
are at the following URL:
https://gist.github.com/aoeu/657386c35131b71893153efe34ec07b4
  • Loading branch information
Travis McDemus committed Apr 19, 2016
1 parent e1840f9 commit db2107a
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion cmd/gomobile/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,11 @@ func fetch(url string) (dst string, err error) {
printcmd("stat %s", dst)
}
if _, err = os.Stat(dst); err == nil {
return dst, nil
if err := checkFetchHash(name, dst); err != nil {
fmt.Fprintf(os.Stderr, "A correct message disgest could not be calculated for existing download of '%v'.\n%v\n", dst, err)
} else {
return dst, nil
}
}
}
if buildX {
Expand Down Expand Up @@ -574,6 +578,30 @@ func fetch(url string) (dst string, err error) {
return dst, nil
}

func checkFetchHash(name string, filepath string) error {
f, err := os.Open(filepath)
if err != nil {
return err
}
h, err := calcHash(f)
switch {
case err != nil:
return fmt.Errorf("could not calculate sha256 for %v: %v", name, err)
case fetchHashes[name] != h:
return fmt.Errorf("sha256 for %q: %v, want %v", name, h, fetchHashes[name])
default:
return nil
}
}

func calcHash(r io.Reader) (string, error) {
w := sha256.New()
if _, err := io.Copy(w, r); err != nil {
return "", err
}
return hex.EncodeToString(w.Sum(nil)), nil
}

func doCopyAll(dst, src string) error {
return filepath.Walk(src, func(path string, info os.FileInfo, errin error) (err error) {
if errin != nil {
Expand Down

0 comments on commit db2107a

Please sign in to comment.