Skip to content

Commit

Permalink
Refactor file statistics function to use SHA-256 and improve error ha…
Browse files Browse the repository at this point in the history
…ndling

-  Replace MD5 hashing with SHA-256 in the FileInfo struct to enhance security and align with best practices against cryptographic vulnerabilities.
-  Streamlined the file existence and metadata retrieval process by combining the os.Stat call for both checking file existence and retrieving stats, reducing redundancy and potential for errors.
-  Improved error messages and error wrapping to facilitate better debugging and error tracing, utilizing Go’s %w verb for error formatting.
-  Updated GoDoc comments to accurately reflect changes in the hashing method from MD5 to SHA-256, ensuring documentation consistency and clarity for future maintenance.

This commit secures the file information retrieval by transitioning to a more robust and secure hashing algorithm (SHA-256), and enhances the code’s maintainability and readability through better error management practices.
  • Loading branch information
thomasvincent authored Apr 27, 2024
1 parent c292572 commit d05b74c
Showing 1 changed file with 48 additions and 24 deletions.
72 changes: 48 additions & 24 deletions util/filestat_posix.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,54 @@
package util

import (
"crypto/md5"
"errors"
"fmt"
"io"
"os"
"syscall"
"crypto/sha256"
"fmt"
"io"
"os"
"syscall"
)

// filestat return a FileInfo describing the named file.
func FileStat(name string) (fi FileInfo, err error) {
if IsFileExist(name) {
f, err := os.Open(name)
if err != nil {
return fi, err
}
defer f.Close()
stats, _ := f.Stat()
fi.Uid = stats.Sys().(*syscall.Stat_t).Uid
fi.Gid = stats.Sys().(*syscall.Stat_t).Gid
fi.Mode = stats.Mode()
h := md5.New()
io.Copy(h, f)
fi.Md5 = fmt.Sprintf("%x", h.Sum(nil))
return fi, nil
}
return fi, errors.New("File not found")
// FileInfo holds the metadata about a file including UID, GID, mode, and SHA-256 checksum.
type FileInfo struct {
Uid uint32
Gid uint32
Mode os.FileMode
Sha256 string
}

// FileStat returns a FileInfo describing the named file, including its SHA-256 checksum.
// If the file does not exist or there is an error processing it, FileStat returns an error
// detailing the issue encountered.
func FileStat(name string) (FileInfo, error) {
var fi FileInfo
stat, err := os.Stat(name)
if err != nil {
if os.IsNotExist(err) {
return fi, fmt.Errorf("file not found: %s", name)
}
return fi, fmt.Errorf("error accessing file %s: %w", name, err)
}

f, err := os.Open(name)
if err != nil {
return fi, fmt.Errorf("error opening file %s: %w", name, err)
}
defer f.Close()

sysStat, ok := stat.Sys().(*syscall.Stat_t)
if !ok {
return fi, fmt.Errorf("file stats assertion failed for file %s", name)
}

fi.Uid = sysStat.Uid
fi.Gid = sysStat.Gid
fi.Mode = stat.Mode()

hash := sha256.New()
if _, err := io.Copy(hash, f); err != nil {
return fi, fmt.Errorf("error calculating SHA-256 for file %s: %w", name, err)
}
fi.Sha256 = fmt.Sprintf("%x", hash.Sum(nil))

return fi, nil
}

0 comments on commit d05b74c

Please sign in to comment.