From b7b34565565e3cde8037d1b5ee95dd2bb3579ef1 Mon Sep 17 00:00:00 2001 From: konoui Date: Thu, 25 Jul 2024 22:00:05 +0900 Subject: [PATCH] update ar header --- pkg/ar/ar.go | 53 +++++++++++++++++++++++++++++++++++++++++------ pkg/ar/ar_test.go | 16 ++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/pkg/ar/ar.go b/pkg/ar/ar.go index 733fc57..814f4a2 100644 --- a/pkg/ar/ar.go +++ b/pkg/ar/ar.go @@ -5,8 +5,10 @@ import ( "errors" "fmt" "io" + "io/fs" "strconv" "strings" + "time" ) const ( @@ -29,6 +31,10 @@ type File struct { type Header struct { Name string Size int64 + ModTime time.Time + UID int + GID int + Mode fs.FileMode nameSize int64 } @@ -112,12 +118,35 @@ func (r *Reader) readHeader() (*Header, error) { } name := TrimTailSpace(header[0:16]) - // mTime := header[16:18] - // uid, gid := header[28:34], buf[34:40] - // perm := header[40:48] - size, err := strconv.ParseInt(TrimTailSpace(header[48:58]), 10, 64) + + parsedMTime, err := parseDecimal(TrimTailSpace(header[16:28])) + if err != nil { + return nil, fmt.Errorf("parse mtime: %w", err) + } + modTime := time.Unix(parsedMTime, 0) + + parsedUID, err := parseDecimal(TrimTailSpace(header[28:34])) + if err != nil { + return nil, fmt.Errorf("parse uid: %w", err) + } + + parsedGID, err := parseDecimal(TrimTailSpace(header[34:40])) if err != nil { - return nil, fmt.Errorf("parse size value of name: %v", err) + return nil, fmt.Errorf("parse gid: %w", err) + } + + uid, gid := int(parsedUID), int(parsedGID) + + parsedPerm, err := parseOctal(TrimTailSpace(header[40:48])) + if err != nil { + return nil, fmt.Errorf("parse mode: %w", err) + } + + perm := fs.FileMode(parsedPerm) + + size, err := parseDecimal(TrimTailSpace(header[48:58])) + if err != nil { + return nil, fmt.Errorf("parse size value of name: %w", err) } endChars := header[58:60] @@ -132,7 +161,7 @@ func (r *Reader) readHeader() (*Header, error) { // handle BSD variant if strings.HasPrefix(name, "#1/") { trimmedSize := strings.TrimPrefix(name, "#1/") - parsedSize, err := strconv.ParseInt(trimmedSize, 10, 64) + parsedSize, err := parseDecimal(trimmedSize) if err != nil { return nil, err } @@ -165,11 +194,23 @@ func (r *Reader) readHeader() (*Header, error) { h := &Header{ Size: size, Name: name, + ModTime: modTime, + GID: gid, + UID: uid, + Mode: perm, nameSize: nameSize, } return h, nil } +func parseDecimal(s string) (int64, error) { + return strconv.ParseInt(s, 10, 64) +} + +func parseOctal(s string) (int64, error) { + return strconv.ParseInt(s, 8, 64) +} + func TrimTailSpace(b []byte) string { return strings.TrimRight(string(b), " ") } diff --git a/pkg/ar/ar_test.go b/pkg/ar/ar_test.go index 9ac36ae..3353204 100644 --- a/pkg/ar/ar_test.go +++ b/pkg/ar/ar_test.go @@ -6,6 +6,7 @@ import ( "debug/macho" "encoding/hex" "io" + "io/fs" "os" "path/filepath" "reflect" @@ -69,6 +70,21 @@ func TestNew(t *testing.T) { continue } + if tt.filename == "arm64-func1.a" && file.Name == "arm64-func1.o" { + if file.UID != 501 { + t.Errorf("uid: want %d, got %d\n", 501, file.UID) + } + if file.GID != 20 { + t.Errorf("gid: want %d, got %d\n", 20, file.GID) + } + if file.ModTime.Unix() != 1697716653 { + t.Errorf("modtime: want %v, got %v\n", 1697716653, file.ModTime.Unix()) + } + if file.Mode.Perm() != fs.FileMode(0644) { + t.Errorf("mode: want %d, got %d\n", fs.FileMode(0644), file.Mode.Perm()) + } + } + got = append(got, file.Name) machoBuf := &bytes.Buffer{}